我需要在Winforms应用程序中将2D数组(UInt16[,]
)显示为16位灰度图像。
我需要采取的步骤(大致):
从Bitmap
阵列构建UInt16[,]
- 请注意我需要有效地执行此操作,因为我希望最终以60 Hz或更高的频率更新图片
在主窗口上绘制Bitmap
,可能在PictureBox
,以60 Hz或更高的频率更新
我想根据PictureBox
From this question,我得到了有效(但不安全)的代码,可以从数组中构建Bitmap
。
另外,我检查过以确保我至少可以毫无问题地绘制预制图像,并且效果很好。
当我尝试显示Bitmap
UInt16[,]
时,我遇到了big red box of doom或(在不同的机器上运行)遇到{{1} },&& 34;参数无效。"
在我遇到失败之后,我获得了代码,以确定System.ArgumentException
中Bitmap
是否为空。这不是问题所在。
下面是一些使用虚拟数组来说明的示例代码。
主要表格代码
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
namespace IntArrViewer
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
int sz = 256;
UInt16[,] raw = new UInt16[sz, sz];
// Assign values to pixels
for (int i = 0; i < sz; i++)
for (int j = 0; j < sz; j++)
raw[i, j] = (UInt16)(i * sz + j);
// Get Bitmap from 2D array of UInt16
Bitmap intBmp= UInt16toBmp(raw, sz, sz);
// Get Bitmap from premade JPG
Bitmap preMadeBmp= new Bitmap(@"premade_pic.jpg");
// Verify that neither BMP is empty
bool emptyIntBmp= BmpIsEmpty(intBmp);
bool emptyPreMadeBmp= BmpIsEmpty(preMadeBmp);
// Set main picture box to premade image
mainPic.Image = preMadeBmp;
// Setting to array image raises an exception
// mainPic.Image = intBmp
}
public unsafe Bitmap UInt16toBmp(UInt16[,] frame, int width, int height)
{
int stride = width * 2;
Bitmap bitmap;
fixed (UInt16* intPtr = &frame[0, 0])
{
bitmap = new Bitmap(width, height, stride,
PixelFormat.Format16bppGrayScale,
new IntPtr(intPtr));
}
return bitmap;
}
public bool BmpIsEmpty(Bitmap bmp)
{
var data = bmp.LockBits(new Rectangle(0, 0, bmp.Width,
bmp.Height),
ImageLockMode.ReadOnly,
bmp.PixelFormat);
var bytes = new byte[data.Height * data.Stride];
Marshal.Copy(data.Scan0, bytes, 0, bytes.Length);
bmp.UnlockBits(data);
return bytes.All(x => x == 0);
}
}
}