【问题标题】:Render pdf using wpf使用 wpf 渲染 pdf
【发布时间】:2017-05-30 09:32:35
【问题描述】:

我需要编写自己的 pdf 查看器 (UserControl)。我为此使用 pdfium.dll。它的包装是 PdfiumService。此服务可以将页面呈现到 BitmapSource。 PdfViewer 在 ScrollViewer 中的 VirtualizingStackPanel 中显示页面。 任何想法如何为 pdf 进行延迟渲染?问题是如果 pdf 大约 20mb(1000 页),渲染页面需要大约 2gb 内存。

VirtualizingStackPanel 可以帮助我吗?我没有找到“BeginVirtualizing”或其他任何事件。有什么简单的方法可以知道现在正在显示什么项目?

也许是这样的:

  1. 计算一次可以显示多少页。
  2. 查看 ScrollViewer 的偏移量。
  3. 计算现在显示的页面索引。
  4. 在当前页面旁边呈现 5 个页面。

是否有任何现成的解决方案,或一些提示或想法?

【问题讨论】:

  • 您可以使用滚动查看器内部的 ItemConrol,然后使用滚动查看器垂直偏移量创建虚拟化。
  • 是的,当然。问题不在于它。我在其中使用 ScrollViewer 和 ItemsControl,并且 ItemsControl.ItemsPanel 是 VirtualizingStackPanel。我知道如何将数据绑定到容器。有没有办法做我想做的事?还是仅手动计算偏移量和图像大小?
  • 我认为没有任何简单的方法,因为您还必须仅加载可见的页面,以便您可以根据该页面进行计算
  • 不好。还是谢谢你。

标签: c# wpf pdf pdfviewer


【解决方案1】:

好吧,我对书籍中的图像有一点……问题不在于放置位图的 gui,而是如何从库中获取图像……是一张一张的吗?顺序还是随机?

事实上,如果你使用 VirtualizingStackPanel,它只会管理 gui 元素的创建或销毁,但如果你在内存中有完整的位图集合,你就死定了。

一种方法是在位图之外创建页面对象,并在需要时创建图像 + 添加一个计时器以清除所有“最旧的图像”

我在CBR 中做了类似的事情;我使用custom 控件来显示页面

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

【讨论】:

  • 请注意,您还可以将 Winform 查看器嵌入到您的应用中 github.com/pvginkel/PdfiumViewer
  • 我想我是按顺序渲染 pdf 页面的。关于 VirtualizingStackPanel 我了解位图存储在内存中。这是一个问题。我已经编写了代码来根据页面大小、控件大小和 ScrollViewer 的偏移量仅呈现显示的页面。好吧,关于清除所有最旧的图像。什么是更好的?根据时间或滚动偏移量进行清理?
  • 我会说也许在索引上,因为在滚动查看器上,如果我使用箭头或向下翻页键,我可以在很短的时间内快速填满内存,按时清理将不起作用。顺便说一句,你给了我一个很好的解决方案(pdfium),开始在 CBR 中查看 PDF,谢谢。
猜你喜欢
  • 2019-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-14
  • 2010-10-05
  • 2011-03-26
  • 2017-10-28
相关资源
最近更新 更多