从PixelSense兼容PC的触摸中捕获图像并将其另存为.bmp

本文关键字:图像 bmp 另存为 兼容 PixelSense PC 触摸 | 更新日期: 2023-09-27 17:56:47

我正在使用Microsoft Surface 2.0 SDK和SUR40 PixelSense兼容计算机。我需要从它的触摸中捕获图像并将其另存为.bmp。由于Surface SDK附带了RawImageVisualizer示例,该示例在屏幕上显示触摸图片,因此我尝试修改用于将图片写入HDD的程序。问题是,我在从触摸捕获的字节数组构建Image时遇到ArgumentException: Parameter is invalid

这是我如何在事件FrameReceivedFrameReceivedEventArgs中检索带有图像数据的字节数组:

event.UpdateRawImage(
                ImageType.Normalized,
                normalizedImage,
                0, 0,
                InteractiveSurface.PrimarySurfaceDevice.WorkingAreaWidth,
                InteractiveSurface.PrimarySurfaceDevice.WorkingAreaHeight);

这就是我尝试将字节作为.bmp写入磁盘的方式:

System.Drawing.Image img;
using (System.Drawing.Image raw = System.Drawing.Image.FromStream(new MemoryStream(normalizedImage)))
{
    img = raw.Clone() as System.Drawing.Bitmap;
}
img.Save("C:/img.bmp", System.Drawing.Imaging.ImageFormat.Bmp);

所以我在尝试从流中创建Image时遇到异常。尽管如此,这个字节数组在显示它的Texture2DSpriteBatch上完全可以正常工作。如何修复ArgumentException

从PixelSense兼容PC的触摸中捕获图像并将其另存为.bmp

我刚刚意识到,UpdateRawImage不返回PNG文件的字节表示形式,而只返回一个像素数组。因此,要从中构建图像,必须将文件结构的所有其他部分写入数组:标题和颜色表(如果需要)。在许多情况下,这可以简单地使用System.Drawing.Bitmap构造函数之一来完成:

public Bitmap(
    int width,
    int height,
    int stride,
    PixelFormat format,
    IntPtr scan0
)

但我就没那么幸运了,因为UpdateRawImage返回 8bpp 灰度像素,而PixelFormat枚举不支持它们(最接近的是 Format16bppGrayScale ,但它使用 2 个字节作为像素,而不是一个)。因此,在这种特殊情况下,有两个明显的解决方案。首先是制作一个新的像素数组,它符合PixelFormat标准之一(这是我的选择,因为我需要 24 位 RGB 图像,尽管它实际上是黑白的,只有 256 种阴影)。第二种是手动编写BMP标头(由于开放规范,这不是很困难)。