从字节数组创建 PNG
Create a PNG from an array of bytes
我有一个一维字节数组,A、R、G 和 B 具有单独的值,并且我知道预期图像的高度和宽度。如何编码此数据并将其保存为 PNG?
您可以使用位图和 Bitmap.SetPixel()。
然后 save the Bitmap as png using ImageFormat.Png
. Also, you might have to make sure that the Bitmap format maintains transparency .
(请参阅此处的其他答案以获得比 SetPixel 更快的方法。)
编辑
也许WPF可以直接使用数组。 (我没有太多经验。)
这是使用 Unsafe pointers
和 LockBits
的更快解决方案
public unsafe Bitmap Retreive(byte[] values)
{
Bitmap bmp = new Bitmap(Width, Height); //enter your width and height here.
BitmapData bmData = bmp.LockBits(new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, bmp.PixelFormat);
IntPtr scan0 = bmData.Scan0;
int stride = bmData.Stride;
int nWidth = bmp.Width;
int nHeight = bmp.Height;
for (int y = 0; y < nHeight; y++)
{
//define the pointers inside the first loop for parallelizing
byte* p = (byte*)scan0.ToPointer();
p += y * stride;
for (int x = 0; x < nWidth; x++)
{
//fill as the values stored in you byte array;
p[0] = values[0];// R component.
p[1] = values[1];// G component.
p[2] = values[2];// B component.
p[3] = values[3];// Alpha component.
p += 4;
}
}
bmp.UnlockBits(bmData);
return bmp;
}
只需填写 p[]
值,就像它们存储在您的数组中一样。
祝你好运。
byte[] data = new byte[] {
255, 255, 000, 000, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 000, 000,
255, 255, 255, 255, 255, 255, 000, 000, 255, 255, 255, 255, 255, 255, 000, 000, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 000, 000, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 000, 000, 255, 255, 255, 255, 255, 255, 000, 000, 255, 255, 255, 255,
255, 255, 000, 000, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 000, 000
};
Bitmap bmp = new Bitmap(5, 5);
for (int y = 0; y < 5; ++y)
for (int x = 0; x < 5; ++x)
{
int offset = y * 5 * 4 + x * 4;
bmp.SetPixel(x, y, Color.FromArgb(data[offset], data[offset + 1], data[offset + 2], data[offset + 3]));
}
bmp.Save(@"c:\tmp.png");
}
如果数组中的值按此方式排序:B G R A B G R A B G R A ...您可以使用以下代码,它应该更快:
byte[] data = new byte[] {
// B G R A B G R A B G R A
0, 0, 255, 255, 0, 0, 0, 255, 0, 255, 0, 255,
0, 0, 0, 255, 0, 255, 0, 255, 255, 255, 255, 255,
0, 255, 0, 255, 0, 0, 0, 255, 255, 0, 0, 255
};
int width = 3;
int height = 3;
Bitmap bmp = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
var bitmapData = bmp.LockBits(new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.WriteOnly, bmp.PixelFormat);
Marshal.Copy(data, 0, bitmapData.Scan0, data.Length);
bmp.UnlockBits(bitmapData);
bmp.Save(@"c:\tmp.png");
这张图片应该是这样的:
我有一个一维字节数组,A、R、G 和 B 具有单独的值,并且我知道预期图像的高度和宽度。如何编码此数据并将其保存为 PNG?
您可以使用位图和 Bitmap.SetPixel()。
然后 save the Bitmap as png using ImageFormat.Png
. Also, you might have to make sure that the Bitmap format maintains transparency .
(请参阅此处的其他答案以获得比 SetPixel 更快的方法。)
编辑
也许WPF可以直接使用数组。 (我没有太多经验。)
这是使用 Unsafe pointers
和 LockBits
public unsafe Bitmap Retreive(byte[] values)
{
Bitmap bmp = new Bitmap(Width, Height); //enter your width and height here.
BitmapData bmData = bmp.LockBits(new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, bmp.PixelFormat);
IntPtr scan0 = bmData.Scan0;
int stride = bmData.Stride;
int nWidth = bmp.Width;
int nHeight = bmp.Height;
for (int y = 0; y < nHeight; y++)
{
//define the pointers inside the first loop for parallelizing
byte* p = (byte*)scan0.ToPointer();
p += y * stride;
for (int x = 0; x < nWidth; x++)
{
//fill as the values stored in you byte array;
p[0] = values[0];// R component.
p[1] = values[1];// G component.
p[2] = values[2];// B component.
p[3] = values[3];// Alpha component.
p += 4;
}
}
bmp.UnlockBits(bmData);
return bmp;
}
只需填写 p[]
值,就像它们存储在您的数组中一样。
祝你好运。
byte[] data = new byte[] {
255, 255, 000, 000, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 000, 000,
255, 255, 255, 255, 255, 255, 000, 000, 255, 255, 255, 255, 255, 255, 000, 000, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 000, 000, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 000, 000, 255, 255, 255, 255, 255, 255, 000, 000, 255, 255, 255, 255,
255, 255, 000, 000, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 000, 000
};
Bitmap bmp = new Bitmap(5, 5);
for (int y = 0; y < 5; ++y)
for (int x = 0; x < 5; ++x)
{
int offset = y * 5 * 4 + x * 4;
bmp.SetPixel(x, y, Color.FromArgb(data[offset], data[offset + 1], data[offset + 2], data[offset + 3]));
}
bmp.Save(@"c:\tmp.png");
}
如果数组中的值按此方式排序:B G R A B G R A B G R A ...您可以使用以下代码,它应该更快:
byte[] data = new byte[] {
// B G R A B G R A B G R A
0, 0, 255, 255, 0, 0, 0, 255, 0, 255, 0, 255,
0, 0, 0, 255, 0, 255, 0, 255, 255, 255, 255, 255,
0, 255, 0, 255, 0, 0, 0, 255, 255, 0, 0, 255
};
int width = 3;
int height = 3;
Bitmap bmp = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
var bitmapData = bmp.LockBits(new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.WriteOnly, bmp.PixelFormat);
Marshal.Copy(data, 0, bitmapData.Scan0, data.Length);
bmp.UnlockBits(bitmapData);
bmp.Save(@"c:\tmp.png");
这张图片应该是这样的: