Loading image into ImageSource - incorrect width and height

JSP picture JSP · Sep 19, 2010 · Viewed 18.6k times · Source

My problem is that the image loading seems to be uncorrectly from application resources. This is code:

    BitmapImage bi = new BitmapImage();
    bi.BeginInit();
    bi.UriSource = new Uri(@"pack://application:,,,/WpfApplication3;component/Resources/Images/16x16_incorrect.png", UriKind.Absolute);
    bi.EndInit();

    ImageSource s = bi;

Image file 16x16_incorrect.png is 16x16 32bpp PNG file, but after executing above code, s.Width = s.Height = 21,59729.... I also have another file - 16x16_correct.png, when it is loaded, both the ImageSource's Width and Height are equal to 16,002.

Other images each of them are loading incorrectly & it looks blurred (or smoothly), because system stretches it from 16x16 to 21x21.

  • correct image : Correct Image
  • incorrect image : Incorrect Image

What is causing this? If the problem in source image files, how can I change ImageSource.Width to desired size in order to use this files?

Answer

Dominic picture Dominic · Apr 14, 2011

If you don't want to change DPI externally you can do it with this:

public static BitmapSource ConvertBitmapTo96DPI(BitmapImage bitmapImage)
{
    double dpi = 96;
    int width = bitmapImage.PixelWidth;
    int height = bitmapImage.PixelHeight;

    int stride = width * bitmapImage.Format.BitsPerPixel;
    byte[] pixelData = new byte[stride * height];
    bitmapImage.CopyPixels(pixelData, stride, 0);

    return BitmapSource.Create(width, height, dpi, dpi, bitmapImage.Format, null, pixelData, stride);
}

If you just need correct values in Image.Source.Width/Height you can do something like I did:

this.myImage.Tag = new double[] { bitmapImage.DpiX, bitmapImage.DpiY };
this.myImage.Source = bitmapImage;

and resize it like so:

public static void ResizeImage(Image img, double maxWidth, double maxHeight)
{
    if (img == null || img.Source == null)
        return;

    double srcWidth = img.Source.Width;
    double srcHeight = img.Source.Height;

    // Set your image tag to the sources DPI value for smart resizing if DPI != 96
    if (img.Tag != null && img.Tag.GetType() == typeof(double[]))
    {
        double[] DPI = (double[])img.Tag;
        srcWidth = srcWidth / (96 / DPI[0]);
        srcHeight = srcHeight / (96 / DPI[1]);
    }

    double resizedWidth = srcWidth;
    double resizedHeight = srcHeight;

    double aspect = srcWidth / srcHeight;

    if (resizedWidth > maxWidth)
    {
        resizedWidth = maxWidth;
        resizedHeight = resizedWidth / aspect;
    }
    if (resizedHeight > maxHeight)
    {
        aspect = resizedWidth / resizedHeight;
        resizedHeight = maxHeight;
        resizedWidth = resizedHeight * aspect;
    }

    img.Width = resizedWidth;
    img.Height = resizedHeight;
}