简体   繁体   中英

Get original size of BitmapImage after changing the DecodePixelWidth/Height

Due to performance reasons, I have to rescale a very large BitmapImage (eg 45000*10000 pixels) during loading. As the image can be zoomed, I cannot simply specify a fixed size but would reduce the pixel size by some (later dynamic) factor:

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();

After initialization is finished, the PixelWidth is equal to the DecodePixelWidth. However, I would somehow need to access the original width and hight of the image. Is it somehow possible to get this information directly out of the image object, or do I have to store it somewhere else?

The problem is, that BitmapImage is sealed, so I cannot extend the class with the new parameters - however, I would like to pass the result image to the source of an Image control.

You should be able to get the original dimensions of the image file using the 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);
}

You can then store the values in variables for later use.

Sometimes, you don't see the forest for the trees... BitmapImage is a dependency object. So no need to derive from the sealed class but simply create some attached properties:

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));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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