简体   繁体   English

快速缩放/裁剪位图图像流以在WPF中显示

[英]Quickly scale/crop a bitmap image stream for display in WPF

Question: 题:

What is a fast way to scale and/or crop a bitmap provided from a WritableBitmap for display in the UI? 缩放和/或裁剪WritableBitmap提供的位图以显示在UI中的快速方法是什么?

Requirements: 要求:

  1. Have Low CPU usage CPU使用率低
  2. Handle large images (5 Megapixel, abt 2500x2000 pixels) 处理大图像(5兆像素,约2500x2000像素)
  3. Resize and/or crop to the same resolution/area as the UI element the bitmap is displayed in. 调整大小和/或裁剪为与显示位图的UI元素相同的分辨率/区域。
  4. Use WPF 使用WPF

Specifically, it must allow a 14FPS 5 Megapixel camera image stream to be displayed in a WPF UI element at full speed. 具体来说,它必须允许14FPS 5百万像素摄像机图像流全速显示在WPF UI元素中。

Update: 更新:

I have been able to speed up the drawing quite a bit by painting to a Canvas control using an ImageBrush as follows, where m_bitmap is my WriteableBitmap : 通过使用如下所示的使用ImageBrush绘制到Canvas控件,我已经能够大大加快绘制速度,其中m_bitmap是我的WriteableBitmap

ImageBrush brush = new ImageBrush();
brush.ImageSource = m_bitmap;
brush.Stretch = Stretch.Uniform;
canvas.Background = brush;

I'm now able to get the full 14FPS, though it still using about 20% CPU, so I'm not sure how well it preform if I add another camera or two (the plan is to have 4 or so running). 我现在可以获得完整的14FPS,尽管它仍使用约20%的CPU,所以我不确定如果再添加一两个摄像机(计划运行4个左右),它的性能如何。

Another thing I think might be slowing down the drawing is the images are in a mono, Gray8, format, not the standard RGB32 (or is it bgra32 for WPF?) format. 我认为可能会减慢绘图速度的另一件事是图像采用单色,Gray8格式,而不是标准RGB32(或者WPF是bgra32?)格式。 If I understand correctly, the image has to be converted to the standard format to be displayed, which would add significant overhead to each frame's drawing time. 如果我理解正确,则必须将图像转换为要显示的标准格式,这会增加每帧绘制时间的开销。

Some background: 一些背景:

I'm currently working with a 5 Megapixel, 14 FPS, video camera and am trying to get the frames to render to the screen at full speed. 我目前正在使用5百万像素,14 FPS的摄像机,正在尝试将帧全速渲染到屏幕上。 I would like to do this using WPF. 我想使用WPF做到这一点。

I currently have an example in WinForms that runs full speed for an unscaled image, but (as I would expect) it has major trouble if I set the pictureBox.SizeMode = Zoom; 我目前在WinForms中有一个示例,该示例可以全速运行未缩放的图像,但是(正如我所期望的)如果设置pictureBox.SizeMode = Zoom;则存在很大的麻烦pictureBox.SizeMode = Zoom; . The example reads raw data directly from the camera stream to a buffer and then copies the data from the buffer into the bitmap set to the PictureBox control. 该示例将原始数据直接从相机流读取到缓冲区,然后将数据从缓冲区复制到设置为PictureBox控件的位图中。 The copy algorithm uses LockBits to speed things up. 复制算法使用LockBits加快速度。

I converted that example into WPF, rewriting the parts using Bitmap objects to instead use WritableBitmap objects and an Image control instead of PictureBox . 我将该示例转换为WPF,使用Bitmap对象重写了零件,而改用WritableBitmap对象和Image控件而不是PictureBox Unforunately this is not able to render the stream to the screen at any decent rate, scaled or unscaled. 不幸的是,这无法将流以任何适当的比例(已缩放或未缩放)呈现到屏幕上。 Both have significant CPU load and very slow updates. 两者都有大量的CPU负载和非常慢的更新。

The performance when rendering to the screen is turned off is great. 关闭渲染到屏幕时的性能很好。 It is able to process the image stream at full speed and resolution while using around 3% CPU and less than 100MB memory. 它能够以大约3%的CPU和少于100MB的内存来全速和高分辨率地处理图像流。

