如何将图像的 MemoryStream 写入页面主体?
How do I write an image's MemoryStream to the page body?
我正在将 ASP.NET WebForms 代码转换为 ASP.NET Core Razor 页面,这对我来说是新的。我正在尝试从企业 class(基于 SixLabors awesome ImageSharp)检索图像 MemoryStream,并让页面呈现 JPEG——不 HTML,只是图像。我打算在其他地方使用此页面作为 <img>
src,例如 <img src="Render?imageID=42&mode=invert" />
在Render.cshtml.cs中:
public class RenderModel : PageModel
{
public void OnGet()
{
//snip
Stream stream = new MemoryStream();
using (Image image1 = Image.Load(imagePath))
{
SixLabors.ImageSharp.Formats.Jpeg.JpegEncoder encoder = new SixLabors.ImageSharp.Formats.Jpeg.JpegEncoder();
encoder.Quality = 75;
image1.Save(stream, encoder);
//image.Save("/temp/xxx.jpg", encoder); //test to see image. it works
}
Response.Clear();
//Response.Headers.ContentLength = stream.Length;
Response.ContentType = "image/jpeg";
Response.Body = stream;
}
}
...但这不起作用,我得到:
System.InvalidOperationException: Response Content-Length mismatch: too few bytes written (0 of 135408).
135408 是 stream.Length.
我可能没有按照 ASP.NET Core/Razor 的方式正确执行此操作。谁能告诉我如何做到这一点?谢谢!
编辑:注释掉 Headers.ContentLength 修复了错误。但是现在我在浏览器中看到一个损坏的图像图标。更近...
我认为 Razor 页面旨在 return html 内容。
但是似乎可以在 OnGet 中 return 不同类型的结果,例如你可以 return 一个新的 FileContentReset(FileStreamResult 似乎有内容长度问题)
// read as bytes
public FileContentResult OnGet()
{
var image = System.IO.File.ReadAllBytes(@"c:\temp\myimage.jpeg");
return new FileContentResult(image.ToArray(), "image/jpeg");
}
// example if image comes from stream
public FileContentResult OnGet()
{
using var imageStr = System.IO.File.Open(@"c:\temp\myimage.jpeg", FileMode.Open);
using var memStr = new MemoryStream();
imageStr.CopyTo(memStr);
return new FileContentResult(memStr.ToArray(), "image/jpeg");
}
最好不要使用 Razor 页面并将 MVC 控制器添加到 return 结果中。
您需要写入 Response.Body
而不是替换它。
stream.Seek(0, SeekOrigin.Begin);
await stream.CopyToAsync(Response.Body);
await Response.Body.FlushAsync();
我正在将 ASP.NET WebForms 代码转换为 ASP.NET Core Razor 页面,这对我来说是新的。我正在尝试从企业 class(基于 SixLabors awesome ImageSharp)检索图像 MemoryStream,并让页面呈现 JPEG——不 HTML,只是图像。我打算在其他地方使用此页面作为 <img>
src,例如 <img src="Render?imageID=42&mode=invert" />
在Render.cshtml.cs中:
public class RenderModel : PageModel
{
public void OnGet()
{
//snip
Stream stream = new MemoryStream();
using (Image image1 = Image.Load(imagePath))
{
SixLabors.ImageSharp.Formats.Jpeg.JpegEncoder encoder = new SixLabors.ImageSharp.Formats.Jpeg.JpegEncoder();
encoder.Quality = 75;
image1.Save(stream, encoder);
//image.Save("/temp/xxx.jpg", encoder); //test to see image. it works
}
Response.Clear();
//Response.Headers.ContentLength = stream.Length;
Response.ContentType = "image/jpeg";
Response.Body = stream;
}
}
...但这不起作用,我得到:
System.InvalidOperationException: Response Content-Length mismatch: too few bytes written (0 of 135408).
135408 是 stream.Length.
我可能没有按照 ASP.NET Core/Razor 的方式正确执行此操作。谁能告诉我如何做到这一点?谢谢!
编辑:注释掉 Headers.ContentLength 修复了错误。但是现在我在浏览器中看到一个损坏的图像图标。更近...
我认为 Razor 页面旨在 return html 内容。
但是似乎可以在 OnGet 中 return 不同类型的结果,例如你可以 return 一个新的 FileContentReset(FileStreamResult 似乎有内容长度问题)
// read as bytes
public FileContentResult OnGet()
{
var image = System.IO.File.ReadAllBytes(@"c:\temp\myimage.jpeg");
return new FileContentResult(image.ToArray(), "image/jpeg");
}
// example if image comes from stream
public FileContentResult OnGet()
{
using var imageStr = System.IO.File.Open(@"c:\temp\myimage.jpeg", FileMode.Open);
using var memStr = new MemoryStream();
imageStr.CopyTo(memStr);
return new FileContentResult(memStr.ToArray(), "image/jpeg");
}
最好不要使用 Razor 页面并将 MVC 控制器添加到 return 结果中。
您需要写入 Response.Body
而不是替换它。
stream.Seek(0, SeekOrigin.Begin);
await stream.CopyToAsync(Response.Body);
await Response.Body.FlushAsync();