.NET Core Blazor上传图片前压缩/缩放方案求助
Blazor图片上传前压缩/缩放替代方案(Magick.Net失败时可用)
需求说明
我需要实现图片上传并存储到数据库的功能,要求在上传至服务器前对图片进行压缩或缩放。之前尝试使用Magick.Net但未成功,恳请提供其他可行方法。以下是我的代码:
Index.razor 页面代码
<FormItem> <Template> <label for="Remarks" class="k-label k-form-label">@MOM.Alias.Common.DTO.Icon</label> <CardImage Src="@ImageSrc" Height="100px" Width="100px" /> <TelerikButton Id="btnTicketCategoryRemove" ButtonType="@Telerik.Blazor.ButtonType.Button" Visible="@(ImageSrc!= MOM.UI.Client.Constants.Common.NoImageIcon)" Icon="FontIcon.Trash" Title=@MOM.UI.Client.Constants.Label.Remove ThemeColor="@ThemeConstants.Button.ThemeColor.Error" OnClick="@RemoveIcon" Size="@size" Rounded="@size"></TelerikButton> <TelerikFileSelect AllowedExtensions="@Common.AllowAllowedFileTypes" OnSelect="@OnSelect" OnRemove="@OnRemove" Multiple=false MinFileSize="Common.MinFileSize" MaxFileSize="Common.MaxFileSize" @ref="@telerikFileSelectRef"> </TelerikFileSelect> <div class="k-form-hint"> @Constants.Label.ExpectedFiles <strong>@Constants.Label.AllowedFileTypes</strong><br /> @Constants.Label.Between <strong> @Constants.Label.MinSizeText</strong> @Constants.Label.And <strong>@Constants.Label.MaxSizeText</strong> </div> </Template> </FormItem>
@code 代码片段
public async Task OnSelect(FileSelectEventArgs args) { try { FileSelectFileInfo file = args.Files[0]; if (!file.InvalidExtension && !file.InvalidMaxFileSize && !file.InvalidMinFileSize) { var byteArray = new byte[file.Stream.Length]; var stream = new MemoryStream(byteArray); await file.Stream.CopyToAsync(stream); dto.Icon = stream.ToArray(); ImageSrc = CommonHelper.GetImageFromByteArray(dto.Icon); } dialogRef?.Refresh(); } catch (Exception ex) { throw ex; } }
可行替代方案
方案一:使用System.Drawing.Common(Windows平台优先)
- 安装NuGet包:
Install-Package System.Drawing.Common - 修改
OnSelect方法,在转换字节数组前加入压缩逻辑:
public async Task OnSelect(FileSelectEventArgs args) { try { FileSelectFileInfo file = args.Files[0]; if (!file.InvalidExtension && !file.InvalidMaxFileSize && !file.InvalidMinFileSize) { using var originalStream = new MemoryStream(); await file.Stream.CopyToAsync(originalStream); originalStream.Position = 0; // 加载原始图片 using var image = System.Drawing.Image.FromStream(originalStream); // 计算目标尺寸(保持比例,最大宽高800px) int targetWidth = 800; int targetHeight = (int)((float)targetWidth / image.Width * image.Height); if (targetHeight > 800) { targetHeight = 800; targetWidth = (int)((float)targetHeight / image.Height * image.Width); } // 创建压缩后的位图 using var bitmap = new System.Drawing.Bitmap(targetWidth, targetHeight); using var graphics = System.Drawing.Graphics.FromImage(bitmap); graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; graphics.DrawImage(image, 0, 0, targetWidth, targetHeight); // 保存为JPEG格式,质量设为70(0-100,数值越小压缩率越高) using var compressedStream = new MemoryStream(); bitmap.Save(compressedStream, System.Drawing.Imaging.ImageFormat.Jpeg); dto.Icon = compressedStream.ToArray(); ImageSrc = CommonHelper.GetImageFromByteArray(dto.Icon); } dialogRef?.Refresh(); } catch (Exception ex) { throw ex; } }
注意:该方案在.NET 6及以上版本仅支持Windows平台,跨平台场景请用方案二。
方案二:使用ImageSharp(跨平台通用)
- 安装NuGet包:
Install-Package SixLabors.ImageSharp - 修改
OnSelect方法实现跨平台压缩:
using SixLabors.ImageSharp; using SixLabors.ImageSharp.Processing; using SixLabors.ImageSharp.Formats.Jpeg; public async Task OnSelect(FileSelectEventArgs args) { try { FileSelectFileInfo file = args.Files[0]; if (!file.InvalidExtension && !file.InvalidMaxFileSize && !file.InvalidMinFileSize) { using var originalStream = new MemoryStream(); await file.Stream.CopyToAsync(originalStream); originalStream.Position = 0; // 加载图片并调整尺寸(最大宽高800px,保持比例) using var image = Image.Load(originalStream); image.Mutate(x => x.Resize(new ResizeOptions { Size = new Size(800, 800), Mode = ResizeMode.Max })); // 保存为JPEG,设置质量为70 using var compressedStream = new MemoryStream(); var jpegEncoder = new JpegEncoder { Quality = 70 }; image.Save(compressedStream, jpegEncoder); dto.Icon = compressedStream.ToArray(); ImageSrc = CommonHelper.GetImageFromByteArray(dto.Icon); } dialogRef?.Refresh(); } catch (Exception ex) { throw ex; } }
优势:完全支持Windows、Linux、macOS,API设计更简洁现代,无平台限制。
内容的提问来源于stack exchange,提问作者Prashil Shah
相关产品推荐
相关产品推荐

