【问题标题】:Processing large bitmap images in WPF在 WPF 中处理大型位图图像
【发布时间】:2012-08-07 11:31:49
【问题描述】:

我需要每秒多次处理(更改亮度、对比度等)非常大的高质量位图(通常超过 10MPx),并且每次都需要在屏幕上更新它(在 WPF 中的图像控制上)。目前我正在使用 AForge.NET 库进行非托管图像处理,但有些问题我无法解决。首先,一个操作需要大约 300 毫秒(不更新屏幕),这对我来说是不可接受的。这是示例代码:

UnmanagedImage _img;
BrightnessCorrection _brightness = new BrightnessCorrection();

void Load()
{
   _img = UnmanagedImage.FromManagedImage((Bitmap)Bitmap.FromFile("image.jpg"));
}

void ChangeBrightness(int val) // this method is invoked by changing Slider value - several times per second
{
   _brightness.AdjustValue = val;
   _brightness.ApplyInPlace(_img); // it takes ~300ms for image 22MPx, no screen update - just change brightness "in background"
} 

我没有图像处理方面的经验,但我认为它的速度不会快很多,因为它的分辨率非常高。我说的对吗?

另一个问题——如何高效地更新屏幕?目前我有以下(ofc 非常糟糕)的解决方案:

void ChangeBrightness(int val)
{
   _brightness.AdjustValue = val;
   _brightness.ApplyInPlace(_img);

    using (MemoryStream ms = new MemoryStream())
    {
        using (Bitmap b = _img.ToManagedImage())
        {
            b.Save(ms, ImageFormat.Bmp);
            ms.Seek(0, SeekOrigin.Begin);

            var bmp = new BitmapImage();
            bmp.BeginInit();
            bmp.StreamSource = ms;
            bmp.CacheOption = BitmapCacheOption.OnLoad;
            bmp.EndInit();

            MyImageControl.Source = new WriteableBitmap(bmp); // !!!
        }
    }
}

如您所见,每次创建新的 WriteableBitmap 时(您可以想象会发生什么)。而不是这些“使用”,我尝试了这种方式:

    WriteableBitmapSource.Lock(); // this object (of type WriteableBitmap) is just MVVM ViewModel's property which is binded to MyImageControl.Source
    WriteableBitmapSource.Source.WritePixels(new Int32Rect(0, 0, _img.Width, _img.Height), _img.ImageData, _img.Stride * _img.Height * 3, _img.Stride, 0, 0); // image's PixelFormat is 24bppRgb

...但 WritePixels 方法抛出“值不在预期范围内”。任何想法为什么? 任何帮助将不胜感激:)

附: AForge.NET 是一个不错的选择吗?也许有更好的图像处理库?

对不起我的英语;P

【问题讨论】:

  • 我想 10MP 是你的问题 - 任何这样做的机器都会受到影响。我已经安装了 Photoshop,并且在 6MP 文件上需要一点时间来更改图像对比度/亮度。

标签: c#


【解决方案1】:

图像 22MPx 的~300ms 约为每像素 20 ns。应该差不多吧。

您需要考虑 CPU 成本和内存访问成本。

如果您想进一步改进这一点,请考虑: 1) 使用多个线程,每个线程负责位图的一部分。 2) 使用 SIMD 指令编写您自己的实现。 3) 不要对位图进行预处理,在需要时变换位图扫描线。

【讨论】:

    猜你喜欢
    • 2012-08-18
    • 2011-01-14
    • 2012-12-13
    • 2012-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多