问题
I want to copy bytes with Marshall.Copy. My code work, but bytes is strange for me. I think, I got indexes not real bytes. If this compute and save back, I got different colors in image with lot bigger byte size (image size is same).
Bitmap bmp = new Bitmap(imagepath);
Width = bmp.Width;
Height = bmp.Height;
byte[] data;
BitmapData bdata;
switch (bmp.PixelFormat)
{
case PixelFormat.Format8bppIndexed:
{
data = new byte[Width * Height];
bdata = bmp.LockBits(new Rectangle(0, 0, Width, Height),ImageLockMode.ReadOnly, bmp.PixelFormat);
Marshal.Copy(bdata.Scan0, data, 0, data.Length);
bmp.UnlockBits(bdata);
break;
}
}
Save image from bytes:
BitmapData bmData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, bmp.PixelFormat);
IntPtr pNative = bmData.Scan0;
Marshal.Copy(data, 0, pNative, Width * Height);
bmp.UnlockBits(bmData);
bmp.Save("output.gif",ImageFormat.Gif); //without format, have same problem
If I read color from first pixel, I got: Color [A=0, R=0, G=0, B=2]
. Is this really color in input image?
I don't know, why output is soo different from input. Where is problem?
Example from input and output (sorry for small images):
回答1:
You did not show how you created the second bmp
for reloading the bytes. But the PixelFormat
is 8bbpIndexed
, which means that your data
array will contain palette indices instead of direct color information. When you create your second bmp
with 8 bit pixel format it will use a default palette, which may be different from the original one.
So you must save the bmp.Palette
of the first image, then use it to restore the actual colors of your second bmp
instance.
Update: Though you can set the palette entries one by one, it has no effect. You must set the whole palette instead. Additionally, here is a post with indexed bitmap manipulation (see the ConvertPixelFormat
) method.
来源:https://stackoverflow.com/questions/41444923/copying-bytes-from-bitmap-to-byte-array-and-back-with-marshall-copy-doesnt-work