2009-03-13 15 views
6

Po wyświetleniu pliku JPEG w aplikacji WPF (przy użyciu poniższego kodu) jest on wyświetlany znacznie mniej niż w przypadku otwarcia pliku JPEG w przeglądarce obrazów systemu Windows rozmiar.Obraz w aplikacji WPF jest wyświetlany mniejszy niż podczas przeglądania w przeglądarce zewnętrznej.

mam wiercić właściwościach mojego ImageSource przy starcie i mój obraz posiada:

  • DPI 219
  • wysokości 238.02739726027397
  • szerokości 312.54794520547944
  • PixelHeight z 543
  • i PixelWidth z 713

Kiedy używam linijki ekranowej do pomiaru wyświetlania WPF obrazu, otrzymuję ok. 313x240 pikseli (co gdybym mógł dokładnie ustawić linijkę prawdopodobnie byłby równy szerokości i wysokości raportowanej przez ImageSource.).

Moje gut mówi, że ma to coś wspólnego z korzystaniem przez WPF z jednostek niezależnych od urządzenia (zamiast pikseli), ale nie mogę tego zrozumieć, i nadal muszę wiedzieć, jak wyświetlić obraz w "rzeczywistym "rozmiar 543x713 w mojej aplikacji.

<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> 

Odpowiedz

4

Użyj DPI 96. WPF jest skalowanie obraz na podstawie rozmiaru w calach, natomiast przeglądarka zdjęć jest wyświetlanie pikseli. W większości systemów Windows przyjmuje się, że rozdzielczość ekranu wynosi 96 DPI, więc użycie tego na obrazie spowoduje tłumaczenie jeden na jeden.

+0

Jeśli ktoś potrzebuje narzędzie do DPI korekta: Możesz użyć [Paint.NET] (http://www.getpaint.net), który jest darmowy i łatwy w użyciu do tego celu. – Beauty

1

Jest to wynik samego pliku .jpg określającego DPI - WPF po prostu przestrzega. Here is a forum post opisując problem z niektórymi rozwiązaniami:

8

Dzięki Mark! Zrobiłem trochę Googling na podstawie twoich informacji i znalazłem this article, który dostarczył rozwiązanie, by uzyskać pożądany rezultat. Teraz zaczyna to mieć sens ...

Edytuj: Linkrot. Wklejając krytyczny tekst z artykułu tutaj dla odniesienia ....

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

Tutaj mamy ustawić Stretch jednolitych i związany szerokość i wysokość do PixelWidth i> PixelHeight Źródła, skutecznie ignorując DPI. Obraz jednak nie będzie pikselowy> idealny, nawet jeśli użyjemy SnapToDevicePixels (który po prostu zaskoczy granice, a nie piksele> w obrazie). Jednak WPF w 3.5 SP1 będzie obsługiwać NearestNeighbor> BitmapScalingMode, co powinno to poprawić.

+0

Używane w MultiBinding do przechowywania w tagu Image Control do późniejszego wykorzystania, thx! –

+0

** BitmapScalingMode ** można zastosować w następujący sposób: '' – Beauty

3

Alternatywnie, można rozszerzyć obraz i wdrożenia MeasureOverride i ArrangeOverride aby zmienić efekt obrazu w DPI:

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

używać go w XAML, jak gdyby był to obraz:

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

Błędy dotyczące powyższego kodu (który znam):

  • ignoruje Stretch
  • Zakłada źródłowy jest BitmapImage

=== Edit - komentarz zostanie sugeruje, że chciałby wiedzieć, co jest w 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? Pomocny. – Will

Powiązane problemy