成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久

您的位置:首頁技術文章
文章詳情頁

Net core中使用System.Drawing對上傳的圖片流進行壓縮(示例代碼)

瀏覽:303日期:2022-06-08 13:57:32
目錄
  • 直接壓縮圖片
  • 通過文件流壓縮圖片
  • 上傳到七牛云前壓縮圖片
    • 部署問題
    • 在Linux中安裝
  • 產生原因
    • 解決方案

      由于net core 中默認沒有System.Drawing,可以通過nuget下載一個來代替System.Drawing.Common

      直接壓縮圖片

      /// <summary>/// 圖片壓縮/// </summary>/// <param name="sFile">原圖片位置</param>/// <param name="dFile">壓縮后圖片位置</param>/// <param name="dHeight">圖片壓縮后的高度</param>/// <param name="dWidth">圖片壓縮后的寬度</param>/// <param name="flag">圖片壓縮比0-100,數值越小壓縮比越高,失真越多</param>/// <returns></returns>public static bool GetPicThumbnailTest(string sFile, string dFile, int dHeight, int dWidth, int flag){    System.Drawing.Image iSource = System.Drawing.Image.FromFile(sFile);    //如果為參數為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(System.Drawing.Imaging.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(dFile, jpegICIinfo, ep);//dFile是壓縮后的新路徑 }else{    ob.Save(dFile, tFormat);}return true;    }    catch    {return false;    }    finally    {iSource.Dispose();ob.Dispose();    }}

      通過文件流壓縮圖片

      有些時候我們不想先把圖片保存后,然后在去讀取壓縮,我們想通過文件流就直接對圖片進行壓縮了,比如我們要把圖片上傳到七牛云

      先把流進行壓縮在上傳到七牛云就比較科學了

      1:首先我們需要通過圖片上傳的流來獲取圖片

      foreach (IFormFile file in files)//獲取多個文件列表集合   {       if (file.Length > 0)       {   //獲取圖片上傳的流   Stream stream = file.OpenReadStream();   //直接從流里邊變成圖片   System.Drawing.Image iSource = System.Drawing.Image.FromStream(stream);       }   }

      2:通過圖片壓縮算法把圖片進行壓縮

      這里有一個參數是輸入流,后面還有一個是壓縮后的輸出流

      /// <summary>/// 上傳圖片文件/// </summary>/// <returns></returns>[HttpPost]public async Task<IActionResult> UploadImageFile_WeChat(){    var file = IHttpContextAccessor.HttpContext.Request.Form.Files;    if (file == null || file.Count == 0)    {return Fail("未上傳有效文件");    }    var result = new List<dynamic>();    foreach (var item in file)    {var ExtensionName = Path.GetExtension(item.FileName).ToLower();var RemotePath = getRemotePath(ExtensionName);if (string.IsNullOrEmpty(RemotePath) || !"image".Equals(RemotePath)){    return Fail("不支持此類型文件的上傳");}string remotePath = PathFormatter.Format(item.FileName + "." + ExtensionName, "/upload/" + RemotePath + "/image" + "/{yyyy}{mm}/{dd}{time}{rand:6}");string savePath = AppDomain.CurrentDomain.BaseDirectory + "/wwwroot/" + remotePath;MemoryStream memoryStream = new MemoryStream();//ob.Save(memoryStream, jpegICIinfo, ep);//這里的ob就是壓縮后的Bitmap對象var k = GetPicThumbnail(item.OpenReadStream(), 0, 0, 70, memoryStream);System.Drawing.Image imgSource = System.Drawing.Image.FromStream(memoryStream);imgSource.Save(savePath);if (k){    result.Add(new { url = Config.FileConfig.fileUrl + remotePath, remoteUrl = remotePath, name = item.FileName });}    }    return Success("上傳成功", result);}private bool GetPicThumbnail(Stream stream, int dHeight, int dWidth, int flag, Stream outstream){    //可以直接從流里邊得到圖片,這樣就可以不先存儲一份了    System.Drawing.Image iSource = System.Drawing.Image.FromStream(stream);    //如果為參數為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(System.Drawing.Imaging.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();    }}

        3:把壓縮后的圖片轉化成流,很簡單用一個內存流來中轉一下就好了

      MemoryStream memoryStream = new MemoryStream(); ob.Save(memoryStream, jpegICIinfo, ep);//這里的ob就是壓縮后的Bitmap對象

         為了驗證一下轉化是否正確,我們可以把流在轉化成圖片然后在圖片進行存儲

      System.Drawing.Image imgSource = System.Drawing.Image.FromStream(memoryStream);imgSource.Save("url");

        如果能夠成功壓縮并成功保存就說明這些步驟都成功了!

      這里說一下圖片傳輸的思路:

      圖片文件這種本身是無法進行傳輸的,就像跨語言的對象也是無法進行傳輸。但是我們可以事先約定一種標準,

      讓雙方都可以認識都可以解析的一種標準,比如base64,比如對象的json序列化,比如光纖信號的光波表示,其實原理都是一樣。

      上傳到七牛云前壓縮圖片

      通過上面的方法可以得到一個輸出流,我們可以通過它進行圖片的保存,但是如果直接把這個輸出流傳遞到七牛云的方法中去,圖片是不能被上傳成功的,存儲大小會是0kb,說明我們這個流七牛云的接口識別不到,也就是約定的內容不一樣,我們要改造成七牛云能夠被識別的狀態

      換一個方法嘗試,直接用流不行,就從流里邊讀出來字節數組試試

      //實例化一個內存流,存放壓縮后的圖片   MemoryStream ysstream = new MemoryStream();   bool issuc = ImageTool.GetPicThumbnail(stream, 300, 300, 80, ysstream);    if (issuc)   {       //通過流上傳圖片到七牛云       //HttpResult result = um.UploadStream(stream, saveKey, uploadToken);       //從內存流里邊讀出來字節數組上傳到七牛云       HttpResult result = um.UploadData(ysstream.ToArray(), saveKey, uploadToken);       if (result.Code == 200)       {   return Json(result.Text);       }       else       {   throw new Exception(result.RefText);//上傳失敗錯誤信息       }   }   else   {       throw new Exception("圖片壓縮失敗");//上傳失敗錯誤信息   }

        成功了

      換回流試試呢,不應該啊。傳遞流進去他里邊也應該是讀取的直接哇,本質上都一樣哇

      還是不行,看來得看一下他這個源碼了,看一下他拿到這個流過后是怎么去用的,就能針對性解決問題了

      部署問題

      在Windows環境下直接運行是沒問題的,但是發布到Linux上就會報錯

      在Linux中安裝

      開始安裝libgdiplus,執行【docker ps -a 】查看所有容器

      【docker start 容器ID】 將容器運行起來

      【docker exec -it e90f2b9d448d /bin/bash】進入該容器bash界面

      執行【apt-get update】

      【apt-get install -y libgdiplus】安裝libgdiplus類庫

      【ln -s /usr/lib/libgdiplus.so /usr/lib/gdiplus.dll】創建鏈接文件

      【eixt】退出docker bash到宿主機的bash,執行 【docker restart 容器ID】,此時接口已經能正確訪問了

      上面的方法有個弊端,假如容器被誤刪,又要重新給容器安裝libgdiplus庫。

      我們可以把修改好的容器制作成鏡像,執行【docker commit e90f2b9d448d skyapi_libgdiplus】,然后執行【docker images】,

      可以看到名字叫skyapi_libgdiplus的Docker鏡像已經制作好了。今后只需要在 docker run -t 參數后面指定skyapi_libgdiplus鏡像即可。

      當前還可以將鏡像保存到docker hub,本地硬盤都可以。

      喜聞樂見的是,.NET 6發布了,但是避免不了新框架帶來各種問題。在以往的跨平臺應用中,往往采用System.Drawing.Common這個庫作為圖形編輯組件。

      在.NET 6之前,在Linux操作系統中需要用到這個庫時,只需要安裝libgdiplus和libc6-dev這兩個依賴即可。但是在.NET 6中,System.Drawing.Common被歸為Windows特定的庫,編譯時產生“'Image.xxx()' is only supported on: 'windows'.”這樣的警告。這不是最重要的,嚴重的是,在Linux中調用時,會產生“The type initializer for 'Gdip' threw an exception.”這樣的異常。

      產生原因

      在設計上System.Drawing.Common 是 Windows 技術的精簡包裝器,因此其跨平臺實現欠佳。

      具微軟文檔中描述,在舊的行為上,libgdiplus 是本機端 System.Drawing.Common 跨平臺實現的主要提供程序。 libgdiplus 實際上是對 System.Drawing.Common 所依賴的 Windows 部分的重新實現。 該實現使 libgdiplus 成為一個重要的組件。 它大約有 30,000 行 C 代碼,大部分未經測試,而且缺少很多功能。 libgdiplus 還具有許多用于圖像處理和文本呈現的外部依賴項,例如 cairo、pango 和其他本機庫。 這些依賴項使得維護和交付組件更具挑戰性。 自從包含 Mono 跨平臺實現以來,我們已將許多從未得到修復的問題重定向到 libgdiplus。 相比之下,我們采用的其他外部依賴項,例如 icu 或 openssl,都是高質量的庫。 使 libgdiplus 的功能集和質量與 .NET 堆棧的其余部分相媲美是不可行的。

      在這之后,System.Drawing.Common 將僅在 Windows 窗體和 GDI+ 項目中使用。

      解決方案

      1、項目不會在Linux平臺運行,僅在Windows中運行

      可以忽略這個警告。

      2、通過將 runtimeconfig.json 文件中的 System.Drawing.EnableUnixSupport 運行時配置開關設置為 true 來啟用對非 Windows 平臺的支持。

      {   "runtimeOptions": {      "configProperties": { "System.Drawing.EnableUnixSupport": true      }   }}

      3、換用其它支持跨平臺的圖像處理庫

      如:

      • ImageSharp
      • SkiaSharp

      需要注意的是,這些庫并不與System.Drawing.Common的API兼容,所以更換相應的庫之后需要重新編寫相關代碼。

      到此這篇關于Net core中使用System.Drawing對上傳的圖片流進行壓縮的文章就介紹到這了,更多相關Net core圖片壓縮內容請搜索以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持!

      標簽: ASP.NET
      成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久
      国产激情一区二区三区桃花岛亚洲| 国产美女久久久久| 麻豆成人久久精品二区三区红| 亚洲国产专区校园欧美| 久久久久亚洲综合| 欧美日韩一区二区三区不卡| 久久精品国产77777蜜臀| 丰满少妇久久久久久久| 国产精品18久久久| 一区二区三区在线视频免费观看| 国产乱人伦精品一区二区在线观看| 一区二区毛片| 日韩美女视频一区二区| 亚洲婷婷免费| 欧美国产成人在线| 欧美日本国产| 久久精品欧美一区二区三区不卡| 日韩和欧美的一区| 久久综合狠狠| 日韩高清不卡一区| 91福利资源站| 日本va欧美va欧美va精品| 美女诱惑黄网站一区| 亚洲国产精品麻豆| 亚洲综合欧美| 亚洲福利一二三区| 亚洲免费网站| 亚洲欧美精品| 日韩一区精品字幕| 91极品视觉盛宴| 蜜桃视频免费观看一区| 乱码第一页成人| 视频精品一区二区| 色天天综合色天天久久| 日本麻豆一区二区三区视频| 色婷婷久久久综合中文字幕| 日韩国产欧美一区二区三区| 色婷婷av一区二区三区大白胸| 美女在线视频一区| 69堂成人精品免费视频| 极品少妇一区二区三区精品视频 | 亚洲一级影院| 一区二区三区欧美亚洲| 亚洲欧美日韩专区| 亚洲v精品v日韩v欧美v专区| 色婷婷精品久久二区二区蜜臀av| 麻豆精品久久久| 欧美妇女性影城| 成人性色生活片| 国产欧美一区二区精品忘忧草| 欧美人成在线| 一区二区三区国产| 久久久久久一区二区| 日本视频免费一区| 欧美日韩在线直播| 成人蜜臀av电影| 国产精品久久久久久妇女6080| 国产欧美日本在线| 日本v片在线高清不卡在线观看| 91.com视频| 欧美一区不卡| 一区二区中文视频| 亚洲在线不卡| 久久国产精品72免费观看| 丝袜美腿一区二区三区| 欧美日韩国产美| 99久久免费视频.com| 中文字幕一区在线| 久久精品盗摄| 国产精华液一区二区三区| 国产网红主播福利一区二区| 亚洲专区在线| 国产一区二区网址| 久久久高清一区二区三区| 国产伊人精品| 视频在线观看一区| 日韩欧美一区在线观看| 欧美视频观看一区| 亚洲午夜久久久久久久久电影院 | 国产精品久久二区二区| 国产精品一区亚洲| 老司机精品视频导航| 久久亚洲影视婷婷| 香蕉久久夜色| www.在线欧美| 亚洲不卡av一区二区三区| 欧美一区二区三区在线电影 | 欧美在线免费播放| 高清国产一区二区| 亚洲免费电影在线| 欧美精品成人一区二区三区四区| av电影在线观看不卡| 亚洲免费观看高清在线观看| 欧美三级蜜桃2在线观看| 91美女片黄在线观看| 一区二区三区日韩欧美精品 | 91在线免费看| 午夜精品久久久久影视| wwwwxxxxx欧美| 欧美亚洲免费| 91色九色蝌蚪| 麻豆91在线播放免费| 中文字幕巨乱亚洲| 精品视频在线看| 在线播放一区| 国产激情一区二区三区四区| 亚洲欧洲国产日韩| 在线不卡欧美精品一区二区三区| 欧美激情1区| 免费高清成人在线| 自拍视频在线观看一区二区| 日韩视频中午一区| 香蕉国产精品偷在线观看不卡| 99久久精品国产导航| 青青草97国产精品免费观看 | 国内精品久久久久影院一蜜桃| 亚洲欧洲一区二区三区| 欧美一级xxx| 久久综合久久综合这里只有精品| 色综合亚洲欧洲| 奇米精品一区二区三区四区| 亚洲国产精品激情在线观看| 欧美日韩一区小说| 一本久道久久久| 丰满少妇久久久久久久| 亚洲一区二区成人在线观看| 久久久久久久精| 欧美午夜宅男影院| 国产伦精品一区二区三区照片91 | 成人av网站免费观看| 日韩国产精品久久久久久亚洲| 国产午夜精品一区二区三区嫩草| 欧美另类一区二区三区| 亚洲综合电影一区二区三区| 色综合久久中文综合久久97| 精品一区二区三区影院在线午夜 | 国产精一品亚洲二区在线视频| 国内视频一区| 精品999久久久| 26uuu精品一区二区在线观看| 天天综合天天综合色| 免费人成在线不卡| 欧美激情1区2区| 欧美日韩系列| 日韩一区二区三区精品视频| 国模娜娜一区二区三区| 亚洲成人动漫在线免费观看| 国产欧美中文在线| 91精品在线免费| 欧美精品xxxxbbbb| 不卡一区在线观看| 葵司免费一区二区三区四区五区| 亚洲国产一区二区三区| 欧美+亚洲+精品+三区| 国产精品麻豆视频| 欧美精品一区二区三区在线看午夜 | 国产精品久久久久久久久图文区| 日韩视频中午一区| 国产一区二区毛片| 国产精品家庭影院| 亚洲精品系列| 亚洲第四色夜色| 欧美久久久久久久久| av在线播放不卡| 国产精品传媒视频| 色诱视频网站一区| 一区二区三区日本| 裸体在线国模精品偷拍| 一区二区三区.www| 一区二区高清视频在线观看| 亚洲国产成人自拍| 久久―日本道色综合久久| 这里是久久伊人| 欧美二区在线观看| 欧美巨大另类极品videosbest| 青青草成人在线观看| 亚洲成av人片在线观看| 夜夜揉揉日日人人青青一国产精品| 亚洲特黄一级片| 综合欧美一区二区三区| 五月天国产精品| 日韩在线一区二区| 亚洲国产中文字幕| 午夜欧美在线一二页| 五月天国产精品| 日韩高清在线电影| 九色综合狠狠综合久久| 国精产品一区一区三区mba桃花| 精品一区二区三区视频在线观看 | 亚洲伦伦在线| 国产精品久久久免费| 久久福利一区| 欧美色图第一页| 欧美一级爆毛片| 久久精品夜色噜噜亚洲aⅴ| 中文字幕av免费专区久久| 一区精品在线播放| 五月天丁香久久| 久久99精品国产麻豆不卡| 国产一区999|