相信逛過淘寶的都知道,同一張圖片,展示在不同的地方,尺寸是不同的,如果強制對原圖進行拉伸,有可能會變形,影響視覺效果,在這種情況下,對同一張圖片,根據需要,生成不同的縮略圖,需要的時候再調用,就可以很好的解決這一問題。下面通過一個實例來詳細的說明一下這種情況:
下圖是百度圖片廣場的列表頁:
列表頁 圖-1
通過Chrome瀏覽器,我們可以看到,在這里這張圖片所占的大小為188px X 188px(列表頁 圖-2),也就是此時只需要188px X 188px大小的圖片就足夠了,如果將原圖500px X 500px的圖片強制壓縮放在這里,是可以展示出來,但是加載的卻是原來的大圖,對於用戶的流量來說,這就浪費了很大一部分,如果網速不給力的話,加載也會非常的慢。當我們點擊這張圖片的時候,會進入二級列表頁,這里的尺寸又會不一樣(二級列表 圖-3),當我們再點進去之后就會到詳細頁面,這里展示的又是另外一個尺寸(詳細頁 圖-4)。
列表頁 圖-2
二級列表 圖-3
詳細頁 圖-4
稍微細心一點你也可以發現,每張圖片顯示的都很合適,沒有明顯的拉伸或者壓縮的現象,這就用到了我們今天所說的縮略圖。當然,這只是作者自己做的一個小Demo,里邊肯定會有很多不足的地方,也會有很多考慮不周的地方,如果願意分享一下您瀏覽之后的感想,十分感謝。
先說一下大致的思路:首先選定一個文件夾,找出里邊所有的圖片文件,然后再根據需要生成縮略圖的尺寸和生成縮略圖的模式,生成縮略圖文件,然后保存到指定的路徑下。這里需要說明一下的就是生成縮略圖的模式,既然是縮略圖,肯定和原圖的尺寸不一樣,根據不同的模式,裁剪的方式也不一樣。本文中共提出了5中縮略圖,實際中您可以根據自己的情況,增加需要或者刪除不需要的縮略圖模式。以下是五種生成縮略圖的模式:
1、自動縮放:如果需要生成縮略圖的寬度比高度大,那么效果跟第二種模式產生的效果一樣;如果寬度比高度小,則效果跟第三種模式產生的效果一樣。
2、指定寬高按比例:這種模式下,寬度即為需要生成的圖片寬度,高度為需要生成的縮略圖的寬度與原圖寬度的比再乘以需要生成的縮略圖的高度。
3、指定高寬按比例:這種模式證號和第二種模式相反,高度一定,寬度乘以比值。
4、指定高寬縮放:按照指定的尺寸生成縮略圖。
5、指定高寬裁剪:指定高,把兩邊的寬裁剪掉。
這里示例就采用傳統的WebForm的方式來做演示,也可以用MVC來實現。這里新建了一個WebApplication項目,如圖-5,里邊包含一個頁面展示頁面,一個縮略圖模式的枚舉,一個生成縮略圖的Handler,一個JQuery腳本(用來提交數據)。這里值得注意的就是,Handler需要在WebConfig里做配置,才能生效。還有一點就是,會默認調用Handler里的ProcessRequest方法,只需要將生成縮略圖的代碼放到這個Request方法里就可以了。
圖-5
由於僅僅只是做演示,所以這里忽略掉了樣式,元素只是簡單地疊加,並沒有美化。開始界面如圖-6:
圖-6
以下是定義的枚舉:

public enum MakeThumbnailMode { Auto,//自動裁剪模式 W,//指定寬,高按比例 H, //指定高,寬按比例 HW,//指定高,寬縮放 Cut//指定寬,高裁剪 }
以下部分是生成縮略圖的兩個關鍵方法:

static Bitmap getThumBitmap(Image originalImage, int width, int height, MakeThumbnailMode mode, out Graphics graphics) { Bitmap bitmap; int thumbWidth = width; int thumbHeight = height; int x = 0; int y = 0; int originalWidth = originalImage.Width; int originalHeight = originalImage.Height; if (mode == MakeThumbnailMode.Auto) { if (thumbWidth > thumbHeight) { mode = MakeThumbnailMode.W; } else { mode = MakeThumbnailMode.H; } } if (originalHeight < thumbHeight && originalWidth < thumbWidth) { thumbWidth = originalWidth; thumbHeight = originalHeight; } switch (mode) { case MakeThumbnailMode.W: thumbHeight = originalHeight * width / originalWidth; break; case MakeThumbnailMode.H: thumbWidth = originalWidth * height / originalHeight; break; case MakeThumbnailMode.HW: break; case MakeThumbnailMode.Cut: if ((double)originalWidth / (double)originalHeight>(double)width / (double)height) { originalHeight = originalImage.Height; originalWidth = width * originalHeight / height; y = 0; x = (originalWidth - width) / 2; } else { originalWidth = originalImage.Width; originalHeight = height * originalWidth / width; x = 0; y = (originalHeight - height) / 2; } break; } bitmap = new Bitmap(thumbWidth, thumbHeight); bitmap.MakeTransparent(Color.Transparent); graphics = Graphics.FromImage(bitmap); graphics.Clear(Color.Transparent); graphics.DrawImage(originalImage, new Rectangle(0, 0, thumbWidth, thumbHeight), new Rectangle(x, y, originalWidth, originalHeight), GraphicsUnit.Pixel); return bitmap; }

static void MakeThumbPic(string originalImagePath, string thumbnailPath, int width, int height, MakeThumbnailMode mode, ImageFormat imageFormat) { using (Image image = Image.FromFile(originalImagePath)) { Graphics graphics; Bitmap bitmap = getThumBitmap(image, width, height, mode, out graphics); try { bitmap.Save(thumbnailPath, imageFormat); } catch (Exception) { throw; } } }
然后在ProcessRequest方法里調用MakeThumbPic方法,即可生成縮略圖了。由於代碼都不是太難,所以這里就給出一個思路,詳細的代碼就不敲了,有需要的可以發郵箱。通過context上下文獲取到提交過來的數據,然后遍歷圖片文件,獲得所有的圖片文件,然后循環,每張圖片都調用生成縮略圖的makeThumbpic方法,即可生成需要的縮略圖了。
如您有任何的建議和看法,歡迎和我聯系,大家一起學習,一起進步,謝謝!