using System; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Linq; using System.Threading.Tasks; using Sony.Filtr.Contracts.Abstractions; namespace Sony.Filtr.Core.Factory { public class ImageFactory : IImageFactory { private readonly string _bucketPrefix; private readonly StorageFactory _storageFactory; public ImageFactory(string bucketPrefix, StorageFactory storageFactory) { _bucketPrefix = bucketPrefix; _storageFactory = storageFactory; } private const string OriginalBucketName = "sony-editorialimages-original"; private const string ThumbnailBucketName = "sony-editorialimages"; private const string IconBucket = "sony-playlistcategoryicon"; private readonly Size _resizeSize = new Size(128, 202); private readonly Size _iconSize = new Size(128, 128); public Stream GetOriginal(string fileName) { return _storageFactory.GetObject(fileName, GetBucketName(OriginalBucketName)); } private string GetBucketName(string bucketName) { if (!string.IsNullOrWhiteSpace(_bucketPrefix)) { return _bucketPrefix + "-" + bucketName; } return bucketName; } public Stream GetThumbnail(string fileName) { return _storageFactory.GetObject(fileName, GetBucketName(ThumbnailBucketName)); } public void DeleteImage(string fileName) { _storageFactory.DeleteObject(fileName, GetBucketName(ThumbnailBucketName)); _storageFactory.DeleteObject(fileName, GetBucketName(OriginalBucketName)); } public async Task SaveImageAsync(string fileName, Stream stream) { await _storageFactory.PutObjectAsync(fileName, GetBucketName(ThumbnailBucketName), stream); } public void SaveResizedAndOrignalImage(string fileName, Stream stream) { var outputStream = ResizeImage(stream, _resizeSize); _storageFactory.PutObject(fileName, GetBucketName(ThumbnailBucketName), outputStream); _storageFactory.PutObject(fileName, GetBucketName(OriginalBucketName), stream); } public void SavePlaylistCategoryIcon(string fileName, Stream stream) { var outputStream = ResizeImage(stream, _iconSize); _storageFactory.PutObject(fileName, GetBucketName(IconBucket), outputStream); } public Stream ResizeImage(Image image, Size size, ImageFormat imageFormat) { Image outputBitmap = new Bitmap(size.Width, size.Height); using (var g = Graphics.FromImage(outputBitmap)) { g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality; g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; g.DrawImage(image, 0, 0, size.Width, size.Height); } Stream outputStream; if (imageFormat.Equals(ImageFormat.Png)) { outputStream = GetPNGStream(outputBitmap); } else if (imageFormat.Equals(ImageFormat.Jpeg)) { outputStream = GetHighQualityJpeg(outputBitmap); } else { throw new Exception("Unsupported imageFormat"); } outputBitmap.Dispose(); outputStream.Position = 0; return outputStream; } public Stream ResizeImage(Stream inputStream, Size size) { inputStream.Position = 0; var inputBitmap = Image.FromStream(inputStream); Image outputBitmap = new Bitmap(size.Width, size.Height); using (var g = Graphics.FromImage(outputBitmap)) { g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality; g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; g.DrawImage(inputBitmap, 0, 0, size.Width, size.Height); } var outputStream = GetPNGStream(outputBitmap);// GetHighQualityJpeg(outputBitmap); inputBitmap.Dispose(); outputBitmap.Dispose(); outputStream.Position = 0; return outputStream; } private Stream GetPNGStream(Image outputBitmap) { var outputStream = new MemoryStream(); outputBitmap.Save(outputStream, ImageFormat.Png); return outputStream; } private Stream GetHighQualityJpeg(Image outputBitmap) { var jpgEncoder = GetImageEncoders(ImageFormat.Jpeg); Encoder myEncoder = Encoder.Quality; var encoderParameters = new EncoderParameters(); encoderParameters.Param[0] = new EncoderParameter(myEncoder, (long)90); var outputStream = new MemoryStream(); outputBitmap.Save(outputStream, jpgEncoder, encoderParameters); return outputStream; } private ImageCodecInfo GetImageEncoders(ImageFormat format) { ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders(); return codecs.FirstOrDefault(codec => codec.FormatID == format.Guid); } public bool IsValidImageAndAllowedFormat(Stream requestStream) { var result = false; try { Image img = Image.FromStream(requestStream); // Check if file stream can be loaded as image and is either jpeg or png. result = img.RawFormat.Equals(ImageFormat.Jpeg) || img.RawFormat.Equals(ImageFormat.Png); } catch (OutOfMemoryException) { // Image.FromFile throws an OutOfMemoryException // if the file does not have a valid image format or // GDI+ does not support the pixel format of the file. // } requestStream.Position = 0; return result; } public Image GetImage(Stream requestStream) { try { Image img = Image.FromStream(requestStream); return img; } catch (Exception) { return null; } } } }