[英]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.