3

I want to load an image and put it into a viewbox. The image is displayed correctly, but, when I'm going to get it's width and height, it's both NaN.

This is my image load code :

Image img = new Image();
img.Source = (ImageSource)new ImageSourceConverter().ConvertFromString("1.png");

Viewbox vb = new Viewbox();

vb.Width = img.Width;
vb.Height = img.Height;

vb.Child = img;

cnv.Children.Add(vb);

The reason I want to get the image width and height is so I could resize it (via viewbox resize) later inside the application.

Any idea how to get the image dimension?

And this is how I'm going to resize it (via mouse wheel)

    private void cnv_MouseWheel(object sender, MouseWheelEventArgs e)
    {
        if (vb != null)
        {
            vb.Width += Mouse.MouseWheelDeltaForOneLine;
            vb.Height += Mouse.MouseWheelDeltaForOneLine;
        }
    }

And it returns error and said that vb.Width is not a valid value.

Questions to sum this up :

  1. How to get the image width / height in wpf?
  2. How to resize the viewbox (which will also result in image resize) via mouse wheel? For example, if I scroll up the wheel, the width and height is added by 1, and if I scroll down the wheel, the width and height is reduced by 1.

Thank you

P.S. Viewbox vb; and Image img; is a global variable, I just shorten the script down. P.S.S. I know if the Viewbox width and height initialized by a number, lets say 100 and 100, it will work, I just wanna know how to get the image original size.

EDIT : The resize can be achieved by detecting whether it's scrolled up or down by detecting e.Delta > 0 or e.Delta < 0 (Source : http://social.msdn.microsoft.com/Forums/vstudio/en-US/170c4fd0-1441-4d83-903d-594af75f8fb4/detect-mouse-scroll)

Moses Aprico
  • 1,951
  • 5
  • 30
  • 53

2 Answers2

5

It seems as though the Image object is not fully loaded at that stage. I believe that you can use the Width and Height properties of the ImageSource class instead. That should be fully loaded at this stage.

ImageSource.Width Property
ImageSource.Height Property

For other users, you can also possibly find the values that you want from the ActualWidth and ActualHeight properties of the Image class (inherited from the FrameworkElement class) instead of the more usual Width and Height properties.

FrameworkElement.ActualHeight Property
FrameworkElement.ActualWidth Property

Sheridan
  • 68,826
  • 24
  • 143
  • 183
  • Can you elaborate what do you mean by "fully loaded"? Isn't if the image is successfully shown, then it's "fully loaded"? – Moses Aprico May 21 '14 at 09:59
  • 1
    When you set an `Image.Source` property, the Framework has to complete some work to load the actual source into memory and make it available for display. See the answer to the [Dynamic loading of images in WPF](http://stackoverflow.com/questions/569561/dynamic-loading-of-images-in-wpf) question for an example of the kind of thing that I'm talking about. I can't think of any other reason for you not getting dimension values, other than your image actually having no dimensions. – Sheridan May 21 '14 at 10:04
  • Hmm. So, there's a "delay" because they got processed on, let say a different thread? – Moses Aprico May 21 '14 at 10:15
  • 2
    In essence, yes. Using the Width and Height properties in the way you're using them is not the recommended way of doing things in WPF. In case of bitmaps the easiest way is probably to look at the actual dimensions of the png file (see my answer below). Width and Height contain the desired width and height or double.NaN if not set, ActualWidth and ActualHeight are only valid after the UI has been rendered, which is not right after you have set the Source property. – Markus May 21 '14 at 19:17
0

The image original size can only be obtained in Pixels while your WPF controls are measured in Device Independent Pixels so you're going to have to make a translation from Pixels to Device Independent Pixels and back wherever necessary.

That said, to obtain the width and height for a png file, you can load it into a BitmapImage instead of Image and query the PixelWidth and PixelHeight properties for the BitmapImage.

Again, be aware that this is the only place in your code where you're going to be dealing with Pixels, all Width and Height properties (including ActualWidth and ActualHeight, only set after the control is fully rendered) are measured in Device Independent Pixels. This can be misleading because in a lot of situations this happens to be a 1:1 conversion but this is not guaranteed to be the case.

More info can be found here: http://msdn.microsoft.com/en-us/library/windows/desktop/ff684173%28v=vs.85%29.aspx

Markus
  • 116
  • 4