Wpf 为什么要创建新位图以转换为BitmapImage?
我在一些遗留代码中有一个转换器,它做了一些似乎错误的事情,但我不太了解位图。 看起来它是基于 具有一些附加功能Wpf 为什么要创建新位图以转换为BitmapImage?,wpf,bitmap,valueconverter,Wpf,Bitmap,Valueconverter,我在一些遗留代码中有一个转换器,它做了一些似乎错误的事情,但我不太了解位图。 看起来它是基于 具有一些附加功能 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
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.Collections.Generic;
使用系统、绘图、成像;
利用制度全球化;
使用System.IO;
使用System.Linq;
使用系统文本;
使用System.Windows.Data;
使用System.Windows.Media.Imaging;
名称空间CompanyName.Converters
{
[ValueConversion(typeof(System.Drawing.Image)、typeof(System.Windows.Media.ImageSource))]
///
///从System.Drawing.Image到System.Windows.Media.ImageSource的单向转换器
///
公共类图像转换器:IValueConverter
{
公共对象转换(对象值、类型targetType、对象参数、CultureInfo区域性)
{
//空图像是空的。。。
如果(值==null)
{
返回null;
}
if(value.GetType()==typeof(System.Drawing.Image))
{
var image=(System.Drawing.image)值;
//Winforms映像我们要从以下位置获取WPF映像。。。
var bitmap=new System.Windows.Media.Imaging.BitmapImage();
bitmap.BeginInit();
MemoryStream MemoryStream=新的MemoryStream();
//保存到内存流。。。
保存(memoryStream,ImageFormat.Bmp);
//倒流。。。
memoryStream.Seek(0,System.IO.SeekOrigin.Begin);
bitmap.StreamSource=memoryStream;
EndInit();
bitmap.Freeze();
返回位图;
}
else if(value.GetType()==typeof(System.Drawing.Bitmap))
{
var image=值为System.Drawing.Bitmap;
System.Drawing.Bitmap Bitmap=新的System.Drawing.Bitmap(图像);
使用(MemoryStream memory=new MemoryStream())
{
保存(内存,ImageFormat.Png);
记忆位置=0;
BitmapImage BitmapImage=新的BitmapImage();
bitmapImage.BeginInit();
bitmapImage.StreamSource=内存;
bitmapImage.CacheOption=BitmapCacheOption.OnLoad;
bitmapImage.EndInit();
bitmapImage.Freeze();
返回位图图像;
}
}
返回null;
}
公共对象转换回(对象值、类型targetType、对象参数、CultureInfo区域性)
{
返回null;
}
}
}
你到底为什么要
System.Drawing.Bitmap Bitmap=new System.Drawing.Bitmap(image)代码>?这难道不只是在内存中创建位图的副本而没有任何好处吗?这是可怕的代码还是有正当理由在转换前复制位图?通过构造函数复制位图而不明确指定像素格式将导致图像转换为32bpp argb,如果您试图绑定到目标不支持的像素格式的图像,这将反过来防止出现问题。在WPF的情况下,图像控件确实正确呈现索引图像,但可能有其他格式或其他控件类型会失败。最初的作者可能只是试图涵盖所有的基础。这只是一段可怕的代码System.Drawing.Image
是一个抽象类,因此value.GetType()==typeof(System.Drawing.Image)
将始终为false。它应该是值为System.Drawing.Image
。else
块将是多余的,因为Bitmap
是从Image
派生的。当然,您可以使用else
部分中的来为MemoryStream保留块。@Clemens在else分支中创建的位图
此时可以安全地处理吗?或者BitmapImage
仍然需要它吗?您应该删除else块。这完全是多余的。@Clemens,不。在Mark在这里发布的答案中指出,.GetType()
永远不会返回抽象类。所以if块是完全无用的,else是实际发生的。这无关紧要,因为位图也是图像。当您只需检查if(值为System.Drawing.Image)
(如我之前所写)时,它将以相同的方式处理所有图像派生类,包括位图。这就是为什么我们不能有好的编码。感谢您的副作用知识,以及不删除它的好理由。