【问题标题】:Why would you create a new Bitmap to convert to BitmapImage?为什么要创建一个新的 Bitmap 来转换为 BitmapImage?
【发布时间】:2015-09-02 00:29:31
【问题描述】:

我在一些遗留代码中有一个转换器,它正在做一些看起来错误的事情,但我不太了解位图。 好像是基于https://stackoverflow.com/a/3427114/57883 具有一些附加功能。

using System;
using System.Collections.Generic;
using System.Drawing.Imaging;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Data;
using System.Windows.Media.Imaging;

namespace CompanyName.Converters
{
    [ValueConversion(typeof(System.Drawing.Image), typeof(System.Windows.Media.ImageSource))]

    /// <summary>
    /// One-way converter from System.Drawing.Image to System.Windows.Media.ImageSource
    /// </summary>
    public class ImageConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            // empty images are empty...
            if (value == null) 
            { 
                return null; 
            }

            if (value.GetType() == typeof(System.Drawing.Image))
            {
                var image = (System.Drawing.Image)value;

            // Winforms Image we want to get the WPF Image from...
            var bitmap = new System.Windows.Media.Imaging.BitmapImage();
            bitmap.BeginInit();
            MemoryStream memoryStream = new MemoryStream();

            // Save to a memory stream...
            image.Save(memoryStream, ImageFormat.Bmp);

            // Rewind the stream...
            memoryStream.Seek(0, System.IO.SeekOrigin.Begin);
            bitmap.StreamSource = memoryStream;
            bitmap.EndInit();
            bitmap.Freeze();
            return bitmap;
            }

            else if (value.GetType() == typeof(System.Drawing.Bitmap))
            {
                var image = value as System.Drawing.Bitmap;

                System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(image);

                using (MemoryStream memory = new MemoryStream())
                {
                    bitmap.Save(memory, ImageFormat.Png);
                    memory.Position = 0;
                    BitmapImage bitmapImage = new BitmapImage();
                    bitmapImage.BeginInit();
                    bitmapImage.StreamSource = memory;
                    bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
                    bitmapImage.EndInit();
                    bitmapImage.Freeze();
                    return bitmapImage;
                }
            }

            return null;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return null;
        }
    }
}

你到底为什么要System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(image);?这不是只是在内存中创建位图的副本而没有任何好处吗?这只是可怕的代码还是有正当理由在转换位图之前复制它?

【问题讨论】:

  • 这只是可怕的代码。 System.Drawing.Image 是一个抽象类,因此 value.GetType() == typeof(System.Drawing.Image) 将始终为 false。它应该是value is System.Drawing.Image。然后else 块将是多余的,因为Bitmap 是从Image 派生的。您当然会从 else 部分保留 MemoryStream 的 using 块。
  • @Clemens 在 else 分支中创建的Bitmap 此时可以安全地处理吗?还是BitmapImage 还需要它?
  • 你应该删除 else 块。这完全是多余的。
  • @Clemens 好吧,不。在 Mark here 发布的答案中,它指出 .GetType() 永远不会返回抽象类。所以 if 块完全没用, else 才是真正发生的事情。
  • 没关系,因为位图也是图像。当您只检查if (value is System.Drawing.Image)(正如我之前写的)时,它将处理所有图像派生类,包括位图以相同的方式。

标签: wpf bitmap valueconverter


【解决方案1】:

通过构造函数复制位图而不明确指定 PixelFormat 将导致图像被转换为​​ 32bpp argb,这反过来又可以防止在您尝试绑定到目标不使用的像素格式的图像时出现问题支持。在 WPF 的情况下,图像控件确实可以正确呈现索引图像,但可能有其他格式或其他控件类型会失败。原作者可能只是试图涵盖所有基础。

【讨论】:

  • 这就是为什么我们不能有好的编码的东西。感谢您提供有关副作用的知识,以及不删除它的充分理由。
猜你喜欢
  • 2021-10-20
  • 2011-09-22
  • 2013-12-31
  • 1970-01-01
  • 1970-01-01
  • 2016-07-14
  • 1970-01-01
  • 2018-08-26
  • 1970-01-01
相关资源
最近更新 更多