1
我正在使用Kinect傳感器深度數據創建圖像。我想將傳感器集成到winforms應用程序中,所以我將示例MS應用程序轉換爲爲Picturebox創建位圖。該圖像只用於測試,所以我不關心性能問題。 我遇到的問題是WriteBitmap的返回值無效並導致引發異常。唯一的例外是位圖格式無效
Exception thrown: 'System.ArgumentException' in System.Drawing.dll
的代碼:
public partial class Results : Form
{
private KinectSensor sensor;
private DepthImagePixel[] depthPixels;
private byte[] colorPixels;
public Results()
{
InitializeComponent();
}
private void Results_Load(object sender, EventArgs e)
{
foreach (var potentialSensor in KinectSensor.KinectSensors)
{
if (potentialSensor.Status == KinectStatus.Connected)
{
this.sensor = potentialSensor;
break;
}
}
if (null != this.sensor)
{
// Turn on the depth stream to receive depth frames
this.sensor.DepthStream.Enable(DepthImageFormat.Resolution640x480Fps30);
// Allocate space to put the depth pixels we'll receive
this.depthPixels = new DepthImagePixel[this.sensor.DepthStream.FramePixelDataLength];
// Allocate space to put the color pixels we'll create
this.colorPixels = new byte[this.sensor.DepthStream.FramePixelDataLength * sizeof(int)];
this.sensor.DepthFrameReady += this.SensorDepthFrameReady;
// Start the sensor!
try
{
this.sensor.Start();
}
catch (IOException)
{
this.sensor = null;
}
}
if (null == this.sensor)
{
this.statusBarText.Text = "No sensor detected";
}
}
private void Results_FormClosing(object sender, FormClosingEventArgs e)
{
if (null != this.sensor)
{
this.sensor.Stop();
}
}
private void SensorDepthFrameReady(object sender, DepthImageFrameReadyEventArgs e)
{
using (DepthImageFrame depthFrame = e.OpenDepthImageFrame())
{
if (depthFrame != null)
{
// Copy the pixel data from the image to a temporary array
depthFrame.CopyDepthImagePixelDataTo(this.depthPixels);
// Get the min and max reliable depth for the current frame
int minDepth = depthFrame.MinDepth;
int maxDepth = depthFrame.MaxDepth;
// Convert the depth to RGB
int colorPixelIndex = 0;
for (int i = 0; i < this.depthPixels.Length; ++i)
{
// Get the depth for this pixel
short depth = depthPixels[i].Depth;
// To convert to a byte, we're discarding the most-significant
// rather than least-significant bits.
// We're preserving detail, although the intensity will "wrap."
// Values outside the reliable depth range are mapped to 0 (black).
byte intensity = (byte)(depth >= minDepth && depth <= maxDepth ? depth : 0);
this.colorPixels[colorPixelIndex++] = intensity;
this.colorPixels[colorPixelIndex++] = intensity;
this.colorPixels[colorPixelIndex++] = intensity;
// We're outputting BGR, the last byte in the 32 bits is unused so skip it
++colorPixelIndex;
}
//// Write the pixel data into our bitmap
try {
//// Write the pixel data into our bitmap
if (this.logImage.Image != null) this.logImage.Image.Dispose();
this.logImage.Image = null;
this.logImage.Image = WriteBitmap(this.sensor.DepthStream.FrameWidth, this.sensor.DepthStream.FrameHeight, this.colorPixels);
}catch(Exception ex)
{
Console.Write(ex);
}
}
}
}
Bitmap WriteBitmap(int width, int height, byte[] imageData)
{
using (var stream = new MemoryStream(imageData))
using (var bmp = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppRgb))
{
BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0,
width,
height),
ImageLockMode.WriteOnly,
bmp.PixelFormat);
Marshal.Copy(imageData, 0, bmpData.Scan0, imageData.Length);
bmp.UnlockBits(bmpData);
return bmp;
}
}
}