private SKData GetImageData(string imagePath, ResizeParams resizeParams, DateTime lastWriteTimeUtc) { // check cache and return if cached long cacheKey; unchecked { cacheKey = imagePath.GetHashCode() + lastWriteTimeUtc.ToBinary() + resizeParams.ToString().GetHashCode(); } SKData imageData; byte[] imageBytes; bool isCached = _memoryCache.TryGetValue <byte[]>(cacheKey, out imageBytes); if (isCached) { _logger.LogInformation("Serving from cache"); return(SKData.CreateCopy(imageBytes)); } SKCodecOrigin origin; // this represents the EXIF orientation var bitmap = LoadBitmap(File.OpenRead(imagePath), out origin); // always load as 32bit (to overcome issues with indexed color) // if autorotate = true, and origin isn't correct for the rotation, rotate it if (resizeParams.autorotate && origin != SKCodecOrigin.TopLeft) { bitmap = RotateAndFlip(bitmap, origin); } // if either w or h is 0, set it based on ratio of original image if (resizeParams.h == 0) { resizeParams.h = (int)Math.Round(bitmap.Height * (float)resizeParams.w / bitmap.Width); } else if (resizeParams.w == 0) { resizeParams.w = (int)Math.Round(bitmap.Width * (float)resizeParams.h / bitmap.Height); } // if we need to crop, crop the original before resizing if (resizeParams.mode == "crop") { bitmap = Crop(bitmap, resizeParams); } // store padded height and width var paddedHeight = resizeParams.h; var paddedWidth = resizeParams.w; // if we need to pad, or max, set the height or width according to ratio if (resizeParams.mode == "pad" || resizeParams.mode == "max") { var bitmapRatio = (float)bitmap.Width / bitmap.Height; var resizeRatio = (float)resizeParams.w / resizeParams.h; if (bitmapRatio > resizeRatio) // original is more "landscape" { resizeParams.h = (int)Math.Round(bitmap.Height * ((float)resizeParams.w / bitmap.Width)); } else { resizeParams.w = (int)Math.Round(bitmap.Width * ((float)resizeParams.h / bitmap.Height)); } } // resize var resizedImageInfo = new SKImageInfo(resizeParams.w, resizeParams.h, SKImageInfo.PlatformColorType, bitmap.AlphaType); var resizedBitmap = bitmap.Resize(resizedImageInfo, SKBitmapResizeMethod.Lanczos3); // optionally pad if (resizeParams.mode == "pad") { resizedBitmap = Pad(resizedBitmap, paddedWidth, paddedHeight, resizeParams.format != "png"); } // encode var resizedImage = SKImage.FromBitmap(resizedBitmap); var encodeFormat = resizeParams.format == "png" ? SKEncodedImageFormat.Png : SKEncodedImageFormat.Jpeg; imageData = resizedImage.Encode(encodeFormat, resizeParams.quality); // cache the result _memoryCache.Set <byte[]>(cacheKey, imageData.ToArray()); // cleanup resizedImage.Dispose(); bitmap.Dispose(); resizedBitmap.Dispose(); return(imageData); }
private SKData GetImageData(string imagePath, ResizeParams resizeParams, DateTime lastWriteTimeUtc) { // check cache and return if cached string cacheKey; unchecked { cacheKey = "imgasc_" + imagePath.GetHashCode() + lastWriteTimeUtc.ToBinary() + resizeParams.ToString().GetHashCode(); } SKData imageData; byte[] cacheData = _asyncCacheService.GetByKeyAsync <byte[]>(cacheKey).Result; if (cacheData != null) { return(SKData.CreateCopy(cacheData)); } // this represents the EXIF orientation SKBitmap bitmap = LoadBitmap(File.OpenRead(imagePath), out SKEncodedOrigin origin); // always load as 32bit (to overcome issues with indexed color) // if autorotate = true, and origin isn't correct for the rotation, rotate it if (resizeParams.autorotate && origin != SKEncodedOrigin.TopLeft) { bitmap = RotateAndFlip(bitmap, origin); } // if either w or h is 0, set it based on ratio of original image if (resizeParams.h == 0) { resizeParams.h = (int)Math.Round(bitmap.Height * (float)resizeParams.w / bitmap.Width); } else if (resizeParams.w == 0) { resizeParams.w = (int)Math.Round(bitmap.Width * (float)resizeParams.h / bitmap.Height); } // if we need to crop, crop the original before resizing if (resizeParams.mode == "crop") { bitmap = Crop(bitmap, resizeParams); } // store padded height and width int paddedHeight = resizeParams.h; int paddedWidth = resizeParams.w; // if we need to pad, or max, set the height or width according to ratio if (resizeParams.mode == "pad" || resizeParams.mode == "max") { float bitmapRatio = (float)bitmap.Width / bitmap.Height; float resizeRatio = (float)resizeParams.w / resizeParams.h; if (bitmapRatio > resizeRatio) // original is more "landscape" { resizeParams.h = (int)Math.Round(bitmap.Height * ((float)resizeParams.w / bitmap.Width)); } else { resizeParams.w = (int)Math.Round(bitmap.Width * ((float)resizeParams.h / bitmap.Height)); } } // resize SKImageInfo resizedImageInfo = new SKImageInfo(resizeParams.w, resizeParams.h, SKImageInfo.PlatformColorType, bitmap.AlphaType); SKBitmap resizedBitmap = bitmap.Resize(resizedImageInfo, SKFilterQuality.None); // optionally pad if (resizeParams.mode == "pad") { resizedBitmap = Pad(resizedBitmap, paddedWidth, paddedHeight, resizeParams.format != "png"); } // encode SKImage resizedImage = SKImage.FromBitmap(resizedBitmap); SKEncodedImageFormat encodeFormat = resizeParams.format == "png" ? SKEncodedImageFormat.Png : SKEncodedImageFormat.Jpeg; imageData = resizedImage.Encode(encodeFormat, resizeParams.quality); // cache the result _asyncCacheService.SetValueAsync(cacheKey, imageData.ToArray()); // cleanup resizedImage.Dispose(); bitmap.Dispose(); resizedBitmap.Dispose(); return(imageData); }