快速生成缩略图
相信逛过淘宝的都知道,同一张图片,展示在不同的地方,尺寸是不同的,如果强制对原图进行拉伸,有可能会变形,影响视觉效果,在这种情况下,对同一张图片,根据需要,生成不同的缩略图,需要的时候再调用,就可以很好的解决这一问题。下面通过一个实例来详细的说明一下这种情况:
下图是百度图片广场的列表页:
列表页 图-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方法,即可生成需要的缩略图了。
如您有任何的建议和看法,欢迎和我联系,大家一起学习,一起进步,谢谢!