private static void CropImage(CustomRatio ratio, IMagickImage image) { var cropWidth = Math.Abs(ratio.X2 - ratio.X1); var cropHeight = Math.Abs(ratio.Y2 - ratio.Y1); if (image.BaseWidth == cropWidth && image.BaseHeight == cropHeight) //requested image is same size { return; } var cropSize = new MagickGeometry(cropWidth, cropHeight) { IgnoreAspectRatio = false, //keep aspect ratio! FillArea = false, X = ratio.X1, Y = ratio.Y1 }; image.Crop(cropSize); }
public byte[] GetImageAsBytes(int requestWidth, int requestHeight, int quality, byte[] bytes, string options, out string mimeType, CustomRatio ratio = null) { if (!IsGif(bytes)) { return(ProcessImage(requestWidth, requestHeight, quality, bytes, options, ratio, out mimeType)); } mimeType = "image/gif"; return(ProcessGif(requestWidth, requestHeight, quality, bytes, options)); }
private static byte[] ProcessImage(int requestWidth, int requestHeight, int quality, byte[] bytes, string options, CustomRatio ratio, out string mimeType) { if (ratio != null) { using (MagickImage image = new MagickImage(bytes)) { CropImage(ratio, image); bytes = image.ToByteArray(); } } using (MagickImage image = new MagickImage(bytes)) { ResizeImage(requestWidth, requestHeight, quality, options, image); // return the result if (image.HasAlpha) { mimeType = "image/png"; bytes = image.ToByteArray(MagickFormat.Png); } else { mimeType = "image/jpeg"; bytes = image.ToByteArray(MagickFormat.Pjpeg); } } return(bytes); }
private async Task <IActionResult> ImageResult(string id, string slug, int w = 0, int h = 0, int quality = 100, string options = "", string hash = "") { if (string.IsNullOrWhiteSpace(id)) { _logger.LogError("Id is null"); return(new StatusCodeResult((int)HttpStatusCode.BadRequest)); } if (0 > w || 0 > h) { _logger.LogError("Width or height is negative"); return(new StatusCodeResult((int)HttpStatusCode.BadRequest)); } byte[] bytes; CustomRatio customRatio = null; try { var host = _fileService.GetHostConfig(slug); if (host.WhiteList != null && host.WhiteList.Any() && host.WhiteList.All(x => x != $"{w}x{h}")) //whitelist checking { _logger.LogError("Image request cancelled due to whitelist."); return(new StatusCodeResult((int)HttpStatusCode.BadRequest)); } if (w != 0 && h != 0 && !string.IsNullOrEmpty(hash) && host.Type == HostType.GridFs) //customratio & mongodb file { var metadata = await _metadataService.GetFileMetadataAsync(host, id); var ratio = (double)w / h; //image request ratio customRatio = double.IsNaN(ratio) ? metadata.CustomRatio.FirstOrDefault(x => x.Hash == hash) : metadata.CustomRatio.FirstOrDefault(x => x.MinRatio < ratio && x.MaxRatio >= ratio); if (customRatio == null) // request with hash but no customratio { _logger.LogError( "Image request redirected due to wrong custom ratio hash (redirected to base url)"); return(Redirect(string.IsNullOrEmpty(options) ? $"/i/{slug}/{quality}/{w}x{h}/{id}" : $"/i/{slug}/{quality}/{w}x{h}/{options}/{id}")); } if (!double.IsNaN(ratio) && customRatio.Hash != hash) //hash is not correct { _logger.LogError( "Image request redirected due to wrong custom ratio hash (redirected to new customRatio)"); return(Redirect(string.IsNullOrEmpty(options) ? $"/i/{slug}/{quality}/{w}x{h}/h-{customRatio.Hash}/{id}" : $"/i/{slug}/{quality}/{w}x{h}/{options}/h-{customRatio.Hash}/{id}")); } } bytes = await _fileService.GetFileAsync(slug, id); if (bytes == null) { _logger.LogError("File not found"); return(NotFound()); } } catch (RedirectToFallbackException e) { _logger.LogWarning(e, e.Message); return(Redirect(string.IsNullOrEmpty(options) ? $"/i/{slug}/{quality}/{w}x{h}/{e.FallbackImage}" : $"/i/{slug}/{quality}/{w}x{h}/{options}/{e.FallbackImage}")); } catch (SlugNotFoundException e) { _logger.LogError(e, e.Message); return(new StatusCodeResult((int)HttpStatusCode.BadRequest)); } catch (GridFsObjectIdException e) { _logger.LogError(e, "GridFS ObjectId Parse Error:" + e.Message); return(new StatusCodeResult((int)HttpStatusCode.BadRequest)); } catch (TimeoutException e) { _logger.LogError(e, "Timeout: " + e.Message); return(new StatusCodeResult((int)HttpStatusCode.GatewayTimeout)); } catch (Exception e) { _logger.LogError(e, e.Message); throw; } try { bytes = _imageService.GetImageAsBytes(w, h, quality, bytes, options, out var mime, customRatio); if (bytes != null) { return(File(bytes, mime)); } _logger.LogError("File found but image operation failed by unknown cause"); return(StatusCode((int)HttpStatusCode.NotAcceptable)); } catch (Exception e) { _logger.LogError(e, "Image Service Error: " + e.Message); throw; } }