Изменение размера изображения и добавление черного фона с помощью MagickImage и C# - PullRequest
0 голосов
/ 27 января 2020

Мне нужно покрыть четыре возможных сценария ios с помощью Magick Image:

  1. ЕСЛИ ширина или высота загружаемого изображения меньше 150 центрирует изображение и рисует все на заднем плане в черном цвете

  2. Ширина> 150 и форматное соотношение, отличное от 1: 1 кадрированного изображения с обеих сторон для покрытия 150px

  3. Высота > 150 и форматное соотношение отличается от 1: 1 кадрированного изображения с обеих сторон для покрытия 150 px

  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;
    }

Output of an image 48x10px

А вот оригинальное изображение:

enter image description here

1 Ответ

0 голосов
/ 28 января 2020

Очень простое решение.

Также я добавил проверку, чтобы сохранить аспект изображения, чтобы оно не сжималось:

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 do c обратитесь к их github: https://github.com/dlemstra/Magick.NET

Если вы загрузите проект и откроете документы, вы увидите документацию - комментарии, которые описывают методы, а затем логику c в методах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...