You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WPF Image控件设置BitmapSource时尺寸不符问题求助(附现有代码及解决尝试)

WPF Image控件设置BitmapSource时尺寸不符问题求助(附现有代码及解决尝试)

各位好,我碰到一个WPF Image控件的尺寸适配问题,想请教下大家:

我用Emgu.CV读取图片后,将其转换为BitmapSource并设置给WPF的Image控件,但发现显示的尺寸和原图片的像素尺寸不一致——原图片读取后是1700×2200,可设置到Image.Source后,Width和Height变成了1360×1760,我希望Image控件能严格按照原图片的像素尺寸来显示。


现有实现代码

图片读取与Source设置部分

// Get a specific page then display it.
Emgu.CV.Mat[]? emguPageMats = CvInvoke.Imreadmulti(randomTestPreviewPath,
Emgu.CV.CvEnum.ImreadModes.Color);

Emgu.CV.Image<Bgr, byte> emguImage = emguPageMats[0].ToImage<Bgr, byte>();

// 调试输出原图片尺寸
Debug.Print(emguPageMats[0].Width + ", " + emguPageMats[0].Height); -> **返回 1700, 2200**

image.Source = ConvertBitmapToBitmapSource(emguImage.ToBitmap(), emguImage);

// 调试输出Image.Source的尺寸
Debug.Print(image.Source.Width + ", " + image.Source.Height); -> **返回 1360, 1760**

转换方法(重命名后使用)

public static BitmapSource ConvertBitmapToBitmapSource(System.Drawing.Bitmap bitmap,
Emgu.CV.Image<Bgr, byte> emguImage)
{
    var bitmapData = bitmap.LockBits(
        new System.Drawing.Rectangle(0, 0, emguImage.Width, emguImage.Height),
        System.Drawing.Imaging.ImageLockMode.ReadOnly, bitmap.PixelFormat);

    var bitmapSource = BitmapSource.Create(
        bitmapData.Width, bitmapData.Height,
        bitmap.HorizontalResolution, bitmap.VerticalResolution,
        PixelFormats.Bgr24, null,
        bitmapData.Scan0, bitmapData.Stride * bitmapData.Height, bitmapData.Stride);

    bitmap.UnlockBits(bitmapData);
    return bitmapSource;
}

我的排查与解决尝试

初步发现

我后来注意到,BitmapSource的实际像素尺寸是存在PixelWidth和PixelHeight属性里的,而不是直接用Width和Height——但我不知道怎么让Image控件直接使用这个像素尺寸来显示。

临时解决方法

后来我尝试通过屏幕DPI计算缩放比例,手动设置Image控件的Width和Height,目前看起来能得到正确的尺寸,但总觉得写法可以更优雅,想问问有没有更合适的方案:

// Get a specific page then display it.
Emgu.CV.Mat[]? emguPageMats = CvInvoke.Imreadmulti(randomTestPreviewPath,
Emgu.CV.CvEnum.ImreadModes.Color);

Emgu.CV.Image<Bgr, byte> emguImage = emguPageMats[0].ToImage<Bgr, byte>();
maxPages = emguPageMats.Count();

image.Source = ConvertBitmapToBitmapSource(emguImage.ToBitmap(), emguImage);

// 读取屏幕DPI(测试中dpi.X和dpi.Y都是120)
public static System.Drawing.PointF dpi;
using (Graphics graphics = Graphics.FromHwnd(IntPtr.Zero))
{
    dpi.X = graphics.DpiX;
    dpi.Y = graphics.DpiY;
}

// 根据DPI计算缩放比例,将Source的Width/Height转换为像素尺寸对应的控件尺寸
double d = (1d / 96) * dpi.X;
var finalWidth = image.Source.Width * d;
var finalHeight = image.Source.Height * d;

Debug.Print("final: " + finalWidth + ", " + finalHeight);

// 手动设置Image控件的宽高
image.Width = finalWidth;
image.Height = finalHeight;

Debug.Print("image: " + finalWidth + ", " + finalHeight);

感谢大家花时间看我的问题,希望能得到更好的建议!


备注:内容来源于stack exchange,提问作者CJP

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.21 07:04:51