8

WPF アプリケーションで (次のコードを使用して) JPEG を表示すると、Windows 画像ビューアーで JPEG を実際のサイズで開いた場合よりも大幅に小さく表示されます。

実行時に ImageSource のプロパティを掘り下げましたが、イメージには次のものがあります。

  • 219 の DPI
  • 高さ 238.02739726027397
  • 312.54794520547944 の幅
  • 543 の PixelHeight
  • および 713 の PixelWidth

スクリーンルーラーを使用して画像のWPF表示を測定すると、約になります。313x240 ピクセル (定規を完全に配置できれば、ImageSource が報告している幅と高さにおそらく等しくなります)。

私の直感では、これは WPF が (ピクセルではなく) デバイスに依存しない単位を使用していることと関係があるとのことですが、意味がわかりません。543x713 の「実際の」サイズで画像を表示する方法を知る必要があります。私のアプリケーションで。

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

4 に答える 4

11

ありがとうマーク!私はあなたの情報に基づいていくつかのグーグルを行い、私が望む結果を得るための解決策を提供するこの記事を見つけました. これは今では意味を成し始めています...

編集:リンクロット。記事の重要なテキストを参照用にここに貼り付けます....

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

ここでは、Stretch を Uniform に設定し、Width と Height を Source の PixelWidth と >PixelHeight にバインドして、実質的に DPI を無視しています。ただし、SnapToDevicePixels (画像内のピクセルではなく境界線をスナップするだけ) を使用している場合でも、画像は完全なピクセルではありません。ただし、3.5 SP1 の WPF は NearestNeighbor >BitmapScalingMode をサポートするため、これは修正されるはずです。

于 2009-03-13T21:01:03.457 に答える
6

96 の DPI を使用します。イメージ ビューアーがピクセルを表示している間、WPF はインチ単位のサイズに基づいてイメージをスケーリングします。ほとんどの Windows システムでは、画面解像度は 96 DPI であると想定されているため、画像でそれを使用すると、1 対 1 の変換が行われます。

于 2009-03-13T20:47:34.737 に答える
3

または、Image を拡張し、MeasureOverride と ArrangeOverride を実装して、画像の 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));
    }
}

イメージであるかのように xaml で使用します。

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

上記のコードの欠陥 (私が知っている):

  • ストレッチを無視
  • ソースが BitmapImage であると仮定します

=== 編集 - ウィルのコメントは、彼が 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;
    }
于 2011-06-21T06:29:51.617 に答える
1

これは、DPI を指定する .jpg ファイル自体の結果です。WPF は単に従っています。 これは、いくつかの解決策で問題を詳述しているフォーラムの投稿です。

于 2009-03-13T20:50:12.050 に答える