在 Visual C# 中从由 PixelData 组成的 Byte[] 数组创建位图图像
Creating a BitMap Image out of a Byte[] Array consisting of PixelData in Visual C#
在一个大学项目中,我和我的团队必须构建一个扫描单元。处理完扫描单元 returns 一个由 8 位灰度值组成的字节数组(高度大约 3,7k 像素,宽度大约 20k 像素,这个巨大的分辨率是必要的,所以设置 PixelData Pixelwise 是不可取的这会花很多时间)。
在网上搜索时,我在 This SO 主题中找到了答案。我试过如下实现:
public static class Extensions
{
public static Image ImageFromArray(
this byte[] arr, int width, int height)
{
var output = new Bitmap(width, height, PixelFormat.Format16bppGrayScale);
var rect = new Rectangle(0, 0, width, height);
var bmpData = output.LockBits(rect,
ImageLockMode.ReadWrite, output.PixelFormat);
var ptr = bmpData.Scan0;
Marshal.Copy(arr, 0, ptr, arr.Length);
output.UnlockBits(bmpData);
return output;
}
}
我试过 运行 函数的数组填充如下:
testarray[0] = 200;
testarray[1] = 255;
testarray[2] = 90;
testarray[3] = 255;
testarray[4] = 0;
testarray[5] = 0;
testarray[6] = 100;
testarray[7] = 155;
并希望在图片框中显示 bmp:
pictureBox1.Image = Extensions.ImageFromArray(testarray, 2, 2);
调试时,代码通过函数运行,但结果显示错误图像。
此外,如果有人知道更简单的方法来计算任务,那么分享一下方法会非常好。我找不到方法
- 在 C# 中使用 8 位灰度像素格式
- 创建一个包含流和 PixelFormat 的位图对象
非常感谢您的帮助:)
使用 Format8bppIndexed 并设置明显的调色板
Bitmap ImageFromArray(byte[] arr, int width, int height)
{
var output = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
var rect = new Rectangle(0, 0, width, height);
var bmpData = output.LockBits(rect,ImageLockMode.WriteOnly, output.PixelFormat);
var ptr = bmpData.Scan0;
if (bmpData.Stride != width)
throw new InvalidOperationException("Cant copy directly if stride mismatches width, must copy line by line");
Marshal.Copy(arr, 0, ptr, width*height);
output.UnlockBits(bmpData);
var palEntries = new Color[256];
var cp = output.Palette;
for (int i = 0; i < 256; i++)
cp.Entries[i] = Color.FromArgb(i, i, i);
output.Palette = cp;
return output;
}
将 PictureBox.SizeMode 设置为 StretchImage。你可能会需要它。
在一个大学项目中,我和我的团队必须构建一个扫描单元。处理完扫描单元 returns 一个由 8 位灰度值组成的字节数组(高度大约 3,7k 像素,宽度大约 20k 像素,这个巨大的分辨率是必要的,所以设置 PixelData Pixelwise 是不可取的这会花很多时间)。
在网上搜索时,我在 This SO 主题中找到了答案。我试过如下实现:
public static class Extensions
{
public static Image ImageFromArray(
this byte[] arr, int width, int height)
{
var output = new Bitmap(width, height, PixelFormat.Format16bppGrayScale);
var rect = new Rectangle(0, 0, width, height);
var bmpData = output.LockBits(rect,
ImageLockMode.ReadWrite, output.PixelFormat);
var ptr = bmpData.Scan0;
Marshal.Copy(arr, 0, ptr, arr.Length);
output.UnlockBits(bmpData);
return output;
}
}
我试过 运行 函数的数组填充如下:
testarray[0] = 200;
testarray[1] = 255;
testarray[2] = 90;
testarray[3] = 255;
testarray[4] = 0;
testarray[5] = 0;
testarray[6] = 100;
testarray[7] = 155;
并希望在图片框中显示 bmp:
pictureBox1.Image = Extensions.ImageFromArray(testarray, 2, 2);
调试时,代码通过函数运行,但结果显示错误图像。
此外,如果有人知道更简单的方法来计算任务,那么分享一下方法会非常好。我找不到方法
- 在 C# 中使用 8 位灰度像素格式
- 创建一个包含流和 PixelFormat 的位图对象
非常感谢您的帮助:)
使用 Format8bppIndexed 并设置明显的调色板
Bitmap ImageFromArray(byte[] arr, int width, int height) { var output = new Bitmap(width, height, PixelFormat.Format8bppIndexed); var rect = new Rectangle(0, 0, width, height); var bmpData = output.LockBits(rect,ImageLockMode.WriteOnly, output.PixelFormat); var ptr = bmpData.Scan0; if (bmpData.Stride != width) throw new InvalidOperationException("Cant copy directly if stride mismatches width, must copy line by line"); Marshal.Copy(arr, 0, ptr, width*height); output.UnlockBits(bmpData); var palEntries = new Color[256]; var cp = output.Palette; for (int i = 0; i < 256; i++) cp.Entries[i] = Color.FromArgb(i, i, i); output.Palette = cp; return output; }
将 PictureBox.SizeMode 设置为 StretchImage。你可能会需要它。