Reputation: 3453
I’ve got a method which takes an input image, does some things to the image, then saves it to another file. At its most basic it resizes the image, but it can do a few more complicated things like converting to greyscale, quantizing etc, but for the case of this question I’m only attempting to resize the image and not performing any of the other actions.
It looks something like:
public void SaveImage(string src, string dest, int width, int height, ImageFormat format, bool deleteOriginal, bool quantize, bool convertToGreyscale) {
// Open the source file
Bitmap source = (Bitmap)Image.FromFile(src);
// Check dimensions
if (source.Width < width)
throw new Exception();
if (source.Height < height)
throw new Exception();
// Output image
Bitmap output = new Bitmap(width, height);
using (Graphics g = Graphics.FromImage(output)) {
// Resize the image to new dimensions
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.DrawImage(source, 0, 0, width, height);
}
// Convert to greyscale if supposed to
if (convertToGreyscale) {
output = this.ConvertToGreyscale(output);
}
// Save the image
if (quantize) {
OctreeQuantizer quantizer = new OctreeQuantizer(255, 8);
using (var quantized = quantizer.Quantize(output)) {
quantized.Save(dest, format);
}
}
else {
output.Save(dest, format);
}
// Close all the images
output.Dispose();
source.Dispose();
// Delete the original
if (deleteOriginal) {
File.Delete(src);
}
}
Then to use it I’d call something like: imageService.SaveImage("c:\image.png", "c:\output.png", 300, 300, ImageFormat.Png, false, false, false);
That should open up the “image.png” file, resize in to 300×300, then save it to “output.png” as a PNG file. But it’s not working—the file that gets created is in the correct location but has a file size of zero and contains no image at all.
This also only seems to happen when I pass in the parameter ImageFormat.Png
; if I pass ImageFormat.Jpeg
, then it works fine and creates the image file perfectly.
I’m wondering if there’s some sort of delay occurring between creating the image and somewhere else in the code attempting to access the image that’s been created (not in the above code) which locks up the file and so it’s never written to? Could that be the case?
Any ideas what else could be going on?
Cheers
Edits:
Upvotes: 4
Views: 1903
Reputation: 16468
Using the Save() parameter with a Stream instead of a filename will allow you to ensure the file is flushed to disk before the objects are disposed.
However, I'd strongly suggest using a server-safe image-processing library here, as you're playing with fire.
Upvotes: 0
Reputation: 2786
There are some historical issues with saving bitmaps as png.
Using System.Windows.Media.Imaging.PngBitmapEncoder
can resolve this
See System.Windows.Media.Imaging.PngBitmapEncoder
And How to: Encode and Decode a PNG Image for a sample.
Upvotes: 3