2009-03-13 11 views
6

Khi tôi hiển thị JPEG trong ứng dụng WPF của mình (sử dụng mã sau), nó được hiển thị nhỏ hơn đáng kể so với khi tôi mở JPEG trong Trình xem ảnh Windows tại thực tế kích thước.Ảnh trong ứng dụng WPF hiển thị nhỏ hơn khi được xem trong trình xem bên ngoài

Tôi đã khoan vào các thuộc tính của ImageSource của tôi trong thời gian chạy và hình ảnh của tôi có:

  • một DPI của 219
  • một Chiều cao của 238,02739726027397
  • một Chiều rộng của 312,54794520547944
  • một PixelHeight của 543
  • và PixelWidth là 713

Khi tôi sử dụng thước đo màn hình để đo hiển thị hình ảnh WPF, tôi nhận được khoảng. 313x240 pixel (nếu tôi có thể positiont người cai trị hoàn toàn có thể sẽ bằng với Chiều rộng và Chiều cao mà ImageSource đang báo cáo.). Đường ruột của tôi cho tôi biết điều này có liên quan đến việc sử dụng các thiết bị độc lập của WPF (thay vì pixel) nhưng tôi không thể hiểu được nó, và tôi vẫn cần biết cách hiển thị hình ảnh tại 'thực tế 'kích thước 543x713 trong đơn đăng ký của tôi.

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

Trả lời

4

Sử dụng DPI 96. WPF sẽ thu nhỏ hình ảnh của bạn dựa trên kích thước tính bằng inch trong khi trình xem hình ảnh hiển thị pixel. Trên hầu hết các hệ thống Windows, độ phân giải màn hình được giả định là 96 DPI, vì vậy việc sử dụng nó trong hình ảnh của bạn sẽ dẫn đến một bản dịch một-một.

+0

Nếu ai đó cần một công cụ để các Sở KH & ĐT chỉnh sửa: Bạn có thể sử dụng [Paint.NET] (http://www.getpaint.net), miễn phí và dễ sử dụng cho mục đích này. – Beauty

1

Đây là kết quả của tệp .jpg tự xác định DPI - WPF chỉ đơn giản là tuân theo. Here is a forum post nêu chi tiết sự cố với một số giải pháp:

8

Cảm ơn Mark! Tôi đã làm một số Googling dựa trên thông tin của bạn và tìm thấy this article cung cấp một giải pháp để có được kết quả tôi muốn. Điều này đang bắt đầu có ý nghĩa bây giờ ...

Chỉnh sửa: Linkrot. Dán văn bản quan trọng từ các bài viết ở đây để tham khảo ....

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

Ở đây chúng ta đã thiết Stretch để Uniform và ràng buộc Width và Height cho PixelWidth và> PixelHeight của Source, bỏ qua một cách hiệu quả DPI. Tuy nhiên, hình ảnh sẽ không phải là pixel> hoàn hảo, ngay cả khi sử dụng SnapToDevicePixels (chỉ đơn giản là chụp các đường viền chứ không phải pixel> bên trong hình ảnh). Tuy nhiên, WPF trong 3.5 SP1 sẽ hỗ trợ một MaximumNeighbor> BitmapScalingMode, nên sửa lỗi này.

+0

Được sử dụng trong MultiBinding để lưu trữ trong Thẻ điều khiển hình ảnh để sử dụng sau này, thx! –

+0

** BitmapScalingMode ** bạn có thể áp dụng như thế này: ' ' – Beauty

3

Ngoài ra, bạn có thể mở rộng hình ảnh và thực hiện MeasureOverride và ArrangeOverride để thay đổi tác động của Sở KH & ĐT của hình ảnh:

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

Sử dụng nó trong XAML như thể nó là một hình ảnh:

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

Sai sót ở trên mã (mà tôi biết):

  • bỏ qua Stretch
  • Giả Nguồn là một BitmapImage

=== Edit - bình luận Will gợi ý ông muốn biết những gì có trong 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? Hữu ích. – Will