2010-09-19 112 views
15

我的问题是图像加载似乎不正确地从应用程序资源中加载。这是代码:将图像加载到ImageSource中 - 宽度和高度不正确

BitmapImage bi = new BitmapImage(); 
    bi.BeginInit(); 
    bi.UriSource = new Uri(@"pack://application:,,,/WpfApplication3;component/Resources/Images/16x16_incorrect.png", UriKind.Absolute); 
    bi.EndInit(); 

    ImageSource s = bi; 

图像文件 “16x16_incorrect.png” 为16x16 32bpp的PNG文件,但上面的代码执行后,s.Width = s.Height = 21,59729 ....我也有另一个文件 - “16x16_correct.png”,当我以相同的方式加载它时,ImageSource的宽度和高度都等于16,002。

我有一大堆有用的PNG 16x16 32bpp图像,我打算在我的应用程序的UI中使用。不幸的是,它们每个都加载不正确&看起来模糊(或光滑),因为系统将其从16x16扩展到21x21。

  • 正确的图像:Correct Image
  • 不正确的图像:Incorrect Image

你愿意为这么好心来解释这个问题的可能的解决方案?如果源图像文件存在问题,我如何将ImageSource.Width更改为所需的大小以便使用此文件?

回答

11

您需要将图像分辨率设置为96 DPI(目前对于不正确的png,它是71.12)。

您可以使用免费的paint.net程序(http://getpaint.net)从图像菜单中选择画布大小做到这一点,并设置了“分辨率”字段96

6

这是因为图像的DPI。 WPF呈现96 dpi的默认值。如果您查看不正确的png图像的dpi。您会看到它被设置为72.这会导致WPF将图像缩放到96 DPI并保持原始大小。

有两种解决方案。 您可以:

  1. 使用例如XnView修改DPI。将它设置为96
  2. 设置宽度和高度属性为16,拉伸性能,以统一

    <Grid> 
    <Grid.RowDefinitions> 
        <RowDefinition /> 
        <RowDefinition /> 
        <RowDefinition /> 
    </Grid.RowDefinitions> 
    <Image x:Name="MyIncorrectImageFixed" Source="http://i.piccy.info/i5/24/41/504124/16x16_incorrect.png" Width="16" Height="16" Stretch="Uniform" /> 
    <Image x:Name="MyIncorrectImage" Source="http://i.piccy.info/i5/24/41/504124/16x16_incorrect.png" Stretch="None" Grid.Row="1" /> 
    <Image x:Name="MyCorrectImage" Source="http://i.piccy.info/i5/22/41/504122/16x16_correct.png" Stretch="None" Grid.Row="2" /> 
    

+1

也谢谢你,hkon。 :) – JSP 2010-09-19 15:58:49

+0

第二种解决方案根本不会改变DPI,它只会将原始图像拉伸(均匀)填充容器,从而导致模糊的图像。 – 2017-11-09 18:13:31

+0

事实上,对于这个问题中的例子,我认为它没有什么区别。 – hkon 2017-11-25 21:38:01

17

如果你不想改变外部DPI可以与此做到这一点:

public static BitmapSource ConvertBitmapTo96DPI(BitmapImage bitmapImage) 
{ 
    double dpi = 96; 
    int width = bitmapImage.PixelWidth; 
    int height = bitmapImage.PixelHeight; 

    int stride = width * bitmapImage.Format.BitsPerPixel; 
    byte[] pixelData = new byte[stride * height]; 
    bitmapImage.CopyPixels(pixelData, stride, 0); 

    return BitmapSource.Create(width, height, dpi, dpi, bitmapImage.Format, null, pixelData, stride); 
} 

如果你只需要在Image.Source.Width /身高正确的价值观,你可以做一些像我一样:

this.myImage.Tag = new double[] { bitmapImage.DpiX, bitmapImage.DpiY }; 
this.myImage.Source = bitmapImage; 

和r像这样调整它:

public static void ResizeImage(Image img, double maxWidth, double maxHeight) 
{ 
    if (img == null || img.Source == null) 
     return; 

    double srcWidth = img.Source.Width; 
    double srcHeight = img.Source.Height; 

    // Set your image tag to the sources DPI value for smart resizing if DPI != 96 
    if (img.Tag != null && img.Tag.GetType() == typeof(double[])) 
    { 
     double[] DPI = (double[])img.Tag; 
     srcWidth = srcWidth/(96/DPI[0]); 
     srcHeight = srcHeight/(96/DPI[1]); 
    } 

    double resizedWidth = srcWidth; 
    double resizedHeight = srcHeight; 

    double aspect = srcWidth/srcHeight; 

    if (resizedWidth > maxWidth) 
    { 
     resizedWidth = maxWidth; 
     resizedHeight = resizedWidth/aspect; 
    } 
    if (resizedHeight > maxHeight) 
    { 
     aspect = resizedWidth/resizedHeight; 
     resizedHeight = maxHeight; 
     resizedWidth = resizedHeight * aspect; 
    } 

    img.Width = resizedWidth; 
    img.Height = resizedHeight; 
} 
+4

借用你的DPI方法,谢谢。为了还款,一个错误修正(原始不起作用,例如,与黑白tifs)。 – Will 2014-02-21 14:46:30