如何在Maui Blazor特定平台跳过System.Drawing.Common依赖?
解决方案
要解决MAUI Blazor中System.Drawing.Common跨平台依赖冲突的问题,核心思路是让非Windows平台完全不加载相关依赖包,同时通过平台专属实现拆分功能逻辑:
1. 条件引用依赖包
直接在项目文件(.csproj)中配置,仅让Windows平台引入Ghostscript和System.Drawing.Common,从根源避免iOS/Android打包时包含不兼容依赖:
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0-windows10.0.19041.0'"> <PackageReference Include="System.Drawing.Common" Version="8.0.0" /> <PackageReference Include="Ghostscript.NET" Version="1.2.2" /> </ItemGroup>
2. 封装平台专属的PDF缩略图提取服务
先定义统一接口,隔离平台差异:
public interface IPdfThumbnailExtractor { Task<byte[]?> ExtractThumbnailAsync(Stream pdfStream, int pageNumber = 0); }
Windows平台实现(基于Ghostscript)
用条件编译限定仅Windows编译这段代码:
#if WINDOWS using Ghostscript.NET.Rasterizer; using System.Drawing.Imaging; namespace YourApp.Services { public class WindowsPdfThumbnailExtractor : IPdfThumbnailExtractor { public async Task<byte[]?> ExtractThumbnailAsync(Stream pdfStream, int pageNumber = 0) { using var rasterizer = new GhostscriptRasterizer(); rasterizer.Open(pdfStream); // Ghostscript页码从1开始,生成100x100的缩略图 using var image = rasterizer.GetPage(100, 100, pageNumber + 1); using var ms = new MemoryStream(); image.Save(ms, ImageFormat.Png); return ms.ToArray(); } } } #endif
iOS/Android平台实现(基于跨平台替代库)
用SkiaSharp实现跨平台PDF缩略图提取(需先引用对应平台的SkiaSharp原生包):
#if ANDROID || IOS using SkiaSharp; namespace YourApp.Services { public class MobilePdfThumbnailExtractor : IPdfThumbnailExtractor { public async Task<byte[]?> ExtractThumbnailAsync(Stream pdfStream, int pageNumber = 0) { try { using var pdf = SKDocument.Open(pdfStream); using var page = pdf.GetPage(pageNumber); // 按宽度缩放到100px,保持比例 var scale = 100f / page.Size.Width; using var bitmap = SKBitmap.FromImage(page.ToImage((int)(page.Size.Width * scale), (int)(page.Size.Height * scale))); using var ms = new MemoryStream(); bitmap.Encode(ms, SKEncodedImageFormat.Png, 100); return ms.ToArray(); } catch { return null; } } } } #endif
对应的SkiaSharp包条件引用:
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0-android'"> <PackageReference Include="SkiaSharp.NativeAssets.Android" Version="2.88.6" /> </ItemGroup> <ItemGroup Condition="'$(TargetFramework)' == 'net8.0-ios'"> <PackageReference Include="SkiaSharp.NativeAssets.iOS" Version="2.88.6" /> </ItemGroup> <ItemGroup> <PackageReference Include="SkiaSharp" Version="2.88.6" /> </ItemGroup>
3. 注册平台专属服务
在MauiProgram.cs中根据当前平台注入对应实现:
builder.Services.AddTransient<IPdfThumbnailExtractor>(sp => { if (DeviceInfo.Platform == DevicePlatform.WinUI) { #if WINDOWS return new WindowsPdfThumbnailExtractor(); #endif } #if ANDROID || IOS return new MobilePdfThumbnailExtractor(); #endif throw new NotSupportedException("当前平台不支持PDF缩略图提取"); });
4. Blazor组件中调用服务
注入服务后直接调用,无需额外判断平台(服务内部已处理):
@inject IPdfThumbnailExtractor ThumbnailExtractor @inject IJSRuntime JSRuntime <input type="file" accept=".pdf" @onchange="HandleFileUpload" /> @if (thumbnailData != null) { <img src="data:image/png;base64,@Convert.ToBase64String(thumbnailData)" alt="PDF缩略图" /> } @code { private byte[]? thumbnailData; private async Task HandleFileUpload(InputFileChangeEventArgs e) { using var stream = e.File.OpenReadStream(); thumbnailData = await ThumbnailExtractor.ExtractThumbnailAsync(stream); if (thumbnailData == null) { await JSRuntime.InvokeVoidAsync("alert", "无法提取PDF缩略图"); } StateHasChanged(); } }
内容的提问来源于stack exchange,提问作者Matias Masso
相关产品推荐
相关产品推荐