Note: when I say rendering to the screen is turned off, the WritableBitmap is still being continuously updated, only is not set to the Image control. 注意:当我说关闭向屏幕的渲染时,WritableBitmap仍在不断更新,只是未将其设置为Image控件。

I've seen a lot of discussion about getting fast bitmap updating in WPF, but have been unsuccessful in getting it to work at an reasonable speed/cpu load. 我已经看到了很多有关在WPF中快速更新位图的讨论,但是未能使其以合理的速度/ cpu负载工作。 Also I would like to have the image scaled in such a way that I can see the whole image. 另外,我希望以可以看到整个图像的方式缩放图像。

I imagine the key will lie in some sort of scaling/crop combination that needs to be done so that WPF will not try to render(cache?) all 5 million pixels, but only those on the screen, and only at the current screen resolution. 我想关键在于需要进行某种缩放/裁剪组合,以便WPF不会尝试渲染(缓存?)所有500万像素,而是仅渲染屏幕上的像素,并且仅以当前屏幕分辨率渲染。 。 I imagine/hope this can be done fairly easily and without too much hit to memory or CPU, but currently have no idea how to do so. 我想/希望可以很容易地做到这一点,并且不会对内存或CPU造成太大的影响,但是目前还不知道该怎么做。 I have found the DecodePixelWidth and DecodePixelHeight properties, but those are only applicable when loading an image from a file to a BitmapImage . 我已经找到DecodePixelWidthDecodePixelHeight属性,但是这些属性仅在将图像从文件加载到BitmapImage

Did you have a look at the following post? 您是否看过以下帖子?

Resizing WritableBitmap 调整WritableBitmap的大小

If it does not solve your problem, I have more questions for you: 如果它不能解决您的问题,那么我还有更多问题要问:

What is the resolution of your image? 您的图像分辨率是多少? Is the size of you UI element constant? UI元素的大小是否恒定? What's its size? 它的大小是多少?


Edit: After your edit, I noticed that you want to display a BitmapImage in Gray8 PixelFormat, why don't you try to set this property when creating your BitmapImage (m_bitmap)? 编辑:编辑后,我注意到您想以Gray8 PixelFormat显示BitmapImage,为什么在创建BitmapImage(m_bitmap)时不尝试设置此属性? m_bitmap.Format = PixelFormat.Gray8; m_bitmap.Format = PixelFormat.Gray8; // could not test //无法测试

I am certain that taking your 8 bits/pixel and multiplying the amount of bits needed per pixel by 4 while not gaining any quality is slowing down your application. 我敢肯定,将您的8位/像素乘以每个像素所需的位数乘以4而又不获得任何质量,将会减慢您的应用程序的速度。 Especially because you run operations on 32 bits per pixel images when you could be running those operations on 8 bits per pixel images. 尤其是因为您可以对每像素图像8位运行这些操作,所以您可以对每像素图像8位运行这些操作。

While its interface is a bit old-fashioned, I believe that convert (see http://en.wikipedia.org/wiki/ImageMagick ) is very often used (and may in fact be the industry standard). 虽然它的界面有点过时,但我相信convert (请参阅http://en.wikipedia.org/wiki/ImageMagick )非常常用(实际上可能是行业标准)。

Edit: StackOverflow has about 2,300 question tagged with imagemagick here . 编辑:StackOverflow上具有约2300问题标记imagemagick 位置 See for example What is the difference for sample/resample/scale/resize/adaptive-resize/thumbnail operators in ImageMagick convert? 例如,请参见ImageMagick convert中的样本/重采样/缩放/调整大小/自适应调整大小/缩略图运算符有何区别?

The OP for https://apple.stackexchange.com/a/41531 decided to go with ImageMagick. https://apple.stackexchange.com/a/41531的OP决定使用ImageMagick。 And the accepted answer to Efficient JPEG Image Resizing in PHP also suggests ImageMagick, with 19 votes. 对于PHP中的高效JPEG图像大小调整,公认的答案还建议ImageMagick,获得19票。

However, I don't know whether ImageMagick is capable of meeting your requirements of 14FPS, 5 Megapixels . 但是,我不知道ImageMagick是否能够满足您的14FPS 5 Megapixels的要求。

The only answer to Recommendation for real time image processing tools on Linux suggests a fork graphicsmagick , which seems to also be available for Windows. 对于Linux上的实时图像处理工具的Recommendation的唯一答案是fork graphicsmagick ,它似乎也可用于Windows。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM