【问题标题】:Getting a Controls.Image Width and Height获取 Controls.Image 的宽度和高度
【发布时间】:2011-01-03 02:56:07
【问题描述】:

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

【问题讨论】:

  • 如何将位图绑定到图像?您是否在 XAML 中为您的图像明确设置了宽度/高度?
  • 图像的宽度和高度设置为自动,但我相信这是允许水平和垂直对齐设置为拉伸的必要条件
  • 这可以解释它 - 图像将根据其内容重新调整大小,因此在您将位图绑定到它之前它没有任何宽度
  • 图像应该只调整大小到它的父级,当它的父级调整大小时,它也应该这样做
  • 我猜最后一个问题是,有没有比 Bitmap 更好的东西可以让我指定每个像素的值,并且比转换 Bitmap 更有效

标签: .net wpf image-processing bitmap


【解决方案1】:

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

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 将平等地调整其所有子容器的大小。我会先尝试一个只有一行的网格。

【讨论】:

    【解决方案2】:

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

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

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

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

    【讨论】:

    • 好的,如果初始来源为空怎么办?
    • 无法获取空对象的大小。您需要验证这一点。
    • 在问题的场景中,源还没有设置,所以它总是为空,这种方法是行不通的
    猜你喜欢
    • 2017-12-26
    • 1970-01-01
    • 2012-10-10
    • 2021-06-30
    • 1970-01-01
    • 2010-11-18
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多