cscg24-photoeditor

CSCG 2024 Challenge 'PhotoEditor'
git clone https://git.sinitax.com/sinitax/cscg24-photoeditor
Log | Files | Refs | sfeed.txt

DynamicPhotoEditorController.cs (3845B)


      1using System.Diagnostics;
      2using Microsoft.AspNetCore.Mvc;
      3using PhotoEditor.Models;
      4using SixLabors.ImageSharp;
      5using SixLabors.ImageSharp.Processing;
      6using SixLabors.ImageSharp.Formats;
      7using SixLabors.ImageSharp.PixelFormats;
      8using SixLabors.ImageSharp.Advanced;
      9using Newtonsoft.Json;
     10
     11namespace PhotoEditor.Controllers;
     12
     13[ApiController]
     14[Route("api/[controller]")]
     15public class DynamicPhotoEditorController : BaseAPIController
     16{
     17    private readonly ILogger<DynamicPhotoEditorController> _logger;
     18    private Image _cachedImage = null;
     19
     20    public DynamicPhotoEditorController(ILogger<DynamicPhotoEditorController> logger)
     21    {
     22        _logger = logger;
     23    }
     24
     25
     26    [HttpPost]
     27    [Route("EditImage")]
     28    public IActionResult EditImage([FromBody]PhotoTransferRequestModel photoTransferRequestModel)
     29    {
     30        try {
     31            this._cachedImage = Image.Load(Convert.FromBase64String(photoTransferRequestModel.Base64Blob));
     32            _logger.LogTrace(0, "Loaded Image: {0}", this._cachedImage);
     33
     34            var actionMethod = this.GetType().GetMethod(photoTransferRequestModel.DynamicAction);
     35            if (actionMethod == null) {
     36                throw new Exception("Unable to find dynamic action: " + photoTransferRequestModel.DynamicAction);
     37            }
     38
     39            var editParams = (object[])JsonConvert.DeserializeObject<object[]>(photoTransferRequestModel.Parameters);
     40            if (photoTransferRequestModel.Types != null) {
     41                for (int i = 0; i < photoTransferRequestModel.Types.Length; i++) {
     42                    editParams[i] = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(editParams[i]),GetTypeByName(photoTransferRequestModel.Types[i]));
     43                }
     44            }
     45            
     46            _logger.LogWarning(0, "Params: {0} Raw: {1}", editParams, photoTransferRequestModel.Parameters);
     47
     48            var transformedImage = (Image)actionMethod.Invoke(this, editParams);
     49            
     50            var imageAsBase64 = ImageToBase64(transformedImage);
     51
     52            var retValue = new PhotoTransferResponseModel();    
     53            retValue.Base64Blob = imageAsBase64;
     54            return Ok(retValue);
     55        }
     56        catch (Exception e) {
     57            Console.WriteLine(e.ToString());
     58            var retValue = new PhotoTransferResponseModel();    
     59            retValue.Error = e.Message;
     60            return StatusCode(StatusCodes.Status500InternalServerError, retValue);
     61        }
     62    }
     63
     64    private Type GetTypeByName(String name) {
     65        return AppDomain.CurrentDomain.GetAssemblies()
     66            .Reverse()
     67            .Select(assembly => assembly.GetType(name))
     68            .FirstOrDefault(t => t != null);
     69    }
     70
     71    public String ImageToBase64(Image image) {
     72
     73         using (var memoryStream = new MemoryStream())
     74        {
     75            var imageEncoder = image.Metadata.DecodedImageFormat;
     76            image.SaveAsPng(memoryStream);
     77            return Convert.ToBase64String(memoryStream.ToArray());
     78        }
     79    }
     80
     81    public Image GrayscaleImage(double amount) {
     82        this._cachedImage.Mutate(m => m.Grayscale((float)amount));
     83        return this._cachedImage;
     84    }
     85
     86    public Image BlackWhiteImage() {
     87        this._cachedImage.Mutate(m => m.BlackWhite());
     88        return this._cachedImage;
     89    }
     90
     91    public Image RotateImage(double degrees) {
     92        this._cachedImage.Mutate(m => m.Rotate((float)degrees));
     93        return this._cachedImage;
     94    }
     95
     96    public Image InvertImage() {
     97        this._cachedImage.Mutate(m => m.Invert());
     98        return this._cachedImage;
     99    }
    100
    101    public Image CropImage(RectangleStruct rect) {
    102        this._cachedImage.Mutate(m => m.Crop(new Rectangle(rect.X, rect.Y, rect.W, rect.H)));
    103        return this._cachedImage;
    104    }
    105}