更改 DecodePixelWidth/Height 后获取 BitmapImage 的原始大小

Get original size of BitmapImage after changing the DecodePixelWidth/Height

由于性能原因,我必须在加载过程中重新缩放非常大的 BitmapImage(例如 45000*10000 像素)。由于图像可以缩放,我不能简单地指定一个固定大小,而是将像素大小减小一些(后来的动态)因子:

image = new BitmapImage();
var memory = new MemoryStream();

using (var stream = File.OpenRead(fileName))
{
    stream.CopyTo(memory);
}

memory.Position = 0;
var tempImage = new BitmapImage();
tempImage.BeginInit();
tempImage.CacheOption = BitmapCacheOption.OnDemand;
tempImage.StreamSource = memory;
tempImage.EndInit();

memory.Position = 0;
image.BeginInit();
image.CacheOption = BitmapCacheOption.OnDemand;
image.CreateOptions = BitmapCreateOptions.DelayCreation;
image.StreamSource = memory;
image.DecodePixelWidth = tempImage.PixelWidth/2;
image.DecodePixelHeight = tempImage.PixelHeight/2;
image.EndInit();

初始化完成后,PixelWidth等于DecodePixelWidth。但是,我会以某种方式需要访问图像的原始宽度和高度。是否可以通过某种方式直接从图像对象中获取此信息,还是必须将其存储在其他地方?

问题是 BitmapImage 是密封的,所以我无法使用新参数扩展 class - 但是,我想将结果图像传递给 Image 控件的源.

您应该能够使用 BitmapDecoder:

获取图像文件的原始尺寸
int height;
int width;
using (var stream = File.OpenRead(fileName))
{
    var decoder = BitmapDecoder.Create(stream, BitmapCreateOptions.IgnoreColorProfile,
        BitmapCacheOption.Default);
    height = decoder.Frames[0].PixelHeight;
    width = decoder.Frames[0].PixelWidth;

    stream.CopyTo(memory);
}

然后您可以将这些值存储在变量中供以后使用。

有时候,只见树木不见森林... BitmapImage 是一个依赖对象。所以不需要从密封的 class 派生,只需创建一些附加属性:

public static int GetSourcePixelWidth(this BitmapSource bitmap) { return ((int)bitmap.GetValue(SourcePixelWidthProperty)).IfZero(bitmap.PixelWidth); }
public static void SetSourcePixelWidth(this BitmapSource bitmap, int value) { bitmap.SetValue(SourcePixelWidthProperty, value); }

public static readonly DependencyProperty SourcePixelWidthProperty =
        DependencyProperty.RegisterAttached("SourcePixelWidth", typeof(int), typeof(Attached), new PropertyMetadata(0));

public static int GetSourcePixelHeight(this BitmapSource bitmap) { return ((int)bitmap.GetValue(SourcePixelHeightProperty)).IfZero(bitmap.PixelHeight); }
public static void SetSourcePixelHeight(this BitmapSource bitmap, int value) { bitmap.SetValue(SourcePixelHeightProperty, value); }

public static readonly DependencyProperty SourcePixelHeightProperty =
        DependencyProperty.RegisterAttached("SourcePixelHeight", typeof(int), typeof(Attached), new PropertyMetadata(0));