.Net MAUI Blazor如何显示本地存储图片与应用资源图片
.NET MAUI Blazor 非wwwroot目录图片加载实现
默认放在wwwroot目录下的静态资源,可以直接通过相对路径在<img>标签引用,设备本地存储图片、应用内嵌资源图片的实现方式如下:
加载设备内部存储的本地图片
BlazorWebView默认禁止直接通过file://协议访问设备本地文件,需要通过请求拦截的方式代理返回文件流,步骤如下:
- 配置平台存储权限
- Android平台:打开
Platforms/Android/AndroidManifest.xml,在<manifest>节点下添加对应权限:
运行时需要动态申请权限,可调用<!-- Android 12及以下版本 --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <!-- Android 13及以上版本 --> <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />Permissions.CheckStatusAsync<Permissions.StorageRead>()和Permissions.RequestAsync<Permissions.StorageRead>()完成权限校验。 - iOS平台:打开
Platforms/iOS/Info.plist,添加相册访问权限描述:<key>NSPhotoLibraryUsageDescription</key> <string>需要访问相册以选择和展示图片</string>
- Android平台:打开
- 注册BlazorWebView请求拦截
打开MainPage.xaml,给BlazorWebView组件绑定WebResourceRequested事件:
在<BlazorWebView x:Name="blazorWebView" HostPage="wwwroot/index.html" WebResourceRequested="BlazorWebView_WebResourceRequested"> <BlazorWebView.RootComponents> <RootComponent Selector="#app" ComponentType="{x:Type local:App}" /> </BlazorWebView.RootComponents> </BlazorWebView>MainPage.xaml.cs中实现事件处理逻辑,拦截约定前缀的请求返回本地文件流:private async void BlazorWebView_WebResourceRequested(object sender, WebResourceRequestedEventArgs e) { var requestPath = e.Request.RequestUri.LocalPath; // 拦截本地文件请求,约定前缀为 /local-file/ if (requestPath.StartsWith("/local-file/")) { var realFilePath = Uri.UnescapeDataString(requestPath.Replace("/local-file/", "")); if (!File.Exists(realFilePath)) return; var fileBytes = await File.ReadAllBytesAsync(realFilePath); var contentType = Path.GetExtension(realFilePath).ToLower() switch { ".png" => "image/png", ".jpg" or ".jpeg" => "image/jpeg", ".gif" => "image/gif", ".webp" => "image/webp", _ => "application/octet-stream" }; e.Response = new WebResourceResponse(contentType, new MemoryStream(fileBytes)); } // 内嵌资源图片的拦截逻辑放在这里 } - Razor组件中使用
直接在img的src属性中拼接约定前缀+本地文件绝对路径即可,例如加载路径为/storage/emulated/0/Pictures/demo.jpg的图片:
建议不要硬编码系统路径,优先通过<img src="/local-file/storage/emulated/0/Pictures/demo.jpg" alt="本地存储图片" style="max-width:100%" />FileSystem类提供的官方API获取目录,或使用MediaPicker选择图片后直接返回的FileResult.FullPath拼接路径,避免不同系统版本路径差异导致的加载失败。
加载应用程序内嵌的资源图片
MAUI项目默认的内嵌图片存放在Resources/Images目录,对应生成操作为MauiImage,这类资源同样可以通过上述请求拦截机制加载:
- 在刚才的
BlazorWebView_WebResourceRequested方法中,补充内嵌资源的拦截分支:
如果你使用的是程序集嵌入资源(生成操作为// 拦截MAUI内嵌资源请求,约定前缀为 /maui-res/ if (requestPath.StartsWith("/maui-res/")) { var resPath = requestPath.Replace("/maui-res/", "").Trim(); try { // 读取应用包内的资源文件 using var resStream = await FileSystem.OpenAppPackageFileAsync(resPath); var ms = new MemoryStream(); await resStream.CopyToAsync(ms); ms.Position = 0; var contentType = Path.GetExtension(resPath).ToLower() switch { ".png" => "image/png", ".jpg" or ".jpeg" => "image/jpeg", ".svg" => "image/svg+xml", _ => "application/octet-stream" }; e.Response = new WebResourceResponse(contentType, ms); } catch { // 资源不存在时忽略,返回默认404即可 } }EmbeddedResource),将读取流的逻辑替换为typeof(Program).Assembly.GetManifestResourceStream("你的项目默认命名空间.资源路径.文件名")即可。 - Razor组件中使用
例如加载Resources/Images/dotnet_bot.png资源:<img src="/maui-res/Images/dotnet_bot.png" alt="应用内嵌图片" />
注意:MAUI会对
MauiImage类型的SVG资源做自动格式转换,如果需要直接加载原始SVG文件,需要将SVG文件的生成操作修改为MauiAsset,避免被转码导致显示异常。
内容的提问来源于stack exchange,提问作者Ziaul Hasan Hamim
相关产品推荐
相关产品推荐

