0
votes

Let's say I want a method that does some manipulation on an image by messing with its pixel values and then returns an image which is otherwise the "same" (equal PixelFormat, RawFormat, VerticalResolution, etc.).

public static Image DoSomeManipulation(this Image source)
{
    // ... 
}

I've been finding this remarkably difficult to do because to manipulate its pixels I want to use Bitmap and I can't find a way to create a Bitmap which has the same ImageFormat.

I've tried:

var target = new Bitmap(source);

and

var temp = new Bitmap(source)
var target = temp.Clone(new Rectangle(0, 0, temp.Width, temp.Height), source.PixelFormat);

and

var temp = new Bitmap(source)
var target = temp.Clone(new Rectangle(0, 0, temp.Width, temp.Height), temp.PixelFormat);

and while each of them works some of the time for my test on my 1,000 random files (PNGs, JPGs, etc.), all of them fail

Assert.AreEqual(target.ImageFormat, source.ImageFormat);

some of the time and I can't figure out why that is.

Is there any solution that doesn't involve one of

  • Serializing and deserializing source (Yes, I've seen this)
  • If source is a local file, creating copy in Temp storage or something like that

??

The ImageFormat class refers to image file formats on disk (or rather, when serialized). It does not refer to GDI's internal raster representation (a DIB or DDB). For example, you cannot directly edit JPEG in-memory in System.Drawing (because a JPEG file doesn't have "pixels") - that's why you have to load it into memory as a raster bitmap first. It sounds like you want to save an in-memory raster as a DIB using the image/bmp format that has the same pixel format as a source image? - Dai
@Dai Unfortunately I'm new too image processing and don't quite speak the language of "GDI", "raster", etc. I'll need an "explain to me like I'm 5 years old" explanatation. :) Basically, I could use an example where I do Image.Load(sourceImagePath), change 1 pixel, then save back to same path (in its "original format" with same resolution and everything, if that concept even makes sense). - user11389375
Gotcha. Well, in many cases that might not be possible depending on the change you made (e.g. loading a 256-color GIF image into a Bitmap then using a color that isnt in the GIF's original palette - so it's impossible to save it back to a 256-color GIF because now there's 257 colors). What are the file-types you're trying to load? (Both the container format and their internal formats, e.g. 24-bit PNG vs 256-color PNG, GIF, JFIF/JPEG using what quality settings? Etc) - Dai
If you're loading Windows *.bmp files (the kind you make in MSPaint) then that means you're working with raster images which is much simpler than working with compressed formats or non-raster formats - but they can have different pixel formats (e.g. 32bpp, 24bpp, 8bpp). Do you have access to Photoshop or any other imaging tool that will show you detailed information about each file? - Dai
"all of them fail some of the time and I can't figure out why that is." - So, try to put that in an "if" with a breakpoint in it and see what's actually changed? Anyway, I really think you're worrying over nothing. Clone is a rather specialised operation which you normally don't need, and ImageFormat has no real effect once you write it back as a specific format anyway. - Nyerguds