2009-03-13 22 views
6

Cuando visualizo un JPEG en mi aplicación WPF (usando el siguiente código), se muestra significativamente más pequeño que si abro el JPEG en el visor de imágenes de Windows en real tamaño.La imagen dentro de una aplicación WPF se muestra más pequeña que cuando se ve en el visor externo

He perforado en las propiedades de mi ImageSource en tiempo de ejecución y mi imagen tiene:

  • un DPI de 219
  • una altura de 238,02739726027397
  • una anchura de 312,54794520547944
  • un PixelHeight de 543
  • y una PixelWidth de 713

Cuando uso una regla de pantalla para medir la visualización WPF de la imagen, obtengo aprox. 313x240 píxeles (que si pudiera posicionar la regla perfectamente probablemente sería igual al ancho y alto que el ImageSource está informando).

Mi instinto me dice que esto tiene algo que ver con el uso de unidades independientes de dispositivo (en lugar de píxeles) de WPF pero no puedo entenderlo, y todavía necesito saber cómo mostrar la imagen en el 'real 'tamaño de 543x713 en mi aplicación.

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Height="300" Width="300"> 
    <StackPanel> 
     <Image Source="Image15.jpg" Stretch="None" /> 
    </StackPanel> 
</Window> 

Respuesta

4

Utilice un DPI de 96. WPF está ampliando su imagen basándose en el tamaño en pulgadas, mientras que el visor de imágenes está mostrando píxeles. En la mayoría de los sistemas Windows, se supone que la resolución de la pantalla es de 96 ppp, por lo que usar eso en la imagen dará como resultado una traducción de uno a uno.

+0

Si alguien necesita una herramienta para el DPI corrección: puede usar [Paint.NET] (http://www.getpaint.net), que es gratis y fácil de usar para este propósito. – Beauty

1

Este es el resultado del propio archivo .jpg que especifica el DPI - WPF simplemente obedece. Here is a forum post detallando el problema con algunas soluciones:

8

Gracias Mark! Hice un poco de google basado en su información y encontré this article que proporcionaba una solución para obtener el resultado que quería. Esto está empezando a tener sentido ahora ...

Editar: Linkrot. Pegando el texto crítico del artículo de aquí por referencia ....

<Image Source=”{Binding …}” 
     Stretch=”Uniform” 
     Width=”{Binding Source.PixelWidth,RelativeSource={RelativeSource Self}}” 
     Height=”{Binding Source.PixelHeight,RelativeSource={RelativeSource Self}}” /> 

Aquí hemos establecido Estirar para uniforme y con destino la anchura y la altura a la PixelWidth y> PixelHeight de la Fuente, haciendo caso omiso de manera efectiva DPI. Sin embargo, la imagen no será píxel> perfecta, incluso cuando se utiliza SnapToDevicePixels (que simplemente ajusta los bordes, no los píxeles> dentro de la imagen). Sin embargo, WPF en 3.5 SP1 admitirá un NearestNeighbor> BitmapScalingMode, que debería corregir esto.

+0

Utilicé estos en un enlace múltiple para almacenar en la etiqueta del control de imagen para su uso posterior, ¡gracias! –

+0

El ** BitmapScalingMode ** se puede aplicar así: '' – Beauty

3

Como alternativa, puede extender la imagen y poner en práctica MeasureOverride y ArrangeOverride para cambiar el efecto de los DPI de la imagen:

class DpiAgnosticImage : Image 
{ 
    protected override Size MeasureOverride(Size constraint) 
    { 
     var bitmapImage = Source as BitmapImage; 

     var desiredSize = bitmapImage == null 
      ? base.MeasureOverride(constraint) 
      : new Size(bitmapImage.PixelWidth, bitmapImage.PixelHeight); 

     var dpiScale = MiscUtil.GetDpiScale(this); 
     desiredSize = new Size(desiredSize.Width/dpiScale.Width, desiredSize.Height/dpiScale.Height); 

     desiredSize = ImageUtilities.ConstrainWithoutDistorting(desiredSize, constraint); 

     if (UseLayoutRounding) 
     { 
      desiredSize.Width = Math.Round(desiredSize.Width); 
      desiredSize.Height= Math.Round(desiredSize.Height); 
     } 

     return desiredSize; 
    } 

    protected override Size ArrangeOverride(Size finalSize) 
    { 
     return new Size(Math.Round(DesiredSize.Width), Math.Round(DesiredSize.Height)); 
    } 
} 

utilizarlo en XAML como si se tratara de una imagen:

<Grid> 
    <local:DpiAgnosticImage 
    Stretch="None" 
    Source="{Binding ViewImage}"> 
    <Image.RenderTransform> 
     <ScaleTransform 
     x:Name="SomeName"/> 
    </Image.RenderTransform> 
    </local:DpiAgnosticImage> 
</Grid> 

Código de defectos a los de arriba (que yo sepa):

  • Ignora estiramiento
  • Asume Fuente es un BitmapImage

=== Editar - comentario de Will sugiere que le gustaría saber lo que está en GetDpiScale()

public static Size GetDpiScale(Visual visual) 
    { 
     var source = PresentationSource.FromVisual(visual); 

     var dpiScale = new Size(
      source.CompositionTarget.TransformToDevice.M11, 
      source.CompositionTarget.TransformToDevice.M22); 

     return dpiScale; 
    } 
+0

MiscUtil? Servicial. – Will

Cuestiones relacionadas