问题
I'm trying to resize an image in .NET, but get a faint black border around the resized image. I found a post - http://social.msdn.microsoft.com/forums/en-US/csharpgeneral/thread/cf765094-c8c1-4991-a1f3-cecdbd07ee15/ which from someone who said making the destination rectangle larger than the canvas worked, but this doesn't work for me. It gets riid of the top and left borders, but the right and bottom are still there, and are a full 1px thick black.
Am I missing something? My code is below.
Image image = ... // this is a valid image loaded from the source
Rectangle srcRectangle = new Rectangle(0,0,width, height);
Size croppedFullSize = new Size(width+3,height+3);
Rectangle destRect = new Rectangle(new Point(-1,-1), croppedFullSize);
using(Bitmap newImage = new Bitmap(croppedFullSize.Width, croppedFullSize.Height, format))
using(Graphics Canvas = Graphics.FromImage(newImage)) {
Canvas.SmoothingMode = SmoothingMode.AntiAlias;
Canvas.InterpolationMode = InterpolationMode.HighQualityBicubic;
Canvas.PixelOffsetMode = PixelOffsetMode.HighQuality;
Canvas.FillRectangle(Brushes.Transparent, destRect);
Canvas.DrawImage(image, destRect, srcRectangle, GraphicsUnit.Pixel);
newImage.Save(filename, image.RawFormat);
}
回答1:
Try it like this, i think i've never got a black border...
If you want to use System.Drawing libraries:
using (var sourceBmp = new Bitmap(sourcePath))
{
decimal aspect = (decimal)sourceBmp.Width / (decimal)sourceBmp.Height;
int newHeight = (int)(newWidth / aspect);
using (var destinationBmp = new Bitmap(newWidth, newHeight))
{
using (var destinationGfx = Graphics.FromImage(destinationBmp))
{
destinationGfx.InterpolationMode = InterpolationMode.HighQualityBicubic;
destinationGfx.DrawImage(sourceBmp, new Rectangle(0, 0, destinationBmp.Width, destinationBmp.Height));
destinationBmp.Save(destinationPath, ImageFormat.Jpeg);
}
}
}
or you can do the same with wpf, like this:
using (var output = new FileStream(outputPath, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.None))
{
var imageDecoder = BitmapDecoder.Create(inputStream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None);
var imageFrame = imageDecoder.Frames[0];
decimal aspect = (decimal)imageFrame.Width / (decimal)imageFrame.Height;
var height = (int)(newWidth / aspect);
var imageResized = new TransformedBitmap(imageFrame,new ScaleTransform(
newWidth / imageFrame.Width * Dpi / imageFrame.DpiX,
height / imageFrame.Height * Dpi / imageFrame.DpiY, 0, 0));
var targetFrame = BitmapFrame.Create(imageResized);
var targetEncoder = new JpegBitmapEncoder();
targetEncoder.Frames.Add(targetFrame);
targetEncoder.QualityLevel = 80;
targetEncoder.Save(output);
}
I recommend the WPF way. The compression & quality seems better...
回答2:
Simply provide the DrawImage method with an ImageAttributes instance which has WrapMode set to TileFlipXY. This will prevent the edge from blending against the background color.
For sample code that doesn't leak memory like the other answers here, see this gist
回答3:
For me it was a bad Bitmap parameter. Instead of this:
new Bitmap(width, height, PixelFormat.Format32bppPArgb);
Just remove the PixelFormat to this:
new Bitmap(width, height);
And everything was ok then.
With the PixelFormat I had black border on the top and left border. Then I tried g.PixelOffsetMode = PixelOffsetMode.HighQuality; which seemed fine at first. But then I noticed light gray borders around the whole image.
来源:https://stackoverflow.com/questions/5452447/net-border-around-resized-imaged