4

Blazor Hybrid (Blazor混合开发)更好的读取本地图片 - tokengo

 1 year ago
source link: https://www.cnblogs.com/hejiale010426/p/17073079.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

在 Blazor Hybrid 应用中,Razor 组件在设备上本机运行。 组件通过本地互操作通道呈现到嵌入式 Web View 控件。 组件不在浏览器中运行,并且不涉及 WebAssembly。 Razor 组件可快速加载和执行代码,组件可通过 .NET 平台完全访问设备的本机功能。 Web View 中呈现的组件样式与平台相关,可能需要你使用自定义样式表来说明不同平台之间的呈现差异。

如何在Blazor Hybrid中读取本地图片展示?

在Blazor Hybrid经常遇到一些读取选中的图片并且渲染,但是文件的目录在Blazor中直接src填写是无法读取到的,这个时候就可能需要将文件Copy到wwwroot中,或者将其转换Base64放入到html中,但是base64转换图片是很长的一串字符串,这样可能会导致渲染可能卡扽,所以我们将使用js提供的功能去实现,其实在Blazor Hybrid为了兼容,可以采用js提供的部分功能实现,效果更好,

创建一个Winform项目

2415052-20230129163225347-1218645027.png

添加 Microsoft.AspNetCore.Components.WebView.WindowsFormsNuGet包

dotnet add package Microsoft.AspNetCore.Components.WebView.WindowsForms

修改项目文件的属性

打开BlazorHybrid.csproj项目文件,将Microsoft.NET.Sdk 修改成Microsoft.NET.Sdk.Razor

<Project Sdk="Microsoft.NET.Sdk.Razor">

创建 _Imports.razor文件,添加以下代码

@using Microsoft.AspNetCore.Components.Web
@using Microsoft.AspNetCore.Components.Routing

创建wwwroot文件夹

创建wwwroot/index.html文件,添加以下代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>WinFormsBlazor</title>
    <base href="/" />
    <link href="css/app.css" rel="stylesheet" />
    <link href="WinFormsBlazor.styles.css" rel="stylesheet" />
</head>

<body>

    <div id="app">加载中...</div>

    <div id="blazor-error-ui">
        An unhandled error has occurred.
        <a href="" class="reload">Reload</a>
        <a class="dismiss">🗙</a>
    </div>
    <!--引用blazor.webview.js Server和web assembly,hybrid的js都不一样-->
    <script src="_framework/blazor.webview.js"></script>

</body>

</html>

创建wwwroot/css/app.css添加以下代码

html, body {
    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}

h1:focus {
    outline: none;
}

a, .btn-link {
    color: #0071c1;
}

.btn-primary {
    color: #fff;
    background-color: #1b6ec2;
    border-color: #1861ac;
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid red;
}

.validation-message {
    color: red;
}

#blazor-error-ui {
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

    #blazor-error-ui .dismiss {
        cursor: pointer;
        position: absolute;
        right: 0.75rem;
        top: 0.5rem;
    }

创建Shared/App.razor添加以下代码

<Router AppAssembly="@typeof(MainLayout).Assembly">
    <Found Context="routeData">
        <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
        <FocusOnNavigate RouteData="@routeData" Selector="h1" />
    </Found>
    <NotFound>
        <PageTitle>Not found</PageTitle>
        <LayoutView Layout="@typeof(MainLayout)">
            <p role="alert">Sorry, there's nothing at this address.</p>
        </LayoutView>
    </NotFound>
</Router>

创建Shared/MainLayout.razor添加以下代码

@inherits LayoutComponentBase
<div>
	@Body
</div>

选择Form1.cs打开设计窗口,将BlazorWebView拖到Form1中,并且将BlazorWebView的属性中的Dock修改成Fill

2415052-20230129163211829-1557253236.png

将以下命名空间添加到Form1.cs文件的顶部

using Microsoft.AspNetCore.Components.WebView.WindowsForms;
using Microsoft.Extensions.DependencyInjection;

Form1 构造函数中的 InitializeComponent 方法调用后面,添加以下代码:

var services = new ServiceCollection();
services.AddWindowsFormsBlazorWebView();
blazorWebView1.HostPage = "wwwroot\\index.html";
blazorWebView1.Services = services.BuildServiceProvider();
blazorWebView1.RootComponents.Add<App>("#app");

效果如图

2415052-20230129163204482-1139565921.png

修改wwwroot/index.html代码。添加js方法,将以下代码添加到body里面

    <script>
        /** 将byte转url对象 */
        function byteToUrl(blob) {
            // 适配webview和web 
            var myBlob = new Blob([blob], { type: "image/png" });
            return (window.URL || window.webkitURL || window || {}).createObjectURL(myBlob);
               }
        /**
        * 释放url对象,因为createObjectURL创建的对象一直会存在可能会占用过多的内存,请注意释放
        */
        function revokeUrl(url) {
            (window.URL || window.webkitURL || window || {}).revokeObjectURL(url);
        }
    </script>

创建Pages/Index.razor文件,并添加以下代码

@using Microsoft.JSInterop;
@inject IJSRuntime JSRuntime

@page "/"

@if (!string.IsNullOrEmpty(Img)){
    <img src="@Img" />
}

<input @bind="ImgPath" />

<button @onclick="OnLoad">加载图片</button>

<button @onclick="Revoke">释放图片</button>
@code {
    public string? ImgPath { get; set; }

    private string? Img;

    private async Task OnLoad()
    {
        // 加载目录中的图片获取到byte 通过byteToUrl转换URL对象 可以直接通过url获取到图片 它存在与本地
        var file = await File.ReadAllBytesAsync(ImgPath);
        Img = await JSRuntime.InvokeAsync<string>("byteToUrl", file);
    }

    private async Task Revoke()
    {
        if (!string.IsNullOrEmpty(Img)){
            await JSRuntime.InvokeVoidAsync("revokeUrl", Img);
            Img = string.Empty;
        }
    }
}

<style>
    button {
        background-color: cornflowerblue;
        height: 30px;
        font-size: 15px;
        width: auto;
    }
    img{
        height:auto;
        width:auto;
    }

</style>

最终效果:

2415052-20230129163146109-218215876.gif

我们可以通过createObjectURL加载本地文件或者图片,并且渲染,这样对比copy到wwwroot或者转换base64的效果更好,而且更容易管理,实现也超级容易,用于跨平台实现也算是最佳实现了,

Blazor技术交流:452761192

来自token的分享

本文作者:tokengo

本文链接:https://www.cnblogs.com/hejiale010426/p/17073079.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK