簡體   English   中英

使用 MagickImage 和 C# 調整圖像大小並添加黑色背景

[英]Resizing an image and adding black background using MagickImage and C#

我必須使用Magick Image涵蓋四種可能的場景:

  1. 如果上傳的圖像的寬度或高度小於 150,則將圖像居中並將背景中的所有內容繪制為黑色

  2. 寬度 > 150 和縱橫比不同的 1:1 從兩側裁剪圖像以覆蓋 150px

  3. 高度 > 150 且縱橫比不同於 1:1 裁剪圖像從兩側覆蓋 150 像素

  4. 在所有其他情況下調整為 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;
    }

輸出圖像 48x10px

這是原始圖像:

在此處輸入圖片說明

非常簡單的解決方案。

我還添加了一個檢查以保留圖像的外觀,因此它不會被擠壓:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM