我們在實際項目開發過程中,曾經遇到過一個需求,就是要開發一個對大量圖檔進行整理(删除掉一些不符合要求的圖檔)、歸類(根據格式進行分類,比如jpg格式、bmp格式等)、壓縮(因為有的圖檔很大很占空間,看能否在保證清晰可辨、尺寸适中的前提下,适當的壓縮掉一部分空間)的小程式。這裡隻是重點分享一下如何對圖檔進行壓縮。
我們也不是水準非常高的圖像處理專家,但是實際項目中又有這個需求,作為普通的程式員應該如何滿足這個要求呢?
很顯然,最簡單的思路就是适當的縮小原圖的尺寸大小或者是适當的降低原圖的品質要求,這樣就能有效地降低原圖所占的空間。
先上一個程式的截圖:

我們通過選擇圖檔的原目錄以及目标目錄,設定好壓縮大小和壓縮品質,點選開始壓縮按鈕,即可進行批量圖檔壓縮。
在圖檔的原目錄選擇當中,能夠周遊根目錄下的所有圖檔(包括子目錄下的圖檔)。
好了,很簡單的一個界面,下面我們直接上幾段核心代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<code>/// <summary></code>
<code>/// 壓縮圖檔方法</code>
<code>/// </summary></code>
<code>/// <param name="sourcePath">原目錄</param></code>
<code>/// <param name="targetPath">目标目錄</param></code>
<code>/// <returns>壓縮是否成功</returns></code>
<code>private</code> <code>bool</code> <code>CompressPicture(</code><code>string</code> <code>sourcePath, </code><code>string</code> <code>targetPath)</code>
<code>{</code>
<code> </code><code>try</code>
<code> </code><code>{</code>
<code> </code><code>double</code> <code>sizeRate = </code><code>double</code><code>.Parse(cbSizeRate.Text) / 100;</code><code>// 大小比率</code>
<code> </code><code>int</code> <code>qualityRate = </code><code>int</code><code>.Parse(cbQualityRate.Text);</code><code>// 品質比率</code>
<code> </code>
<code> </code><code>Image sourceImage = Image.FromFile(sourcePath);</code>
<code> </code><code>//調整圖檔大小</code>
<code> </code><code>Bitmap bmp = </code><code>new</code> <code>Bitmap(sourceImage, </code><code>new</code> <code>Size((</code><code>int</code><code>)(sourceImage.Width * sizeRate), (</code><code>int</code><code>)(sourceImage.Height * sizeRate)));</code>
<code> </code><code>//壓縮圖檔</code>
<code> </code><code>SaveAsJPEG(bmp, targetPath, qualityRate);</code>
<code> </code><code>GC.Collect();</code>
<code> </code><code>return</code> <code>true</code><code>;</code>
<code> </code><code>}</code>
<code> </code><code>catch</code>
<code> </code><code>return</code> <code>false</code><code>;</code>
<code>}</code>
28
<code>/// 儲存為JPEG格式,支援壓縮品質選項</code>
<code>/// <param name="bmp">原始位圖</param></code>
<code>/// <param name="FileName">新檔案位址</param></code>
<code>/// <param name="Qty">壓縮品質,越大越好,檔案也越大(0-100)</param></code>
<code>/// <returns>成功标志</returns></code>
<code>public</code> <code>static</code> <code>bool</code> <code>SaveAsJPEG(Bitmap bmp, </code><code>string</code> <code>FileName, </code><code>int</code> <code>Qty)</code>
<code> </code><code>EncoderParameter p;</code>
<code> </code><code>EncoderParameters ps;</code>
<code> </code>
<code> </code><code>ps = </code><code>new</code> <code>EncoderParameters(1);</code>
<code> </code><code>p = </code><code>new</code> <code>EncoderParameter(System.Drawing.Imaging.Encoder.Quality, Qty);</code>
<code> </code><code>ps.Param[0] = p;</code>
<code> </code><code>bmp.Save(FileName, GetCodecInfo(</code><code>"image/jpeg"</code><code>), ps);</code>
<code>/// 儲存JPG時用</code>
<code>/// <param name="mimeType"></param></code>
<code>/// <returns>得到指定mimeType的ImageCodecInfo</returns></code>
<code>private</code> <code>static</code> <code>ImageCodecInfo GetCodecInfo(</code><code>string</code> <code>mimeType)</code>
<code> </code><code>ImageCodecInfo[] CodecInfo = ImageCodecInfo.GetImageEncoders();</code>
<code> </code><code>foreach</code> <code>(ImageCodecInfo ici </code><code>in</code> <code>CodecInfo)</code>
<code> </code><code>if</code> <code>(ici.MimeType == mimeType) </code><code>return</code> <code>ici;</code>
<code> </code><code>return</code> <code>null</code><code>;</code>
<code>/// 周遊檔案</code>
<code>/// <param name="info"></param></code>
<code>public</code> <code>void</code> <code>ListFiles(FileSystemInfo info)</code>
<code> </code><code>if</code> <code>(!info.Exists) </code><code>return</code><code>;</code>
<code> </code><code>DirectoryInfo dir = info </code><code>as</code> <code>DirectoryInfo;</code>
<code> </code><code>if</code> <code>(dir == </code><code>null</code><code>) </code><code>return</code><code>;</code>
<code> </code><code>FileSystemInfo[] files = dir.GetFileSystemInfos();</code>
<code> </code><code>for</code> <code>(</code><code>int</code> <code>i = 0; i < files.Length; i++)</code>
<code> </code><code>FileInfo file = files[i] </code><code>as</code> <code>FileInfo;</code>
<code> </code><code>if</code> <code>(file != </code><code>null</code> <code>&& file.Name.Trim().LastIndexOf(</code><code>"."</code><code>) > -1)</code>
<code> </code><code>{</code>
<code> </code><code>if</code> <code>(file.Name.Substring(file.Name.LastIndexOf(</code><code>"."</code><code>)).ToUpper() == </code><code>".JPG"</code><code>)</code>
<code> </code><code>{</code>
<code> </code><code>this</code><code>.lvSourceFolderList.Items.Add(file.FullName);</code>
<code> </code><code>imageList.Add(file.FullName);</code>
<code> </code><code>}</code>
<code> </code><code>}</code>
<code> </code><code>else</code>
<code> </code><code>ListFiles(files[i]); </code><code>//對于子目錄,進行遞歸調用</code>
本文轉自 guwei4037 51CTO部落格,原文連結:http://blog.51cto.com/csharper/1330029