Reputation: 904
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
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
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