/// <summary> /// Uploads image by resizing and storing it. /// </summary> /// <param name="source"></param> /// <param name="resizes"></param> /// <param name="fileName">Unique filename.</param> /// <param name="contentType"></param> /// <param name="uploadedOn"></param> /// <param name="appType"></param> /// <param name="userId"></param> /// <param name="uploadFrom"></param> /// <returns></returns> public async Task <Media> UploadImageAsync(Stream source, List <ImageResizeInfo> resizes, string fileName, string contentType, string title, DateTimeOffset uploadedOn, EAppType appType, int userId, EUploadedFrom uploadFrom = EUploadedFrom.Browser) { int resizeCount = 0; var(widthOrig, heightOrig) = GetOriginalSize(source); foreach (var resize in resizes) { using (var dest = new MemoryStream()) { // each time source is read, it needs reset source.Position = 0; // don't resize original png and gif may output large file size, save it as is if (resize.TargetSize == int.MaxValue) { await _storageProvider.SaveFileAsync(source, fileName, resize.Path, resize.PathSeparator); } else if (Math.Max(widthOrig, heightOrig) > resize.TargetSize) // only resize and save when it's larger than target { resizeCount++; Resize(source, dest, resize.TargetSize); dest.Position = 0; await _storageProvider.SaveFileAsync(dest, fileName, resize.Path, resize.PathSeparator); } } } // if already exists return it var media = await _mediaRepo.GetAsync(fileName, uploadedOn.Year, uploadedOn.Month); if (media != null) { return(media); } // create record in db media = new Media { UserId = userId, AppType = appType, FileName = fileName, Title = title, Description = null, Length = source.Length, MediaType = EMediaType.Image, UploadedOn = uploadedOn, UploadedFrom = uploadFrom, Width = widthOrig, Height = heightOrig, Caption = title, ContentType = contentType, Alt = title, ResizeCount = resizeCount, }; await _mediaRepo.CreateAsync(media); return(media); }
/// <summary> /// Uploads image by resizing and storing it. /// </summary> /// <param name="source"></param> /// <param name="resizes"></param> /// <param name="fileName"></param> /// <param name="contentType"></param> /// <param name="uploadedOn"></param> /// <param name="appType"></param> /// <param name="userId"></param> /// <param name="uploadFrom"></param> /// <returns></returns> public async Task <Media> UploadImageAsync(Stream source, List <ImageResizeInfo> resizes, string fileName, string contentType, string title, DateTimeOffset uploadedOn, EAppType appType, int userId, EUploadedFrom uploadFrom = EUploadedFrom.Browser) { int widthOrig; int heightOrig; int resizeCount = 0; if (contentType.Equals("image/gif")) { using (var imageColl = new MagickImageCollection(source)) { widthOrig = imageColl[0].Width; heightOrig = imageColl[0].Height; // resize and store foreach (var resize in resizes) { // save original without resizing, currently I couldn't dec original file size by resizing with ImageMagick if (resize.TargetSize == int.MaxValue) { source.Position = 0; await _storageProvider.SaveFileAsync(source, fileName, resize.Path, resize.PathSeparator); } else if (Math.Max(widthOrig, heightOrig) > resize.TargetSize) { resizeCount++; var(width, height) = GetNewSize(widthOrig, heightOrig, resize.TargetSize); imageColl.Coalesce(); foreach (var image in imageColl) { var colors = image.TotalColors; image.Resize(width, height); // resize will make # of colors higher image.Quantize(new QuantizeSettings { Colors = colors, // set it back to the smaller original colors DitherMethod = DitherMethod.No }); } imageColl.Optimize(); await _storageProvider.SaveFileAsync(imageColl.ToByteArray(), fileName, resize.Path, resize.PathSeparator); } } } } else if (contentType.Equals("image/png")) { using (var image = new MagickImage(source)) { widthOrig = image.Width; heightOrig = image.Height; foreach (var resize in resizes) { // save original without resizing for png if (resize.TargetSize == int.MaxValue) { source.Position = 0; await _storageProvider.SaveFileAsync(source, fileName, resize.Path, resize.PathSeparator); } else if (Math.Max(widthOrig, heightOrig) > resize.TargetSize) { resizeCount++; var(width, height) = GetNewSize(widthOrig, heightOrig, resize.TargetSize); //image.Quality = 75; // does not seem to affect output file size, so commented out image.Resize(width, height); await _storageProvider.SaveFileAsync(image.ToByteArray(), fileName, resize.Path, resize.PathSeparator); } } } } else // jpg { using (var image = new MagickImage(source)) { widthOrig = image.Width; heightOrig = image.Height; foreach (var resize in resizes) { if (resize.TargetSize == int.MaxValue || Math.Max(widthOrig, heightOrig) > resize.TargetSize) { if (resize.TargetSize != int.MaxValue) { resizeCount++; } var(width, height) = GetNewSize(widthOrig, heightOrig, resize.TargetSize); // setting the Quality is needed for having it here makes a difference for a smaller output file size! image.Quality = 85; // 75 is default image.Resize(width, height); await _storageProvider.SaveFileAsync(image.ToByteArray(), fileName, resize.Path, resize.PathSeparator); } } } } // create record in db var media = new Media { UserId = userId, AppType = appType, FileName = fileName, Title = title, Description = null, Length = source.Length, MediaType = EMediaType.Image, UploadedOn = uploadedOn, UploadedFrom = uploadFrom, Width = widthOrig, Height = heightOrig, Caption = title, ContentType = contentType, Alt = title, ResizeCount = resizeCount, }; await _mediaRepo.CreateAsync(media); return(media); }