/// <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 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); } } } // 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); }
public static string GetAppName(uint appID, out EAppType appType) { App data; using (var db = Database.Get()) { data = db.Query <App>("SELECT `AppID`, `Apps`.`Name`, `LastKnownName`, `Apps`.`AppType` FROM `Apps` WHERE `AppID` = @AppID", new { AppID = appID }).SingleOrDefault(); } appType = data.AppID == 0 || data.AppType == EAppType.Invalid ? EAppType.Application : data.AppType; return(FormatAppName(appID, data)); }
/// <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; // currently for gif I only save original so there is no resizing // TODO: with ImageMagick resizing a gif take a long time // plus the resized gif has a larger file size than original // I tried limit gif length to 800px, but even resizing to small has these issues // resize and store foreach (var resize in resizes) { // save original without resizing 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); }
/// <summary> /// Returns full path to a file after saving it to Azure Blob Storage. /// </summary> /// <param name="userId">The id of the user who uploads.</param> /// <param name="fileName">Slugged filename with ext.</param> /// <param name="year">Upload year.</param> /// <param name="month">Upload month.</param> /// <param name="content">The content of file.</param> /// <param name="appId">Which app it uploaded it.</param> /// <returns></returns> public async Task <string> SaveFileAsync(int userId, string fileName, string year, string month, byte[] content, EAppType appId) { // blobName "blog/1/2017/11/filename", container is "media" string blobName = string.Format("{0}/{1}/{2}/{3}/{4}", appId.ToString().ToLowerInvariant(), userId, year, month, fileName); // get a ref to blob which does not call server var blob = _container.GetBlockBlobReference(blobName); // make sure blob is unique int i = 1; while (await blob.ExistsAsync()) { blobName = blobName.Insert(blobName.LastIndexOf('.'), $"-{i}"); blob = _container.GetBlockBlobReference(blobName); } // set content type blob.Properties.ContentType = MimeTypeMap.GetMimeType(Path.GetExtension(fileName)); // create blob with contents await blob.UploadFromByteArrayAsync(content, 0, content.Length); return(blob.Uri.ToString()); }
public bool Deserialize(JSON_BuffEffectParam json) { if (json == null) { return(false); } this.iname = json.iname; this.job = json.job; this.buki = json.buki; this.birth = json.birth; this.sex = (ESex)json.sex; this.un_group = json.un_group; this.elem = Convert.ToInt32(json.elem.ToString("d7"), 2); this.rate = (OInt)json.rate; this.turn = (OInt)json.turn; this.chk_target = (EffectCheckTargets)json.chktgt; this.chk_timing = (EffectCheckTimings)json.timing; this.cond = (ESkillCondition)json.cond; this.mIsUpBuff = (OBool)false; this.mUpTiming = (EffectCheckTimings)json.up_timing; this.mAppType = (EAppType)json.app_type; this.mAppMct = json.app_mct; this.mEffRange = (EEffRange)json.eff_range; this.mFlags = (BuffFlags)0; if (json.is_up_rep != 0) { this.mFlags |= BuffFlags.UpReplenish; } if (json.is_no_dis != 0) { this.mFlags |= BuffFlags.NoDisabled; } if (json.is_no_bt != 0) { this.mFlags |= BuffFlags.NoBuffTurn; } ParamTypes type1 = (ParamTypes)json.type1; ParamTypes type2 = (ParamTypes)json.type2; ParamTypes type3 = (ParamTypes)json.type3; ParamTypes type4 = (ParamTypes)json.type4; ParamTypes type5 = (ParamTypes)json.type5; ParamTypes type6 = (ParamTypes)json.type6; ParamTypes type7 = (ParamTypes)json.type7; ParamTypes type8 = (ParamTypes)json.type8; ParamTypes type9 = (ParamTypes)json.type9; ParamTypes type10 = (ParamTypes)json.type10; ParamTypes type11 = (ParamTypes)json.type11; int length = 0; if (type1 != ParamTypes.None) { ++length; } if (type2 != ParamTypes.None) { ++length; } if (type3 != ParamTypes.None) { ++length; } if (type4 != ParamTypes.None) { ++length; } if (type5 != ParamTypes.None) { ++length; } if (type6 != ParamTypes.None) { ++length; } if (type7 != ParamTypes.None) { ++length; } if (type8 != ParamTypes.None) { ++length; } if (type9 != ParamTypes.None) { ++length; } if (type10 != ParamTypes.None) { ++length; } if (type11 != ParamTypes.None) { ++length; } if (length > 0) { this.buffs = new BuffEffectParam.Buff[length]; int index = 0; if (type1 != ParamTypes.None) { this.buffs[index] = new BuffEffectParam.Buff(); this.buffs[index].type = type1; this.buffs[index].value_ini = (OInt)json.vini1; this.buffs[index].value_max = (OInt)json.vmax1; this.buffs[index].value_one = (OInt)json.vone1; this.buffs[index].calc = (SkillParamCalcTypes)json.calc1; ++index; } if (type2 != ParamTypes.None) { this.buffs[index] = new BuffEffectParam.Buff(); this.buffs[index].type = type2; this.buffs[index].value_ini = (OInt)json.vini2; this.buffs[index].value_max = (OInt)json.vmax2; this.buffs[index].value_one = (OInt)json.vone2; this.buffs[index].calc = (SkillParamCalcTypes)json.calc2; ++index; } if (type3 != ParamTypes.None) { this.buffs[index] = new BuffEffectParam.Buff(); this.buffs[index].type = type3; this.buffs[index].value_ini = (OInt)json.vini3; this.buffs[index].value_max = (OInt)json.vmax3; this.buffs[index].value_one = (OInt)json.vone3; this.buffs[index].calc = (SkillParamCalcTypes)json.calc3; ++index; } if (type4 != ParamTypes.None) { this.buffs[index] = new BuffEffectParam.Buff(); this.buffs[index].type = type4; this.buffs[index].value_ini = (OInt)json.vini4; this.buffs[index].value_max = (OInt)json.vmax4; this.buffs[index].value_one = (OInt)json.vone4; this.buffs[index].calc = (SkillParamCalcTypes)json.calc4; ++index; } if (type5 != ParamTypes.None) { this.buffs[index] = new BuffEffectParam.Buff(); this.buffs[index].type = type5; this.buffs[index].value_ini = (OInt)json.vini5; this.buffs[index].value_max = (OInt)json.vmax5; this.buffs[index].value_one = (OInt)json.vone5; this.buffs[index].calc = (SkillParamCalcTypes)json.calc5; ++index; } if (type6 != ParamTypes.None) { this.buffs[index] = new BuffEffectParam.Buff(); this.buffs[index].type = type6; this.buffs[index].value_ini = (OInt)json.vini6; this.buffs[index].value_max = (OInt)json.vmax6; this.buffs[index].value_one = (OInt)json.vone6; this.buffs[index].calc = (SkillParamCalcTypes)json.calc6; ++index; } if (type7 != ParamTypes.None) { this.buffs[index] = new BuffEffectParam.Buff(); this.buffs[index].type = type7; this.buffs[index].value_ini = (OInt)json.vini7; this.buffs[index].value_max = (OInt)json.vmax7; this.buffs[index].value_one = (OInt)json.vone7; this.buffs[index].calc = (SkillParamCalcTypes)json.calc7; ++index; } if (type8 != ParamTypes.None) { this.buffs[index] = new BuffEffectParam.Buff(); this.buffs[index].type = type8; this.buffs[index].value_ini = (OInt)json.vini8; this.buffs[index].value_max = (OInt)json.vmax8; this.buffs[index].value_one = (OInt)json.vone8; this.buffs[index].calc = (SkillParamCalcTypes)json.calc8; ++index; } if (type9 != ParamTypes.None) { this.buffs[index] = new BuffEffectParam.Buff(); this.buffs[index].type = type9; this.buffs[index].value_ini = (OInt)json.vini9; this.buffs[index].value_max = (OInt)json.vmax9; this.buffs[index].value_one = (OInt)json.vone9; this.buffs[index].calc = (SkillParamCalcTypes)json.calc9; ++index; } if (type10 != ParamTypes.None) { this.buffs[index] = new BuffEffectParam.Buff(); this.buffs[index].type = type10; this.buffs[index].value_ini = (OInt)json.vini10; this.buffs[index].value_max = (OInt)json.vmax10; this.buffs[index].value_one = (OInt)json.vone10; this.buffs[index].calc = (SkillParamCalcTypes)json.calc10; ++index; } if (type11 != ParamTypes.None) { this.buffs[index] = new BuffEffectParam.Buff(); this.buffs[index].type = type11; this.buffs[index].value_ini = (OInt)json.vini11; this.buffs[index].value_max = (OInt)json.vmax11; this.buffs[index].value_one = (OInt)json.vone11; this.buffs[index].calc = (SkillParamCalcTypes)json.calc11; int num = index + 1; } foreach (BuffEffectParam.Buff buff in this.buffs) { if ((int)buff.value_one != 0) { this.mIsUpBuff = (OBool)true; break; } } } if (json.custom_targets != null) { this.custom_targets = new string[json.custom_targets.Length]; for (int index = 0; index < json.custom_targets.Length; ++index) { this.custom_targets[index] = json.custom_targets[index]; } } return(true); }
public bool Deserialize(JSON_BuffEffectParam json) { if (json == null) { return(false); } this.iname = json.iname; this.job = json.job; this.buki = json.buki; this.birth = json.birth; this.sex = (ESex)json.sex; this.elem = Convert.ToInt32(json.elem.ToString("d7"), 2); this.rate = (OInt)json.rate; this.turn = (OInt)json.turn; this.chk_target = (EffectCheckTargets)json.chktgt; this.chk_timing = (EffectCheckTimings)json.timing; this.cond = (ESkillCondition)json.cond; this.mAppType = (EAppType)json.app_type; this.mAppMct = json.app_mct; this.mEffRange = (EEffRange)json.eff_range; ParamTypes type1 = (ParamTypes)json.type1; ParamTypes type2 = (ParamTypes)json.type2; ParamTypes type3 = (ParamTypes)json.type3; ParamTypes type4 = (ParamTypes)json.type4; ParamTypes type5 = (ParamTypes)json.type5; ParamTypes type6 = (ParamTypes)json.type6; ParamTypes type7 = (ParamTypes)json.type7; ParamTypes type8 = (ParamTypes)json.type8; ParamTypes type9 = (ParamTypes)json.type9; ParamTypes type10 = (ParamTypes)json.type10; int length = 0; if (type1 != ParamTypes.None) { ++length; } if (type2 != ParamTypes.None) { ++length; } if (type3 != ParamTypes.None) { ++length; } if (type4 != ParamTypes.None) { ++length; } if (type5 != ParamTypes.None) { ++length; } if (type6 != ParamTypes.None) { ++length; } if (type7 != ParamTypes.None) { ++length; } if (type8 != ParamTypes.None) { ++length; } if (type9 != ParamTypes.None) { ++length; } if (type10 != ParamTypes.None) { ++length; } if (length > 0) { this.buffs = new BuffEffectParam.Buff[length]; int index = 0; if (type1 != ParamTypes.None) { this.buffs[index] = new BuffEffectParam.Buff(); this.buffs[index].type = type1; this.buffs[index].value_ini = (OInt)json.vini1; this.buffs[index].value_max = (OInt)json.vmax1; this.buffs[index].calc = (SkillParamCalcTypes)json.calc1; ++index; } if (type2 != ParamTypes.None) { this.buffs[index] = new BuffEffectParam.Buff(); this.buffs[index].type = type2; this.buffs[index].value_ini = (OInt)json.vini2; this.buffs[index].value_max = (OInt)json.vmax2; this.buffs[index].calc = (SkillParamCalcTypes)json.calc2; ++index; } if (type3 != ParamTypes.None) { this.buffs[index] = new BuffEffectParam.Buff(); this.buffs[index].type = type3; this.buffs[index].value_ini = (OInt)json.vini3; this.buffs[index].value_max = (OInt)json.vmax3; this.buffs[index].calc = (SkillParamCalcTypes)json.calc3; ++index; } if (type4 != ParamTypes.None) { this.buffs[index] = new BuffEffectParam.Buff(); this.buffs[index].type = type4; this.buffs[index].value_ini = (OInt)json.vini4; this.buffs[index].value_max = (OInt)json.vmax4; this.buffs[index].calc = (SkillParamCalcTypes)json.calc4; ++index; } if (type5 != ParamTypes.None) { this.buffs[index] = new BuffEffectParam.Buff(); this.buffs[index].type = type5; this.buffs[index].value_ini = (OInt)json.vini5; this.buffs[index].value_max = (OInt)json.vmax5; this.buffs[index].calc = (SkillParamCalcTypes)json.calc5; ++index; } if (type6 != ParamTypes.None) { this.buffs[index] = new BuffEffectParam.Buff(); this.buffs[index].type = type6; this.buffs[index].value_ini = (OInt)json.vini6; this.buffs[index].value_max = (OInt)json.vmax6; this.buffs[index].calc = (SkillParamCalcTypes)json.calc6; ++index; } if (type7 != ParamTypes.None) { this.buffs[index] = new BuffEffectParam.Buff(); this.buffs[index].type = type7; this.buffs[index].value_ini = (OInt)json.vini7; this.buffs[index].value_max = (OInt)json.vmax7; this.buffs[index].calc = (SkillParamCalcTypes)json.calc7; ++index; } if (type8 != ParamTypes.None) { this.buffs[index] = new BuffEffectParam.Buff(); this.buffs[index].type = type8; this.buffs[index].value_ini = (OInt)json.vini8; this.buffs[index].value_max = (OInt)json.vmax8; this.buffs[index].calc = (SkillParamCalcTypes)json.calc8; ++index; } if (type9 != ParamTypes.None) { this.buffs[index] = new BuffEffectParam.Buff(); this.buffs[index].type = type9; this.buffs[index].value_ini = (OInt)json.vini9; this.buffs[index].value_max = (OInt)json.vmax9; this.buffs[index].calc = (SkillParamCalcTypes)json.calc9; ++index; } if (type10 != ParamTypes.None) { this.buffs[index] = new BuffEffectParam.Buff(); this.buffs[index].type = type10; this.buffs[index].value_ini = (OInt)json.vini10; this.buffs[index].value_max = (OInt)json.vmax10; this.buffs[index].calc = (SkillParamCalcTypes)json.calc10; int num = index + 1; } } return(true); }
/// <summary> /// Returns media url after upload to storage. /// </summary> /// <param name="userId">Id of the user uploading the media.</param> /// <param name="fileName">File name with ext.</param> /// <param name="content">File content</param> /// <param name="appId">Which app it uploaded it.</param> /// <returns></returns> /// <remarks> /// Note: This method is optimized for metaweblog use with olw, other apps have totally /// different file logic. /// /// Depending on the storage provider, the returned media url could be relative path /// (File Sys) or absolute path (Azure Blog). /// </remarks> public async Task <string> UploadMediaAsync(int userId, string fileName, byte[] content, EAppType appId, EUploadedFrom uploadFrom) { // verify ext is supported var ext = Path.GetExtension(fileName); if (ext.IsNullOrEmpty() || !Accepted_Image_Types.Contains(ext, StringComparer.InvariantCultureIgnoreCase)) { throw new FanException("Upload file type is not supported."); } // time var uploadedOn = DateTimeOffset.UtcNow; var year = uploadedOn.Year.ToString(); var month = uploadedOn.Month.ToString("d2"); // make sure file name is not too long var fileNameWithoutExt = Path.GetFileNameWithoutExtension(fileName); if (fileNameWithoutExt.Length > MEDIA_FILENAME_MAXLEN) { fileNameWithoutExt = fileNameWithoutExt.Substring(0, MEDIA_FILENAME_MAXLEN); } // there is a quirk file uploaded from olw had "_2" suffixed to the name if (uploadFrom == EUploadedFrom.MetaWeblog && fileNameWithoutExt.EndsWith("_2")) { fileNameWithoutExt = fileNameWithoutExt.Remove(fileNameWithoutExt.Length - 2); } // slug file name // chinese fn ends up emtpy and the thumb file with chinese fn ends up with only "thumb" var slug = Util.FormatSlug(fileNameWithoutExt); if (slug.IsNullOrEmpty()) { slug = Util.RandomString(6); } else if (uploadFrom == EUploadedFrom.MetaWeblog && slug == "thumb") { slug = string.Concat(Util.RandomString(6), "_thumb"); } string fileNameSlugged = $"{slug}{ext}"; // save file to storage and get back file path var filePath = await _storageProvider.SaveFileAsync(userId, fileNameSlugged, year, month, content, EAppType.Blog); // encode filename var fileNameEncoded = WebUtility.HtmlEncode(fileNameWithoutExt); // since file name could have been updated for uniqueness var start = filePath.LastIndexOf('/') + 1; var uniqueFileName = filePath.Substring(start, filePath.Length - start); // save record to db var media = new Media { UserId = userId, AppId = appId, FileName = uniqueFileName, // unique filename from storage provider Title = fileNameEncoded, // original filename Description = null, Length = content.LongLength, MediaType = EMediaType.Image, UploadedOn = uploadedOn, UploadedFrom = uploadFrom, }; await _mediaRepo.CreateAsync(media); return(filePath); }
public void SetApplicationType(EAppType value) { _app_temp_settings[APPLICATION_TYPE] = ((int)value).ToString(); }
public static void SetAppType(int type) { appType = (EAppType)type; }
/// <summary> /// Returns relative path to a file after saving it on the file system. /// </summary> /// <param name="userId">The id of the user who uploads.</param> /// <param name="fileName">Slugged filename with ext.</param> /// <param name="year">Upload year.</param> /// <param name="month">Upload month.</param> /// <param name="content">The content of file.</param> /// <param name="appId">Which app it uploaded it.</param> /// <returns></returns> public async Task <string> SaveFileAsync(int userId, string fileName, string year, string month, byte[] content, EAppType appId) { // app name var appName = appId.ToString().ToLowerInvariant(); // dir to save this file in var dirPath = string.Format("{0}\\{1}\\{2}\\{3}\\{4}\\{5}", _hostingEnvironment.WebRootPath, _appSettings.MediaContainerName, appName, userId, year, month); // make sure dir exists if (!Directory.Exists(dirPath)) { Directory.CreateDirectory(dirPath); } // combine dir and filename var filePath = Path.Combine(dirPath, fileName); // make sure file is unique int i = 1; while (File.Exists(filePath)) { fileName = fileName.Insert(fileName.LastIndexOf('.'), $"-{i}"); filePath = Path.Combine(dirPath, fileName); } // save file to file sys using (var targetStream = File.Create(filePath)) using (MemoryStream stream = new MemoryStream(content)) { await stream.CopyToAsync(targetStream); } // returns relative path return($"{_appSettings.MediaContainerName}/{appName}/{userId}/{year}/{month}/{fileName}"); }
/// <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); image.Quality = 75; // though 75 is default, having it here does make a difference on making output file size smaller! 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); }