在没有 javascript 的情况下向 blazor 服务器中的客户端显示图像流?
Show an image stream to client in blazor server without javascript?
现在我有以下几行代码:
private async Task SetImageUsingStreamingAsync()
{
var imageStream = await GetImageStreamAsync();
var dotnetImageStream = new DotNetStreamReference(imageStream);
await JSRuntime.InvokeVoidAsync("setImageUsingStreaming",
"image1", dotnetImageStream);
}
上面的代码片段获取一个 Stream,并将该流重新打包为 DotNetStreamReferance,然后将该 DotNetStreamReferance 传递给 JS 函数:
async function setImageUsingStreaming(imageElementId, imageStream) {
const arrayBuffer = await imageStream.arrayBuffer();
const blob = new Blob([arrayBuffer]);
const url = URL.createObjectURL(blob);
document.getElementById(imageElementId).src = url;
}
通过 ID 填充 html 元素。这一切都很好,并且有效,但是如果我想在从数据库获取流时有一个加载屏幕,事情就会变得混乱:
if(isloading)
{
show loadingscreen
}
else
{
foreach(string in listofstrings)
{
<img id="somename"></img>
}
}
img 元素不会“显示”,如果在网站上填充图像之前 bool isloading 未更改为 false,则会导致 js 片段出错。哪一种违背了加载屏幕的目的。
有没有更聪明的方法来做到这一点?最好不要使用 javascript,因为我真的不懂那种语言,也无法根据我的需要修改它。
以上代码直接引用自 .net 文档中关于 blazor 的部分(不是加载部分,而是图像流部分):https://docs.microsoft.com/en-us/aspnet/core/blazor/images?view=aspnetcore-6.0
if (isloading)
{
// show loadingscreen
}
else
{
// Populate a list with image elements...
List imageElements = new List();
foreach(string in listofstrings)
{
Element image = new Element("img");
image.Id = "somename";
imageElements.Add(image);
}
// ...and append the list to the DOM using RenderElementsAsync
// to ensure that it is rendered only when the list is fully
// populated.
await JSRuntime.InvokeAsync("setImageUsingStreaming", imageElements, dotnetImageStream);
}
想法是填充一个 in-memory 元素列表,然后通过使用 RenderElementsAsync 异步呈现该列表一次性将其附加到 DOM。
注意:在您的原始代码中,您应该异步调用 JavaScript 函数 setImageUsingStreaming()
。也就是说,您应该使用 InvokeAsync 而不是 InvokeVoidAsync。
让我知道这是否有帮助...
我是根据 Yogi 在我 post 的评论部分的回答想出来的:
这里绝对没有必要使用 JS,我不知道为什么 blazor 文档更喜欢那样。
一个关于我如何做的简单示例:
private async Task PopulateImageFromStream(Stream stream)
{
MemoryStream ms = new MemoryStream();
stream.CopyTo(ms);
byte[] byteArray = ms.ToArray();
var b64String = Convert.ToBase64String(byteArray);
string imageURL = "data:image/png;base64," + b64String;
}
}
将 imageURL 添加到一个数组,或者简单地声明它全局以在 HTML:
中获取它
<img src="@imageURL">
现在我有以下几行代码:
private async Task SetImageUsingStreamingAsync()
{
var imageStream = await GetImageStreamAsync();
var dotnetImageStream = new DotNetStreamReference(imageStream);
await JSRuntime.InvokeVoidAsync("setImageUsingStreaming",
"image1", dotnetImageStream);
}
上面的代码片段获取一个 Stream,并将该流重新打包为 DotNetStreamReferance,然后将该 DotNetStreamReferance 传递给 JS 函数:
async function setImageUsingStreaming(imageElementId, imageStream) {
const arrayBuffer = await imageStream.arrayBuffer();
const blob = new Blob([arrayBuffer]);
const url = URL.createObjectURL(blob);
document.getElementById(imageElementId).src = url;
}
通过 ID 填充 html 元素。这一切都很好,并且有效,但是如果我想在从数据库获取流时有一个加载屏幕,事情就会变得混乱:
if(isloading)
{
show loadingscreen
}
else
{
foreach(string in listofstrings)
{
<img id="somename"></img>
}
}
img 元素不会“显示”,如果在网站上填充图像之前 bool isloading 未更改为 false,则会导致 js 片段出错。哪一种违背了加载屏幕的目的。
有没有更聪明的方法来做到这一点?最好不要使用 javascript,因为我真的不懂那种语言,也无法根据我的需要修改它。
以上代码直接引用自 .net 文档中关于 blazor 的部分(不是加载部分,而是图像流部分):https://docs.microsoft.com/en-us/aspnet/core/blazor/images?view=aspnetcore-6.0
if (isloading)
{
// show loadingscreen
}
else
{
// Populate a list with image elements...
List imageElements = new List();
foreach(string in listofstrings)
{
Element image = new Element("img");
image.Id = "somename";
imageElements.Add(image);
}
// ...and append the list to the DOM using RenderElementsAsync
// to ensure that it is rendered only when the list is fully
// populated.
await JSRuntime.InvokeAsync("setImageUsingStreaming", imageElements, dotnetImageStream);
}
想法是填充一个 in-memory 元素列表,然后通过使用 RenderElementsAsync 异步呈现该列表一次性将其附加到 DOM。
注意:在您的原始代码中,您应该异步调用 JavaScript 函数 setImageUsingStreaming()
。也就是说,您应该使用 InvokeAsync 而不是 InvokeVoidAsync。
让我知道这是否有帮助...
我是根据 Yogi 在我 post 的评论部分的回答想出来的:
这里绝对没有必要使用 JS,我不知道为什么 blazor 文档更喜欢那样。
一个关于我如何做的简单示例:
private async Task PopulateImageFromStream(Stream stream)
{
MemoryStream ms = new MemoryStream();
stream.CopyTo(ms);
byte[] byteArray = ms.ToArray();
var b64String = Convert.ToBase64String(byteArray);
string imageURL = "data:image/png;base64," + b64String;
}
}
将 imageURL 添加到一个数组,或者简单地声明它全局以在 HTML:
中获取它<img src="@imageURL">