使用来自 intptr 的可写位图创建位图时使用 WritePixels。
我目前正在尝试使用 writeablebitmap 来获取图像扫描的 IntPtr
并将每个图像转换为 Bitmap
。我想使用 writeablebitmap 因为我对标准 gdi 有问题 GDI+ System.Drawing.Bitmap 给出错误参数是间歇性无效
WriteableBitmap
上有一个名为 WritePixels
的方法 http://msdn.microsoft.com/en-us/library/aa346817。 我不确定我为缓冲区
和步幅设置了什么,我发现它显示步幅为 0,尽管这会引发错误。当我将步幅设置为 5 时,图像显示为黑色。我知道这可能不是最有效的代码,但任何帮助将不胜感激。
//create bitmap header
bmi = new BITMAPINFOHEADER();
//create initial rectangle
Int32Rect rect = new Int32Rect(0, 0, 0, 0);
//create duplicate intptr to use while in global lock
dibhand = dibhandp;
bmpptr = GlobalLock(dibhand);
//get the pixel sizes
pixptr = GetPixelInfo(bmpptr);
//create writeable bitmap
var wbitm = new WriteableBitmap(bmprect.Width, bmprect.Height, 96.0, 96.0, System.Windows.Media.PixelFormats.Bgr32, null);
//draw the image
wbitm.WritePixels(rect, dibhandp, 10, 0);
//convert the writeable bitmap to bitmap
var stream = new MemoryStream();
var encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(wbitm));
encoder.Save(stream);
byte[] buffer = stream.GetBuffer();
var bitmap = new System.Drawing.Bitmap(new MemoryStream(buffer));
GlobalUnlock(dibhand);
GlobalFree(dibhand);
GlobalFree(dibhandp);
GlobalFree(bmpptr);
dibhand = IntPtr.Zero;
return bitmap;
Im currently trying to use writeablebitmap to take a IntPtr
of a scan of images and turn each one into a Bitmap
. Im wanting to use writeablebitmap because im having an issue with standard gdi
GDI+ System.Drawing.Bitmap gives error Parameter is not valid intermittently
There is a method on a WriteableBitmap
that called WritePixels
http://msdn.microsoft.com/en-us/library/aa346817.aspx
Im not sure what I set for the buffer and the stride every example I find it shows the stride as 0 although that throws an error. When I set the stride to 5 the image appear black. I know this may not be the most efficient code but any help would be appreciated.
//create bitmap header
bmi = new BITMAPINFOHEADER();
//create initial rectangle
Int32Rect rect = new Int32Rect(0, 0, 0, 0);
//create duplicate intptr to use while in global lock
dibhand = dibhandp;
bmpptr = GlobalLock(dibhand);
//get the pixel sizes
pixptr = GetPixelInfo(bmpptr);
//create writeable bitmap
var wbitm = new WriteableBitmap(bmprect.Width, bmprect.Height, 96.0, 96.0, System.Windows.Media.PixelFormats.Bgr32, null);
//draw the image
wbitm.WritePixels(rect, dibhandp, 10, 0);
//convert the writeable bitmap to bitmap
var stream = new MemoryStream();
var encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(wbitm));
encoder.Save(stream);
byte[] buffer = stream.GetBuffer();
var bitmap = new System.Drawing.Bitmap(new MemoryStream(buffer));
GlobalUnlock(dibhand);
GlobalFree(dibhand);
GlobalFree(dibhandp);
GlobalFree(bmpptr);
dibhand = IntPtr.Zero;
return bitmap;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在 C# 中处理位图的一种有效方法是暂时以不安全模式传递(我知道我没有准确回答问题,但我认为 OP 没有设法使用位图,所以这可能是一个解决方案)。您只需锁定位即可完成:
这确实比 SetPixel(i, j) 高效得多,您只需小心指针限制(并且不要忘记在你完成了)。
现在回答有关步幅的问题:步幅是一行的长度(以字节为单位),它是 4 的倍数。在我的示例中,我使用格式
Format32bppArgb
,它每个像素使用 4 个字节(R、 G、B 和 alpha),因此newImageData.Stride
和newImageData.Width * 4
始终相同。我在循环中使用偏移量只是为了显示需要的地方。但如果您使用其他格式,例如
Format24bppRgb
,每个像素使用 3 个字节(仅限 R、G 和 B),则步幅和宽度之间可能存在偏移。对于这种格式的 10 * 10 像素图像,步幅为 10 * 3 = 30, + 2 才能达到最接近的 4 倍数,即 32。An efficient way to work on Bitmaps in C# is to pass temporarily in unsafe mode (I know I don't answer the question exactly but I think the OP did not manage to use Bitmap, so this could be a solution anyway). You just have to lock bits and you're done:
This is really much more efficient than
SetPixel(i, j)
, you just have to be careful about pointer limits (and not forget to unlock data when you're done).Now to answer your question about stride: the stride is the length in bytes of a line, it is a multiple of 4. In my exemple I use the format
Format32bppArgb
which uses 4 bytes per pixel (R, G, B and alpha), sonewImageData.Stride
andnewImageData.Width * 4
are always the same. I use the offset in my loops only to show where it would be necessary.But if you use another format, for instance
Format24bppRgb
which uses 3 bytes per pixel (R, G and B only), then there may be an offset between stride and width. For an image 10 * 10 pixels in this format, you will have a stride of 10 * 3 = 30, + 2 to reach nearest multiple of 4, i.e. 32.