5

私の仕事は、XPS ドキュメントの各ページのサムネイルをユーザーに表示することです。すべての画像を小さくする必要があるため、dpiを 72.0 に設定してレンダリングします (dpi 72.0 の A4 シートのサイズは 635x896 であるとグーグルで調べました)。基本的に、私は次のことを行います。

        List<BitmapImage> thumbnails = new List<BitmapImage>();
        documentPaginator.ComputePageCount();
        int pageCount = documentPaginator.PageCount;
        for (int i = 0; i < pageCount; i++)
        {
            DocumentPage documentPage = documentPaginator.GetPage(i);
            bool isLandscape = documentPage.Size.Width > documentPage.Size.Height;
            Visual pageVisual = documentPage.Visual;
            //I want all the documents to be less or equals to A4
            //private const double A4_SHEET_WIDTH = 635;
            //private const double A4_SHEET_HEIGHT = 896;
            //A4 sheet size in px, considering 72 dpi
            RenderTargetBitmap targetBitmap = new RenderTargetBitmap(
            (int)(System.Math.Min(documentPage.Size.Width, A4_SHEET_WIDTH)),
            (int)(System.Math.Min(documentPage.Size.Height, A4_SHEET_HEIGHT)),
            72.0, 72.0,
            PixelFormats.Pbgra32);
            targetBitmap.Render(pageVisual);
            BitmapFrame frame = BitmapFrame.Create(targetBitmap);
            PngBitmapEncoder encoder = new PngBitmapEncoder();
            encoder.Frames.Add(frame);
            BitmapImage image = new BitmapImage();
            using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
            {
                encoder.Save(ms);
                image.BeginInit();
                image.CacheOption = BitmapCacheOption.OnLoad;
                image.StreamSource = ms;
                if (isLandscape)
                {
                    image.Rotation = Rotation.Rotate270;
                }
                image.EndInit();
            }
            thumbnails.Add(image);
        }

しかし、ドキュメント ページ (A4) をレンダリングすると、実際のサイズは予想していたサイズではなく846x1194になります。dpi を低く (48.0) しようとしたところ、画像のサイズがさらに大きくなりました (dpi とは何か、それがドキュメントにどのように影響するかをよく理解していないだけだと思います)。dpi=96.0にしてみたところ、サイズが小さくなりました。BitmapImage上記のコードによって生成されたクラスのインスタンスのコレクションから画像の 1 つをImageコントロールのソースとして設定し (WPF アプリケーションを作成しています)、dpi が 96.0 に設定されている場合、プログラムは次のようになります。

サムネイルが正しく表示されない
ご覧のとおり、ページの一部がまったく表示されず、コントロールのサイズが635x896Imageに設定されていても、コントロール内に収まりません。そのため、上記のコードによれば、画像を正しく表示する必要があります。テキストが収まる必要があります。 一言で言えば、どのような結果が期待されますか: ドキュメントのページのサムネイルを作成しようとしていますが、それらを特定の数に比べて小さくしたいと考えています (申し訳ありませんが、そのようなことをどのように言うべきかよくわかりません)英語では、基本的にドキュメントのページ幅が 1200 px の場合は になりたい( nは前述の「数値」) が、縮小された画像のサイズがまだ635x896よりも大きい場合は、サイズを635x896にしたい.
1200/n
前もって感謝します。また、下手な英語で申し訳ありません。

4

1 に答える 1

20

まず、DPI とは Dots Per Inch、または Pixel Per Inch を意味します。A4 ページ (21 x 29.7 cm) を 72 DPI でビットマップにレンダリングする場合、次のサイズのビットマップになります。

  • 幅 = 21 cm / (2.54 cm/インチ) * 72 ピクセル/インチ = 595 ピクセル
  • 高さ = 29.7 cm / (2.54 cm/インチ) * 72 ピクセル/インチ = 842 ピクセル

これに加えて、1 つの例外を除いて、DPI についてあまり気にする必要はありません。WPF レンダリングは 96 DPI で行われます。これは、ドキュメントの A4 サイズのページが 794 x 1123 のビットマップにレンダリングされることを意味します。リマインダーとして:

  • 幅 = 21 cm / (2.54 cm/インチ) * 96 ピクセル/インチ = 794 ピクセル
  • 高さ = 29.7 cm / (2.54 cm/インチ) * 96 ピクセル/インチ = 1123 ピクセル

したがって、正確に A4 のページが含まれている場合、RenderTargetBitmap のサイズは 794 x 1123 になります。ページ サイズが A4 より小さい場合は、ビットマップを小さくする必要があります。一方、ページが A4 より大きい場合は、794 x 1123に縮小する必要があります。これがコツです。ページ ビジュアルを RenderTargetBitmap に直接レンダリングする代わりに、以下に示すように、ScaleTransformを使用してビジュアルをContainerVisualに配置できます。

for (int i = 0; i < paginator.PageCount; i++)
{
    DocumentPage page = paginator.GetPage(i);
    double width = page.Size.Width;
    double height = page.Size.Height;
    double maxWidth = Math.Round(21.0 / 2.54 * 96.0); // A4 width in pixels at 96 dpi
    double maxHeight = Math.Round(29.7 / 2.54 * 96.0); // A4 height in pixels at 96 dpi
    double scale = 1.0;
    scale = Math.Min(scale, maxWidth / width);
    scale = Math.Min(scale, maxHeight / height);

    ContainerVisual containerVisual = new ContainerVisual();
    containerVisual.Transform = new ScaleTransform(scale, scale);
    containerVisual.Children.Add(page.Visual);

    RenderTargetBitmap bitmap = new RenderTargetBitmap(
        (int)(width * scale), (int)(height * scale), 96, 96, PixelFormats.Default);

    bitmap.Render(containerVisual);

    ...
}
于 2012-10-30T20:11:15.167 に答える