You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将URL可访问PDF的第一页转换为BitmapImage用于WPF MVVM缩略图

在WPF MVVM应用中展示PDF第一页缩略图的两种方案

方案一:修复Pdfium.Net SDK加载URL的问题

Pdfium.Net的PdfDocument.Load方法不直接支持远程URL,需要先将PDF内容下载到内存流,再加载。以下是适配MVVM异步场景的修改实现:

代码实现

using System.IO;
using System.Net.Http;
using System.Windows.Media.Imaging;
using Patagames.Pdf;
using Patagames.Pdf.Enums;

// 建议放在ViewModel的异步方法中(避免阻塞UI线程)
public async Task<BitmapImage> GetPdfFirstPageThumbnailAsync(string pdfUrl)
{
    var bitmapImage = new BitmapImage();
    using var httpClient = new HttpClient();
    
    try
    {
        // 下载PDF到内存流
        var pdfStream = await httpClient.GetStreamAsync(pdfUrl);
        
        using var pdfDocument = PdfDocument.Load(pdfStream);
        if (pdfDocument.Pages.Count == 0) return null;

        var firstPage = pdfDocument.Pages[0];
        // 自定义缩略图尺寸,无需与原页面一致
        const int thumbnailWidth = 200;
        var thumbnailHeight = (int)(firstPage.Height * thumbnailWidth / firstPage.Width);

        using var pdfBitmap = new PdfBitmap(thumbnailWidth, thumbnailHeight, true);
        firstPage.Render(
            pdfBitmap,
            0, 0,
            thumbnailWidth, thumbnailHeight,
            PageRotate.Normal,
            RenderFlags.FPDF_THUMBNAIL
        );

        using var imageStream = new MemoryStream();
        pdfBitmap.GetImage().Save(imageStream, System.Drawing.Imaging.ImageFormat.Png);
        imageStream.Seek(0, SeekOrigin.Begin);

        bitmapImage.BeginInit();
        bitmapImage.CacheOption = BitmapCacheOption.OnLoad; // 避免流关闭后图像失效
        bitmapImage.StreamSource = imageStream;
        bitmapImage.EndInit();
        bitmapImage.Freeze(); // 跨线程绑定需Freeze

        return bitmapImage;
    }
    catch (Exception ex)
    {
        // 处理网络错误、PDF损坏等异常
        return null;
    }
}

MVVM绑定注意点

  • 在ViewModel中定义BitmapImage PdfThumbnail属性,调用上述方法后赋值
  • View中用Image控件绑定:<Image Source="{Binding PdfThumbnail}" />

方案二:使用WebView2实现缩略图

如果已用WebView2展示完整PDF,可复用该控件仅显示第一页作为缩略图,无需额外PDF处理库:

步骤1:添加WebView2控件到View

<wv2:WebView2 x:Name="PdfThumbnailWebView" 
              Source="{Binding PdfUrl}"
              Width="200" Height="280" />

(需先安装Microsoft.Web.WebView2 NuGet包)

步骤2:注入CSS隐藏多余页面

在WebView2初始化完成后,注入CSS仅显示第一页并调整为缩略图大小:

// 可通过WPF行为绑定到ViewModel,避免直接写在后台代码
private async void PdfThumbnailWebView_CoreWebView2InitializationCompleted(object sender, CoreWebView2InitializationCompletedEventArgs e)
{
    if (e.IsSuccess)
    {
        var css = @"
            body > div:first-child > div:not(:first-child) { display: none !important; }
            body > div:first-child > div:first-child { width: 100% !important; height: 100% !important; }
            html, body { margin: 0; padding: 0; overflow: hidden; }
        ";
        await PdfThumbnailWebView.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(
            $"var style = document.createElement('style'); style.textContent = '{css.Replace("\n", "").Replace("'", "\\'")}'; document.head.appendChild(style);"
        );
    }
}

MVVM适配

  • 使用Microsoft.Xaml.Behaviors.Wpf库创建行为,将WebView2初始化事件绑定到ViewModel命令
  • ViewModel中定义string PdfUrl属性,绑定到WebView2的Source

内容的提问来源于stack exchange,提问作者Jonas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 22:22:48