-
Before opening an issue, I would like to know if I'm doing something wrong or not. I wanted to open a png file, convert it to bmp in memory to access raw pixel data, modify some bytes in the array, and then save it back to a new png file. The results are not like I expected. So, for easier debugging, I created a bmp image from the modified byte array and got the byte array to surprisingly find that the values are changed. This is the code I'm testing: var pngFile = "Sample32bitImage1.png";
using (var image = Image.Load(pngFile))
{
var pngBitDepth = image.Metadata.GetPngMetadata().BitDepth.Value;
var bmpEncoder = new BmpEncoder();
bmpEncoder.BitsPerPixel = (BmpBitsPerPixel)pngBitDepth;
MemoryStream ms = new MemoryStream();
image.SaveAsBmp(ms, bmpEncoder);
var imgBytes = ms.ToArray();
imgBytes[500] = 100;
imgBytes[600] = 200;
imgBytes[700] = 200;
MemoryStream ms2 = new MemoryStream();
var outputBmpImage = Image.Load(imgBytes);
outputBmpImage.SaveAsBmp(ms2, bmpEncoder);
var outputImgBytes = ms2.ToArray();
} I chose positions far away from the header bytes to avoid creating a bad format image. Pixel data starts on byte 54. I think that imgBytes and outputImgBytes should be exactly the same, but that's not the case. But if we take a look at the modified array positions, the actual values are quite confusing: imgBytes[700] and outputImgBytes[700] match, but not 500 and 600 positions. I know there are ways to directly manipulate pixels using Imagesharp, as explained here, but I'm interested in modifying bytes directly, not caring about bit depth when doing that. And the question is... am I doing something wrong with this approach trying to manipulate bytes or is it some kind of bug? |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 1 reply
-
You're using show and tell for asking questions. |
Beta Was this translation helpful? Give feedback.
-
I'm not associated any way with this project, I'm evaluating this for Greenshot. You could just as well read a BMP from a file directly into memory. As you are not using the library... Going directly on a byte array representation of a BMP is also going to bring you many surprises (e.g. the pixels are encoded in a certain color format, the lines are bottom to top, etc etc,), depending on what format was used. This is actually what such libraries as ImageSharp do for you, especially if you want to modify pixels. Looking at your question, I do not think that this is the place discussing the ins and outs of directly modifying a BMP (which is a file format) in memory. Just my 2 cents... |
Beta Was this translation helpful? Give feedback.
-
After some struggle I finally have my little app ported from Magick.NET to ImageSharp, working fine and taking about 10% of the original Magick.NET version disk space. And it also works fine both in Windows and Linux (Ubuntu 21.04). Answering myself, I was doing MANY things wrong. While Magick.NET does all the bit depth and color mode conversions between formats automatically, in Imagesharp you have to do it manually, and bit depth it's not the same concept for bmp and png files. As an example, in bmp format an ARGB image is 32 bit depth but the equivalent in png is the combination of 8 bit depth and ARGB color mode. And I was initially converting the original ARGB png to 8 bit indexed color bmp, degrading the image, and even worse, creating a big header to store all the indexed colors, while I was only taking the first pixel data offset byte and messing directly with the headers, ruining the image completely. @Lakritzator yeah, you are partially right. I know that modifying image pixel bytes is an unorthodox way of doing things and it's out of the scope of the project, but I needed an image library to do the conversions between png and bmp (PNG -> BMP -> PNG). The thing is, I was doing the image conversions wrong and not getting the correct value for the pixel array offset. |
Beta Was this translation helpful? Give feedback.
After some struggle I finally have my little app ported from Magick.NET to ImageSharp, working fine and taking about 10% of the original Magick.NET version disk space. And it also works fine both in Windows and Linux (Ubuntu 21.04).
Answering myself, I was doing MANY things wrong. While Magick.NET does all the bit depth and color mode conversions between formats automatically, in Imagesharp you have to do it manually, and bit depth it's not the same concept for bmp and png files. As an example, in bmp format an ARGB image is 32 bit depth but the equivalent in png is the combination of 8 bit depth and ARGB color mode. And I was initially converting the original ARGB png to 8 bit indexed co…