[英]Resizing an image and adding black background using MagickImage and C#
我必须使用Magick Image
涵盖四种可能的场景:
如果上传的图像的宽度或高度小于 150,则将图像居中并将背景中的所有内容绘制为黑色
宽度 > 150 和纵横比不同的 1:1 从两侧裁剪图像以覆盖 150px
高度 > 150 且纵横比不同于 1:1 裁剪图像从两侧覆盖 150 像素
在所有其他情况下调整为 150x150
我很难找到文档或任何关于它的信息。 我正在使用试错法。
我首先绘制了所有案例的草图,然后我想将其实现到 C# 代码中
public async Task<IActionResult> SetImageFroUser([FromRoute] string userId, [FromForm] byte[] avatar)
{
if (string.IsNullOrEmpty(userId) || avatar == null || avatar.Length == 0) return BadRequest();
var user = await userManagerWrapper.FindByIdAsync(userId);
if (user == null) return NotFound();
// if (User == null || !User.IsInRole("Administrator")) return Forbid();
if ((User == null || !User.IsInRole("Administrator")) && !user.Id.Equals(userId)) return Forbid();
try
{
avatarManager.SetAvatar(user, new MemoryStream(avatar));
}
catch (MagickException)
{
return BadRequest("Invalid image format");
}
return NoContent();
}
public void SetAvatar(IntentUser user, Stream avatar)
{
using (var ms = new MemoryStream())
{
avatar.CopyTo(ms);
ms.Seek(0, SeekOrigin.Begin);
using MagickImage image = new MagickImage(ms);
ms.Seek(0, SeekOrigin.Begin);
ProcessImage(image.Width, image.Height, image);
image.Write(ms, MagickFormat.Jpeg);
var dbUser = database.Users.FirstOrDefault(u => u.Id == user.Id);
if (dbUser == null)
{
throw new NotFoundException();
}
dbUser.Avatar = ms.ToArray();
user.Avatar = dbUser.Avatar;
database.SaveChanges();
}
}
private void ProcessImage(int width, int height, MagickImage image)
{
double startPosition, endPosition;
if (width < 150 && height < 150)
{
startPosition = 150 - width;
endPosition = 150 - height;
//center image
image.Draw(new DrawableRectangle(startPosition / 2, endPosition / 2, startPosition / 2 + width, endPosition / 2 + height));
image.Draw(new DrawableFillColor(MagickColors.Black));
//rest of background is black
}
else if (width < 150 && height > 150)
{
startPosition = 150 - width;
endPosition = height - 150;
image.Draw(new DrawableRectangle(startPosition / 2, endPosition / 2, startPosition / 2 + width, endPosition / 2 + height));
image.Draw(new DrawableFillColor(MagickColors.Black));
}
else if (width > 150 && height > 150 && width != height)
{
startPosition = width - 150;
endPosition = height - 150;
image.Draw(new DrawableRectangle(startPosition / 2, endPosition / 2, startPosition / 2 + width, endPosition / 2 + height));
image.Draw(new DrawableFillColor(MagickColors.Black));
}
else if (width > 150 && height < 150)
{
startPosition = width - 150;
endPosition = 150 - height;
image.Draw(new DrawableRectangle(startPosition / 2, endPosition / 2, startPosition / 2 + width, endPosition / 2 + height));
image.Draw(new DrawableFillColor(MagickColors.Black));
}
else
{
image.Resize(150, 150);
}
image.Strip();
image.Quality = 75;
}
这是原始图像:
非常简单的解决方案。
我还添加了一个检查以保留图像的外观,因此它不会被挤压:
var aspect_ratio = (decimal)image.Width / (decimal)image.Height;
if (aspect_ratio > 1)
{
var newWidth = (int) Math.Round((decimal) (aspect_ratio * 150));
image.Resize(newWidth, 150);
// cut width and new width is multiply 150 by aspect ratio
}
else if (aspect_ratio < 1)
{
//cut height and new height is multiply 150 by aspect ratio
var newHeight = (int)Math.Round((decimal)((decimal)image.Height / (decimal)image.Width * 150));
image.Resize(150, newHeight);
}
private void ProcessImage(MagickImage image, MemoryStream ms)
{
using var finalImage = new MagickImage(new MagickColor("#000000"), 150, 150);
finalImage.Composite(image, Gravity.Center, CompositeOperator.Over);
finalImage.Write(ms, MagickFormat.Jpg);
image.Strip();
image.Quality = 75;
}
对于 ImageMagick 文档,请参阅他们的 github: https : //github.com/dlemstra/Magick.NET
如果您下载项目并打开文档,您可以看到一个文档 - 描述方法的注释,然后是方法中的逻辑。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.