I'm using Microsoft Surface 2.0 SDK with SUR40 PixelSense compatible computer. I need to capture image from it's touch and save it as .bmp
. Since Surface SDK comes with RawImageVisualizer example, which displays picture from touch on the screen, I've tried to modify program for writing picture to HDD. The problem is, I get ArgumentException: Parameter is invalid
during building Image
from byte array captured from touch.
This is how I retrieve byte array with image data from FrameReceivedEventArgs
on FrameReceived
event:
event.UpdateRawImage(
ImageType.Normalized,
normalizedImage,
0, 0,
InteractiveSurface.PrimarySurfaceDevice.WorkingAreaWidth,
InteractiveSurface.PrimarySurfaceDevice.WorkingAreaHeight);
And that's how I try to write bytes as .bmp
to disk:
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);
So I get the exception trying to create Image
from stream. Nevertheless this byte array works totally fine with Texture2D
and SpriteBatch
which displays it. How can I fix ArgumentException
?
i've just realized, that UpdateRawImage
does not return a byte representation of PNG
file, but only an array of pixels. So, to build an image from it, one have to write all other parts of file structure to the array: header and color table (if needed). In many cases this can be simply done with one of System.Drawing.Bitmap
constructors:
public Bitmap(
int width,
int height,
int stride,
PixelFormat format,
IntPtr scan0
)
But I was not so lucky, because UpdateRawImage
returns 8bpp grayscale pixels, and PixelFormat
enum doesn't support them (the most close is Format16bppGrayScale
, but it uses 2 bytes for pixel, not one). So, in this particular situation, there are two obvious solutions. The first is making a new array of pixels, which meets one of PixelFormat
standards (that was my choice, because I need 24-bit RGB image, despite it's actually black-white with only 256 shades). The second is writing BMP
headers manually (and it's not very difficult due to open specs).