2010-09-19 19 views
15

Il mio problema è che il caricamento dell'immagine sembra non essere corretto dalle risorse dell'applicazione. Questo è un codice:Caricamento immagine in ImageSource - larghezza e altezza errate

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; 

file immagine "16x16_incorrect.png" è file PNG 16x16 32bpp, ma dopo aver eseguito sopra il codice, s.Width = s.Height = 21,59729 .... ho anche un altro file - "16x16_correct.png", quando lo carico nello stesso modo, sia la larghezza che l'altezza di ImageSource sono pari a 16,002.

Ho un grande pacchetto di immagini PNG 16x16 32bpp utili, che intendo utilizzare nell'IU delle mie app. Sfortunatamente, ognuno di essi che carica erroneamente & appare sfocato (o levigato), perché il sistema lo estende da 16x16 a 21x21.

  • corretta immagine: Correct Image
  • immagine non corretta: Incorrect Image

Vuoi da essere così gentilmente spiegare la possibile soluzione di questo problema? Se il problema nei file di immagine di origine, come posso modificare ImageSource.Width alla dimensione desiderata per poter utilizzare questi file?

risposta

11

È necessario impostare la risoluzione dell'immagine a 96 DPI (attualmente è 71,12 per il png errato).

È possibile farlo utilizzando il programma gratuito paint.net (http://getpaint.net) dal menu Immagine taglia SELEZIONA Canvas e impostare il campo "risoluzione" a 96

6

Ciò è dovuto al DPI delle immagini. WPF esegue il rendering di default con 96 dpi. Se si guarda il dpi dell'immagine png errata. Vedrai che è impostato su 72. Ciò fa in modo che WPF riduca l'immagine a 96 DPI e mantenga la dimensione originale.

Esistono due soluzioni. È possibile:

  1. Modificare il DPI utilizzando ad esempio XnView. Impostare a 96.
  2. Impostare le proprietà Larghezza e Altezza a 16, e la proprietà Stretch per Uniform

    <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

Grazie anche a te, hkon. :) – JSP

+0

La seconda soluzione non cambia affatto il DPI, semplicemente allungherà l'immagine originale per riempire (uniformemente) il contenitore che può portare a un'immagine sfocata. –

+0

Infatti, per l'esempio nella domanda penso che farebbe poca differenza. – hkon

17

Se non si desidera cambiare DPI esternamente si può farlo con questo:

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

Se avete solo bisogno valori corretti in Image.Source.Width/altezza si può fare qualcosa come ho fatto io:

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

e r esize in questo modo:

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

Ha preso in prestito il tuo metodo DPI, grazie. Per il rimborso, un bugfix (originale non funzionerebbe, ad esempio, con b/w tifs). – Will

Problemi correlati