获取 Controls.Image 宽度和高度

发布于 2024-10-10 05:39:30 字数 1168 浏览 0 评论 0原文

我是 WPF 新手,正在尝试使用 Controls.Image。我将其设置为在表单展开时拉伸。我正在尝试在运行时生成 Drawing.Bitmap 以显示在 WPF 中的 Controls.Image 上。当我生成 Drawing.Bitmap 时,我只想创建一个与屏幕上的 Image 控件一样大的图(不要浪费 cpu 周期)。为了创建图像,我有以下代码。 Bitmap bImage = new Bitmap((int)imgInput.Width, (int)imgInput.Height);imgInput 是 Controls.Image,bImage 显然是 Drawing.Bitmap。然而,imgInput.Width 和 Height 在运行时显示为 0,尽管它们绝对不是在设计时。如果我不尝试动态拉伸图像以随窗口扩展,则不会出现按预期显示的问题。那么我如何实际获取图像呢?还有人有比在内存中创建 Drawing.Bitmap 并将其转换为 WPF 的 ImageSource 更好的方法吗?我没有从 URI 或类似的东西加载图像,我必须在内存中创建它。

我通过以下代码绑定图像

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

下壹個目標 2024-10-17 05:39:30

从位图创建图像对我来说看起来不错。

XAML 图像将根据位图本身的宽度/高度以及“可用”空间来重新调整大小。 WPF 使用两遍布局系统 - 在第一轮中,每个控件都会被询问它需要多少空间,在第二轮中,每个控件会被分配一个宽度/高度。

在绑定位图之前,如果图像控件的祖先都没有固定/最大宽度,则您无法检索图像高度,因为还没有设置。

一种方法是通过绑定根据祖先设置图像的宽度/高度,这同样需要在容器上设置一些宽度/高度。

网格容器示例:

<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}" />

此外,您还需要仔细选择容器 - StackPanel 即始终会与其子级一起增长(如果方向为水平,则垂直增长,反之亦然),除非您指定固定或最大宽度/高度。其他容器的行为有所不同,即 UniformGrid 会同等地调整其所有子容器的大小。我会先尝试只有一行的网格。

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.

假装不在乎 2024-10-17 05:39:30

要获取 SourceHeightWidth,您需要将代码更改为

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

imgInput.WidthimgInput.Height 给出控件的高度和宽度,

imgInput.Source.WidthimgInput.Source.Height 给出源的高度和宽度

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文