<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
坦白從寬吧,我就是那個花了兩天兩夜把 1M 圖片優化到 100kb 的傢伙——王小二!
自從因為一篇報道登上熱搜後,我差點抑鬱,每天要靠 50 片安眠藥才能入睡。
網路上曝光的那些關於一碼通的訊息,有真有假,我這裡就不再澄清了。就說說我是怎麼把圖片從 1M 優化到 100kb 的故事吧。
是的,由於系統群體規模和存取規模的特殊性,每一行程式碼、每一張圖片、每一個技術檔案都反覆核准,優化再優化,精益求精。為確保系統執行得更高效,我們將一張圖片從1MB壓縮到500KB,再從500KB優化到100KB。
這樣的工作在外人看起來,簡單到就好像悄悄給學妹塞一張情書就能讓她做我女朋友一樣簡單。
但殊不知,這其中蘊含著極高的技術含量!
不信,我給你們普及下。
影象壓縮是資料壓縮技術在數位影像上的應用,目的是減少影象資料中的冗餘資訊,從而用更加高效的格式儲存和傳輸資料。
影象壓縮可以是有損資料壓縮,也可以是無失真資料壓縮。
怎麼樣?
是不是感覺影象壓縮技術沒有想象中那麼簡單了?
更多關於影象壓縮的資料可參考以下連結。
https://www.jb51.net/article/150789.htm
作為這次“20 多萬外包專案”的“主力開發人員”,我這裡就給大家介紹下 Java 數位影像處理技術吧,一開始我就是用它來處理圖片的。
數位影像處理(Digital Image Processing)是通過計算機對影象進行去除噪聲、增強、復原、分割、提取特徵等處理的方法和技術。
輸入的是影象訊號,然後經過 DIP 進行有效的演演算法處理後,輸出為數位訊號。
為了壓縮影象,我們需要讀取影象並將其轉換成 BufferedImage 物件,BufferedImage 是 Image 類的一個子類,描述了一個具有可存取的影象資料緩衝區,由 ColorModel 和 Raster 的影象資料組成。
廢話我就不多說了,直接進入實戰吧!
剛好我本地有一張之前用過的封面圖,離 1M 只差 236 KB,可以拿來作為測試用。
這其中要用到 ImageIO 類,這是一個靜態類,提供了一系列方法用來讀和寫影象,同時還可以對影象進行簡單的編碼和解碼。
比如說通過 ImageIO.read()
可以將影象讀取到 BufferedImage 物件:
File input = new File("ceshi.jpg"); BufferedImage image = ImageIO.read(input);
比如說通過 ImageIO.getImageWritersByFormatName()
可以返回一個Iterator,其中包含了通過命名格式對影象進行編碼的 ImageWriter。
Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("jpg"); ImageWriter writer = (ImageWriter) writers.next();
比如說通過 ImageIO.createImageOutputStream()
可以建立一個影象的輸出流物件,有了該物件後就可以通過 ImageWriter.setOutput()
將其設定為輸出流。
File compressedImageFile = new File("bbcompress.jpg"); OutputStream os =new FileOutputStream(compressedImageFile); ImageOutputStream ios = ImageIO.createImageOutputStream(os); writer.setOutput(ios);
緊接著,可以對 ImageWriter 進行一些引數設定,比如說壓縮模式,壓縮質量等等。
ImageWriteParam param = writer.getDefaultWriteParam(); param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); param.setCompressionQuality(0.01f);
壓縮模式一共有四種,MODE_EXPLICIT 是其中一種,表示 ImageWriter 可以根據後續的 set 的附加資訊進行平鋪和壓縮,比如說接下來的 setCompressionQuality()
方法。
setCompressionQuality()
方法的引數是一個 0-1 之間的數,0.0 表示盡最大程度壓縮,1.0 表示保證影象質量很重要。對於有失真壓縮方案,壓縮質量應該控制檔案大小和影象質量之間的權衡(例如,通過在寫入 JPEG 影象時選擇量化表)。 對於無失真方案,壓縮質量可用於控制檔案大小和執行壓縮所需的時間之間的權衡(例如,通過優化行過濾器並在寫入 PNG 影象時設定 ZLIB 壓縮級別)。
整體程式碼如下所示:
public class Demo { public static void main(String[] args) { try { File input = new File("ceshi.jpg"); BufferedImage image = ImageIO.read(input); Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("jpg"); ImageWriter writer = (ImageWriter) writers.next(); File compressedImageFile = new File("bbcompress.jpg"); OutputStream os = new FileOutputStream(compressedImageFile); ImageOutputStream ios = ImageIO.createImageOutputStream(os); writer.setOutput(ios); ImageWriteParam param = writer.getDefaultWriteParam(); param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); param.setCompressionQuality(0.01f); writer.write(null, new IIOImage(image, null, null), param); os.close(); ios.close(); writer.dispose(); } catch (IOException e) { e.printStackTrace(); } } }
執行壓縮後,可以看到圖片的大小壓縮到了 19 KB:
可以看得出,質量因子為 0.01f 的時候圖片已經有些失真了,可以適當提高質量因子比如說 0.5f,再來看一下。
圖片質量明顯提高了,但大小依然只有 64 KB,壓縮效果還是值得信賴的。
接下來,推薦一些可以輕鬆整合到專案中的影象處理庫吧,它們全都是免費的。
1)ImageJ,用 Java 編寫的,可以編輯、分析、處理、儲存和列印影象。
2)Apache Commons Imaging,一個讀取和寫入各種影象格式的庫,包括快速解析影象資訊(如大小,顏色,空間,ICC組態檔等)和後設資料。
3)ImageMagick,可以讀取和寫入超過100種格式的影象,包括DPX、EXR、GIF、JPEG、JPEG-2000、PDF、PNG、Postscript、SVG和TIFF。還可以調整大小、翻轉、映象、旋轉、扭曲、剪下和變換影象,調整影象顏色,應用各種特殊效果,包括繪製文字、線條、多邊形、橢圓和貝塞爾曲線。
4)OpenCV,由BSD許可證釋出,可以免費學習和商業使用,提供了包括 C/C++、Python 和 Java 等主流程式語言在內的介面。OpenCV 專為計算效率而設計,強調實時應用,可以充分發揮多核處理器的優勢。
這裡就以 OpenCV 為例,來演示一下影象壓縮。當然了,OpenCV 用來壓縮影象屬於典型的大材小用。
第一步,新增 OpenCV 依賴到我們的專案當中,以 Maven 為例。
<dependency> <groupId>org.openpnp</groupId> <artifactId>opencv</artifactId> <version>4.5.1-2</version> </dependency>
第二步,要想使用 OpenCV,需要先初始化。
OpenCV.loadShared();
第三步,使用 OpenCV 讀取圖片。
Mat src = Imgcodecs.imread(imagePath);
第四步,使用 OpenCV 壓縮圖片。
MatOfInt dstImage = new MatOfInt(Imgcodecs.IMWRITE_JPEG_QUALITY, 1); Imgcodecs.imwrite("resized_image.jpg", sourceImage, dstImage);
MatOfInt 的構造引數是一個可變引數,第一個引數 IMWRITE_JPEG_QUALITY 表示對圖片的質量進行改變,第二個是質量因子,1-100,值越大表示質量越高。
執行程式碼後得到的圖片如下所示:
借這個機會,來對比下 OpenCV 和 JDK 原生 API 在壓縮影象時所使用的時間。
這是我本機的設定情況,早年買的頂配 iMac,也是我的主力機。一開始只有 16 G 記憶體,後來加了一個 16 G 記憶體條,不過最近半年電腦突然宕機重啟的頻率明顯提高了,不知道是不是 Big Sur 這個作業系統的問題還是電腦硬體老了。
結果如下所示:
opencvCompress壓縮完成,所花時間:1070
jdkCompress壓縮完成,所花時間:322
壓縮後的圖片大小差不多,都是 19 KB,並且質量因子都是最低值。
經過上面的技術分析後,相信你們都明白了,把1M圖片優化到100kb實在是一件“不太容易”的事情。。。。
100KB 很小了吧?只有原來的 1/10。
要知道,我可是連續加班了兩天兩夜,不眠不休。
累到最後,我趴在電腦上都睡著了。
沒想到哈喇子直接給電腦整短路了,我這才算是從夢裡面嚇醒來了!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45