0

I need to write my own pdf viewer (UserControl). I use pdfium.dll for that. The wrapper of it is PdfiumService. This service can render pages to BitmapSource. PdfViewer displays pages in VirtualizingStackPanel in ScrollViewer. Any ideas how can I do lazy render for pdf? The problem is if pdf is about 20mb (1000 pages), rendered pages take about 2gb RAM.

Can VirtualizingStackPanel help me? I didn't find any events for "BeginVirtualizing" or something else. Any easy ways to know what item is displaying now?

Maybe something like that:

  1. Calculate how many pages can be displayed at once.
  2. See ScrollViewer's offset.
  3. Calculate the index of page is now displaying.
  4. Render 5 pages next to current.

Are there any ready solutions, or some tips, or ideas for this?

DdarkSideE
  • 129
  • 1
  • 11
  • You can use ItemConrol Which is inside a scrollviewer and then using scrollviewer vertical offset you can create virtualization. – Mukesh Methaniya May 30 '17 at 09:51
  • Yes, sure. Question is not about it. I use ScrollViewer and ItemsControl in it, nad ItemsControl.ItemsPanel is VirtualizingStackPanel. I know how to bind data to containers. Is there esear way to do what I want? Or only calculate offsets and images size by hands? – DdarkSideE May 30 '17 at 09:54
  • i think there is no any easy way cause you have to also load only that page which is in view so you can calculate based on that – Mukesh Methaniya May 30 '17 at 10:05
  • It's not good. Thank you anyway. – DdarkSideE May 30 '17 at 10:13

1 Answers1

0

well, i had a bit of that with images from books....the trouble is not really the gui where you put the bitmap, but how you get the images from the library...is it one by one, sequentially or randomly ?

In fact, if you use a VirtualizingStackPanel it will only manage the gui element to create or destroy, but if you have a full collection of bitmaps in memory you are dead.

One way is to create Page object whitout the bitmap, and create the image when needed + add a timer that will clear all "oldest images"

I do something like that in CBR; and i use a custom control to display pages

private BitmapImage _Image = null;
    /// <summary>
    /// the image 
    /// </summary>
    public BitmapImage Image
    {
        get
        {
            if (_Image == null)
                _Image = (DocumentFactory.Instance.GetService(Parent) as BookService).GetImageFromStream(Parent.FilePath, FilePath);

            ImageLastAcces = DateTime.Now;
            return _Image;
        }
        set { _Image = value; }
    }
GCamel
  • 612
  • 4
  • 8
  • note that there is also a winform viewer that you can embed into your app https://github.com/pvginkel/PdfiumViewer – GCamel May 30 '17 at 15:18
  • I render pdf pages sequentially, I think. About VirtualizingStackPanel I understood that bitmaps stored in memory. And it is a problem. I've already written code to render only displayed pages based on page size, control size and ScrollViewer's offset. Well, about clear all oldest iamges. What is better? Clean up based on time or on scroll offset? – DdarkSideE May 30 '17 at 16:55
  • i would say perhaps on index because on a scrollviewer, if i use arrows or page down key, i can quiclly fill up the memory in a very short time and cleaning on time will not work. By the way, you gave me a good solution (pdfium) to start including PDF viewing in CBR, thanks. – GCamel May 31 '17 at 06:06