Reputation: 105
There's lots of posts on here about code to resize images down, but with all of them I get this artefact problem that I don't get when doing it manually in photoshop.
Is there something MORE I can do to fix this? I notice that when exporting bitmap from Photoshop I can make the export "progressive", is there something similar that might help in C#?
Photoshop's downscaling of 1080p to 480p:
Everything from SO's resizing of 1080p to 480p:
The rest of the image is similar but the collar here is a good example of the noise I'm getting with my code.
My current function:
public static Bitmap ResizeImage(Image image, int width, int height)
{
var destRect = new System.Drawing.Rectangle(0, 0, width, height);
var destImage = new System.Drawing.Bitmap(width, height);
destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);
using (var graphics = System.Drawing.Graphics.FromImage(destImage))
{
graphics.CompositingMode = CompositingMode.SourceCopy;
graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
using (var wrapMode = new System.Drawing.Imaging.ImageAttributes())
{
wrapMode.SetWrapMode(WrapMode.TileFlipXY);
graphics.DrawImage(image, destRect, 0, 0, image.Width, image.Height, System.Drawing.GraphicsUnit.Pixel, wrapMode);
}
}
return destImage;
}
Here's the original image in 1920x1080 for reference:
Upvotes: 0
Views: 76
Reputation: 36629
The second image looks like it has fairly severe jpeg artefacting. This is typically evident from a significant amount of noise near high contrast edges.
Photoshop likely also uses a more advanced downscaling filter, but the effect of this should only affect edges or other high frequency features, and the difference should be much more subtle than the large amount of noise in the example images.
See How to set jpeg compression level to control the amount of compression applied when saving images, and therefore the amount of noise:
var jpgEncoder = GetEncoder(ImageFormat.Jpeg);
var myEncoderParameters = new EncoderParameters(1);
myEncoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, 95L);
myBitmap.Save(myFilePath, jpgEncoder, myEncoderParameters);
Do note that different jpeg encoder libraries might produce slightly different result. The builtin encoder should be "good enough", but there are third party libraries that claim slightly better quality/file size. Also note that the jpeg format itself is really old, so if you are more concerned about quality/size than compatibility there are certainly better formats to chose from.
Upvotes: 2