3

I want to convert a pdf file to an image UI control in UWP using c#, xaml.

I've read another way to use the Flip Viewer, but I need each image file of the converted PDF file.

so I modified a bit of the existing sample To open a pdf file.

And my problem is that the quality of the converted image file is extremely bad.

I can not even see the letters.

but this quality problem is same on other pdf sample.

Take a look at my code.


private PdfDocument pdfDocument;

private async void LoadDocument()
    {
        pdfDocument = null;

        //Output means my image UI control (pdf image will be added)
        Output.Source = null;

        //PageNumberBox shows current page
        PageNumberBox.Text = "1";

        var picker = new FileOpenPicker();
        picker.FileTypeFilter.Add(".pdf");
        StorageFile file = await picker.PickSingleFileAsync();

        if (file != null)
        {               
            try
            {
                pdfDocument = await PdfDocument.LoadFromFileAsync(file);
            }
            catch (Exception ex)
            {                   
            }

            if (pdfDocument != null)
            {  // I use this text to move page.
                PageCountText.Text = pdfDocument.PageCount.ToString();                    
            }                
        }            

        uint pageNumber;
        if (!uint.TryParse(PageNumberBox.Text, out pageNumber) || (pageNumber < 1) || (pageNumber > pdfDocument.PageCount))
        {
            return;
        }

        Output.Source = null;

        // Convert from 1-based page number to 0-based page index.            
        uint pageIndex = pageNumber-1 ;

        using (PdfPage page = pdfDocument.GetPage(pageIndex))
        {
            var stream = new InMemoryRandomAccessStream();

            await page.RenderToStreamAsync(stream);

            BitmapImage src = new BitmapImage();
            Output.Source = src;
            await src.SetSourceAsync(stream);
        }
    }

And this is my xaml code.

<Grid>
    <ScrollViewer >            
                <TextBlock Name="ViewPageLabel"VerticalAlignment="center">Now page</TextBlock>                   
                <TextBox x:Name="PageNumberBox" InputScope="Number" Width="30" Text="1" TextAlignment="Right" Margin="5,0,5,0"
                        AutomationProperties.LabeledBy="{Binding ElementName=ViewPageLabel}"/>
                <TextBlock VerticalAlignment="Center">of <Run x:Name="PageCountText"/>.</TextBlock>
    </ScrollViewer>
</Grid>

Is there any suggestions?

Please help me.

Thanks for reading this.

Kay
  • 173
  • 14
  • 1
    I don't get blurry text in this example - https://comentsys.wordpress.com/2018/05/17/uwp-pdfview-app/ that I wrote - maybe there's something there, apologies for the link only comment, hopefully won't be deleted – RoguePlanetoid Aug 20 '18 at 08:31
  • 1
    @RoguePlanetoid Thanks for reply, I saw the comment!, but i think that quality problem is unavoidable. Well, if i reduce my image's width, then the image's quality looks little better. For now, I think that i just reduce my image's width to solve this problem. – Kay Aug 21 '18 at 06:50

2 Answers2

2

Ran into this issue recently, didn't see any definitive answer here, so here it goes:

JosephA is on the right track, but PdfPageRenderOptions does not have anything about image fidelity/quality or anything like that like I had hoped. However, it does allow you to specify image dimensions. All you have to do is scale up the dimensions.

I suspect what's going on is that the PDF has a scale that it would "like" to use, which is smaller than the image you want to draw. Without specifying dimensions, it's drawing the "small" image and then it's getting scaled up, causing the blurriness.

Instead, if you tell it to draw the image at a higher resolution explicitly, it will do PDF magic to make those lines crisper, and the resulting raster image won't have to scale/blur.

PdfPage page = _document.GetPage(pageIndex);
await page.RenderToStreamAsync(stream, new PdfPageRenderOptions {
    DestinationWidth = (uint)page.Dimensions.MediaBox.Width * s,
    DestinationHeight = (uint)page.Dimensions.MediaBox.Height * s
});

Something like this helps, where "s" is the scale factor to achieve the dimensions you need. PdfPage.Dimensions has a number of different properties other than just "MediaBox" that you may want to explore as well depending on your use case.

Ethan
  • 21
  • 2
0

It sounds like you are encountering the common problem where you need to dynamically adjust the resolution the PDF page is rendered at to an image.

I am not familiar with the that PDF library however it appears you need to use the RenderToStreamAsync() overload that takes a PdfPageRenderOptions parameter to accomplish this.

JosephA
  • 1,187
  • 3
  • 13
  • 27
  • Well, I think that i used already.. `await page.RenderToStreamAsync(stream);` Isn't this what you said? – Kay Aug 22 '18 at 08:36
  • My link was inaccurate my apologies, there are two overloads of RenderToStreamAsync() one that takes a single argument and one that takes two arguments. I was suggesting to try using the latter. – JosephA Aug 22 '18 at 15:15