在没有JavaScript的Blazor Server中向客户端显示图像流?

发布于 2025-01-26 03:34:10 字数 1353 浏览 1 评论 0原文

目前,我有以下代码行:

private async Task SetImageUsingStreamingAsync()
{
    var imageStream = await GetImageStreamAsync();
    var dotnetImageStream = new DotNetStreamReference(imageStream);
    await JSRuntime.InvokeVoidAsync("setImageUsingStreaming", 
        "image1", dotnetImageStream);
}

上面的摘要获取流,然后将流到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元素。这一切都很好,可以正常工作,但是如果我想在DB中获得流的过程时要有一个加载屏幕:

if(isloading)
{
  show loadingscreen
}
else
{
   foreach(string in listofstrings)
   {
     <img id="somename"></img>
   }
}

IMG元素不会“出现”,并且如果BOOL的加载,则会在JS片段中造成错误在填充网站上的图像之前,不会更改为false。哪种用加载屏幕击败了目的。

这样做的方法更聪明吗?最好不使用JavaScript,因为我真的不知道该语言,也无法根据我的需求进行修改。

上面的代码是来自Blazor上的.NET文档的直接引用(不是加载部分,而是图像零件的流): https://learn.microsoft.com/en-us/aspnet/aspnet/core/blazor/blazor/images?view= aspnetcore-6.0

Right now i have the following lines of code:

private async Task SetImageUsingStreamingAsync()
{
    var imageStream = await GetImageStreamAsync();
    var dotnetImageStream = new DotNetStreamReference(imageStream);
    await JSRuntime.InvokeVoidAsync("setImageUsingStreaming", 
        "image1", dotnetImageStream);
}

Above snippet gets a Stream, and repackages that stream into DotNetStreamReferance, and then passes that DotNetStreamReferance to a JS function:

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;
} 

which populates an html element by ID. This is all fine, and works, but if i want to have a loadingscreen while i get the streams from the DB things get messy:

if(isloading)
{
  show loadingscreen
}
else
{
   foreach(string in listofstrings)
   {
     <img id="somename"></img>
   }
}

the img element does not "show up", and causes an error in the js snippet if the bool isloading is not changed to false BEFORE populating the images on the site. Which kind of defeats the purpose with a loadingscreen.

Is there a smarter way of doing this? Preferably without using javascript, since i dont really know that language and cannot modify it to my needs.

The above code is a direct reference from .net documentation on blazor(not the loading part, but the stream to image part): https://learn.microsoft.com/en-us/aspnet/core/blazor/images?view=aspnetcore-6.0

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

违心° 2025-02-02 03:34:10
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);
}

这个想法是通过使用RenderElelementsAsync将其异步渲染,然后将列表填充元素中的内存列表,然后将列表一一添加到DOM。
注意:在原始代码中,您应该调用JavaScript函数setImageUsingStreaming()异步。也就是说,您应该使用InvoKeasync而不是InvokeVoidAsync。
让我知道这是否有帮助...

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);
}

The idea is to populate an in-memory list of elements, and then append the list to the DOM in one go, by rendering it asynchronously using RenderElementsAsync.
Note: In your original code, you should invoke the JavaScript function setImageUsingStreaming() asynchronously. That is, you should use InvokeAsync instead of InvokeVoidAsync.
Let me know if this helps...

情话已封尘 2025-02-02 03:34:10

我根据瑜伽士的回答在我的帖子评论部分中的答案中弄清楚了:

在这里绝对没有必要使用JS,我不知道为什么大餐文档喜欢这种方式。

一个简单的示例:

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添加到数组中,或者只是将其声明为Globaly即可在HTML中获取它:

<img src="@imageURL">

I figured it based on Yogi's answer in the comment section of my post:

there is absolutely no need to use JS here, i dont know why the blazor docs prefer it that way.

a simple sample on how i did:

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;
        }
    }

add the imageURL to an array, or simply declare it globaly to get it in HTML:

<img src="@imageURL">
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文