dko
dko

Reputation: 904

Getting a Controls.Image Width and Height

I'm new to WPF and am trying to use a a Controls.Image. I have it set to stretch when the form expands. I am trying to generate a Drawing.Bitmap at runtime to display on the Controls.Image in WPF. When I generate the Drawing.Bitmap I only want to create one as big as the Image control on the screen is (don't waste cpu cycles). To create the image I have the following code. Bitmap bImage = new Bitmap((int)imgInput.Width, (int)imgInput.Height);imgInput is the Controls.Image and bImage obviously is the Drawing.Bitmap. However the imgInput.Width and Height are showing as 0 at runtime although they are definitely not at design time. If I don't try to dynamically stretch the image to expand with the window there is no issue it shows as expected. So how do I actually get the image. Also does anyone have a better way than creating a Drawing.Bitmap in memory and converting it over to a ImageSource for WPF? I am not loading an image from a URI or anything like that I have to create it in memory.

I am binding the image by the following code

            imgInput.Source = loadBitmap(bImage);

    }
    [DllImport("gdi32")]
    static extern int DeleteObject(IntPtr o);

    public static BitmapSource loadBitmap(System.Drawing.Bitmap source)
    {
        BitmapSource bs = null;
        IntPtr ip = source.GetHbitmap();
        try
        {
            bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(ip,
               IntPtr.Zero, Int32Rect.Empty,
               System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
        }
        finally
        {
            DeleteObject(ip);
        }

        return bs;
    }

Upvotes: 1

Views: 2357

Answers (2)

BrokenGlass
BrokenGlass

Reputation: 161002

The image creation from bitmap looks ok to me.

The XAML image will re-size depending on the width/height of the bitmap itself and how much space is "available". WPF uses a two pass layout system - in the first round each control is asked how much space it desires, in the second each control is assigned a width/height.

Before binding the bitmap and if none of the ancestors of your image control have a fixed/maximum width you cannot retrieve the image height, simply because there is none set yet.

One approach would be setting the width/height of the Image based on an ancestor via binding, again this would require some set width/height on the container.

Example for Grid container:

<Image Source="sample.png" 
        Width="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type Grid}},Path=ActualWidth}" 
        Height="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type Grid}},Path=ActualHeight}" />

Also you want to choose your container carefully - a StackPanel i.e. will always grow with its children (vertically if Orientation is Horizontal and vice versa) unless you specify a fixed or maximum width/height. Other containers behave differently, i.e. a UniformGrid would size all its children equally. I would try a Grid with only one row first.

Upvotes: 3

Binil
Binil

Reputation: 6583

To get the Height and Width of the Source you need to change you code to

Bitmap bImage = new Bitmap((int)imgInput.Source.Width, (int)imgInput.Source.Height);

imgInput.Width and imgInput.Height gives the Height and Width of the Control,

imgInput.Source.Width and imgInput.Source.Height gives the Height and Width of the Source

Upvotes: 0

Related Questions