using Infrastructure; using Infrastructure.Attribute; using Infrastructure.Extensions; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Options; using System; using System.IO; using System.Net; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; using ARW.Common; using ARW.Model.System; using ARW.Service.System.IService; using System.Drawing.Drawing2D; using System.Drawing.Imaging; using System.Drawing; using Encoder = System.Drawing.Imaging.Encoder; namespace ARW.Service.System { /// /// 文件管理 /// [AppService(ServiceType = typeof(ISysFileService), ServiceLifetime = LifeTime.Transient)] public class SysFileService : BaseService, ISysFileService { private string domainUrl = AppSettings.GetConfig("AARWYUN_OSS:domainUrl"); private readonly ISysConfigService SysConfigService; private OptionsSetting OptionsSetting; public SysFileService(ISysConfigService sysConfigService, IOptions options) { SysConfigService = sysConfigService; OptionsSetting = options.Value; } /// /// 存储本地 /// /// 存储文件夹 /// 存储根目录 /// 自定文件名 /// 上传的文件流 /// /// public async Task SaveFileToLocal(string rootPath, string fileName, string fileDir, string userName, IFormFile formFile) { string fileExt = Path.GetExtension(formFile.FileName); fileName = (fileName.IsEmpty() ? HashFileName() : fileName) + fileExt; string filePath = GetdirPath(fileDir); string finalFilePath = Path.Combine(rootPath, filePath, fileName); double fileSize = Math.Round(formFile.Length / 1024.0, 2); if (!Directory.Exists(Path.GetDirectoryName(finalFilePath))) { Directory.CreateDirectory(Path.GetDirectoryName(finalFilePath)); } using (var stream = new FileStream(finalFilePath, FileMode.Create)) { // 图片压缩 if (IsImageExtension(fileExt)) { if (fileSize > 100) { GetPicThumbnail(formFile, 0, 0, 90, stream); } else { await formFile.CopyToAsync(stream); } } else //视频压缩 { await formFile.CopyToAsync(stream); } } var fs = File.OpenRead(@finalFilePath); fileSize = Math.Round(fs.Length / 1024.0, 2); string uploadUrl = OptionsSetting.Upload.UploadUrl; string accessPath = string.Concat(uploadUrl, "/", filePath.Replace("\\", "/"), "/", fileName); SysFile file = new(formFile.FileName, fileName, fileExt, fileSize + "kb", filePath, userName) { StoreType = (int)Infrastructure.Enums.StoreType.LOCAL, FileType = formFile.ContentType, FileUrl = finalFilePath.Replace("\\", "/"), AccessUrl = accessPath }; file.Id = await InsertFile(file); return file; } /// /// 上传文件到阿里云 /// /// /// /// public async Task SaveFileToAliyun(SysFile file, IFormFile formFile) { file.FileName = (file.FileName.IsEmpty() ? HashFileName() : file.FileName) + file.FileExt; file.StorePath = GetdirPath(file.StorePath); string finalPath = Path.Combine(file.StorePath, file.FileName); HttpStatusCode statusCode = AliyunOssHelper.PutObjectFromFile(formFile.OpenReadStream(), finalPath, ""); if (statusCode != HttpStatusCode.OK) return file; file.StorePath = file.StorePath; file.FileUrl = finalPath; file.AccessUrl = string.Concat(domainUrl, "/", file.StorePath.Replace("\\", "/"), "/", file.FileName); file.Id = await InsertFile(file); return file; } /// /// 获取文件存储目录 /// /// /// 是否按年月日存储 /// public string GetdirPath(string storePath = "", bool byTimeStore = true) { DateTime date = DateTime.Now; string timeDir = date.ToString("yyyyMMdd"); if (!string.IsNullOrEmpty(storePath)) { timeDir = Path.Combine(storePath, timeDir); } return timeDir; } public string HashFileName(string str = null) { if (string.IsNullOrEmpty(str)) { str = Guid.NewGuid().ToString(); } MD5 md5 = MD5.Create(); return BitConverter.ToString(md5.ComputeHash(Encoding.Default.GetBytes(str)), 4, 8).Replace("-", ""); } public Task InsertFile(SysFile file) { try { return Insertable(file).ExecuteReturnSnowflakeIdAsync();//单条插入返回雪花ID; } catch (Exception ex) { Console.WriteLine("存储图片失败" + ex.Message); throw new Exception(ex.Message); } } #region GetPicThumbnail public static bool GetPicThumbnail(IFormFile stream, int dHeight, int dWidth, int flag, Stream outstream) { //可以直接从流里边得到图片,这样就可以不先存储一份了 Image iSource = Image.FromStream(stream.OpenReadStream()); //如果为参数为0就保持原图片 if (dHeight == 0) { dHeight = iSource.Height; } if (dWidth == 0) { dWidth = iSource.Width; } ImageFormat tFormat = iSource.RawFormat; int sW = 0, sH = 0; //按比例缩放 Size tem_size = new Size(iSource.Width, iSource.Height); if (tem_size.Width > dHeight || tem_size.Width > dWidth) { if ((tem_size.Width * dHeight) > (tem_size.Width * dWidth)) { sW = dWidth; sH = (dWidth * tem_size.Height) / tem_size.Width; } else { sH = dHeight; sW = (tem_size.Width * dHeight) / tem_size.Height; } } else { sW = tem_size.Width; sH = tem_size.Height; } Bitmap ob = new Bitmap(dWidth, dHeight); Graphics g = Graphics.FromImage(ob); g.Clear(Color.WhiteSmoke); g.CompositingQuality = CompositingQuality.HighQuality; g.SmoothingMode = SmoothingMode.HighQuality; g.InterpolationMode = InterpolationMode.HighQualityBicubic; g.DrawImage(iSource, new Rectangle((dWidth - sW) / 2, (dHeight - sH) / 2, sW, sH), 0, 0, iSource.Width, iSource.Height, GraphicsUnit.Pixel); g.Dispose(); //以下代码为保存图片时,设置压缩质量 EncoderParameters ep = new EncoderParameters(); long[] qy = new long[1]; qy[0] = flag;//设置压缩的比例1-100 EncoderParameter eParam = new EncoderParameter(Encoder.Quality, qy); ep.Param[0] = eParam; try { ImageCodecInfo[] arrayICI = ImageCodecInfo.GetImageEncoders(); ImageCodecInfo jpegICIinfo = null; for (int x = 0; x < arrayICI.Length; x++) { if (arrayICI[x].FormatDescription.Equals("JPEG")) { jpegICIinfo = arrayICI[x]; break; } } if (jpegICIinfo != null) { //可以存储在流里边; ob.Save(outstream, jpegICIinfo, ep); } else { ob.Save(outstream, tFormat); } return true; } catch { return false; } finally { iSource.Dispose(); ob.Dispose(); } } #endregion private bool IsImageExtension(string extension) { return extension == ".jpg" || extension == ".jpeg" || extension == ".png" || extension == ".gif"; } } }