一套完整的生成缩略图及点击缩略图显示原图的解决方案

一套完整的生成缩略图及点击缩略图显示原图的解决方案

实例https://kangyonggan.com/album

使用缩略图的优点可以减轻服务器压力,给用户更好的体验。一个界面可能有很多图片,但是用户关心的图片可能只有那么一两个,如果我们加载全部原图,并且原图很大的时候,会浪费很多服务器资源,并且用户会看见大量图片处于加载中(如下图)。如果使用缩略图,就可以解决这个问题。

如何生成缩略图如果只是简单的生成缩略图,方法有很多,但是如何生成一个”好看”的缩略图呢?先捋一下思路,如下:

仅压缩如果强行把一个长图压缩成宽图,就可能导致图片中的人变矮变胖。

仅剪裁如果把一个大图,比如:800x2000的图,剪裁成400x300的图,可能图片中的主要内容根本都显示出来。

剪裁中心区域一般来说,图片中心是主要内容,我们剪裁中心区域400x300的图。

等比例压缩后再剪裁中心区域虽然好了很多,但是还有一个明显的问题,那就是图片包含的内容太少了,因此我先把原图等比例压缩成400x1000的图片,在剪裁中心区域的400x300。

注意:如果是宽图,先把高度压成300,再把宽度等比例压缩,最后剪裁中心区域。

java代码实现1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980package com.kangyonggan.app.util;import javax.imageio.ImageIO;import java.awt.geom.AffineTransform;import java.awt.image.AffineTransformOp;import java.awt.image.BufferedImage;import java.io.FileInputStream;import java.io.FileOutputStream;/** * @author kangyonggan * @date 6/23/17 */public final class Images { private Images() { } /** * 生成缩略图。 * * @param source 原图(大) * @param desc 目标图片 * @param width 目标宽 * @param height 目标高 * @throws Exception */ public static void thumb(String source, String desc, int width, int height) throws Exception { BufferedImage image = ImageIO.read(new FileInputStream(source)); // 判断原图的长宽比是不是比目标图的长宽比大,用于计算压缩后的宽和高 int pressWidth; int pressHeight; if (image.getHeight() * 1.0 / image.getWidth() > height * 1.0 / width) { // 原图是高图 // 让压缩后的宽度等于目标宽度 pressWidth = width; // 等比例计算高度 pressHeight = (int) (1.0 * image.getHeight() * width / image.getWidth()); } else { // 原图是宽图 // 让压缩后的高度等于目标高度 pressHeight = height; // 等比例计算高度 pressWidth = (int) (1.0 * image.getWidth() * height / image.getHeight()); } // 先压缩 BufferedImage temp = zoomImage(image, pressWidth, pressHeight); // 再截取 int x = (temp.getWidth() - width) / 2; int y = (temp.getHeight() - height) / 2; temp = temp.getSubimage(x, y, width, height); // 最后写文件 ImageIO.write(temp, "png", new FileOutputStream(desc)); } /** * 缩放图片 * * @param image * @param w * @param h * @throws Exception */ private static BufferedImage zoomImage(BufferedImage image, int w, int h) throws Exception { double wr = w * 1.0 / image.getWidth(); double hr = h * 1.0 / image.getHeight(); AffineTransformOp ato = new AffineTransformOp(AffineTransform.getScaleInstance(wr, hr), null); return ato.filter(image, null); } public static void main(String[] args) throws Exception { thumb("/Users/kyg/Desktop/origin.jpeg", "/Users/kyg/Desktop/demo.png", 400, 300); }}

上面过程仅是生成缩略图,当生成缩略图后,我们要在网站上展示缩略图,点击放大可查看原图。为此,我写了一个jQuery插件,如下。

zoomer的使用12345678910111213141516171819

zoomer.js源码123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176/** * 图片缩放 * * @author kangyonggan * @since 2017/3/21 */(function ($) { /** * 总入口 * * @param $target * @param settings */ function Zoomer($target, settings) { // 把settings的属性合并到defaults,并且不改变defaults settings = $.extend(true, $.fn.zoomer.defaults, settings); // 模态框图层 var $overlay = $(); // 全部图片 var $allImgs = $target.find("img"); // 修改光标 $allImgs.css("cursor", "zoom-in"); // 给每个img一个下标 for (var i = 0; i < $allImgs.length; i++) { $($allImgs[i]).data("index", i); } // 绑定点击事件 $allImgs.click(function () { showModal($(this)); }); /** * 显示模态框 * * @param $img */ function showModal($img) { $overlay.remove(); var src = $img.data('origin'); if (!src) { src = $img.attr('src'); } var index = $img.data("index"); $overlay = $('

' + '' + '' + '
加载中...
' + '
').css({ position: "fixed", left: 0, top: 0, bottom: 0, right: 0, color: '#fff', zIndex: 9999, cursor: 'zoom-out', background: 'rgba(0, 0, 0, 0.4)', textAlign: "center" }); $("body").append($overlay); // 图片加载完成事件 $overlay.find("img").load(function () { // 图片距离顶部的距离 var top = ($(window).height() - $(this).height()) / 2; // 图片距离左边的距离 var left = ($(window).width() - $(this).width()) / 2; // 上一张 $(this).parents("div").find(".zoomer-prev-img").css({ "display": "inline-block", "top": top + "px", "left": left + "px", "bottom": top + "px", "width": $(this).width() / 3 + "px" }).hover(function () { $(this).css({ background: "-webkit-linear-gradient(left, rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0))", background: "-o-linear-gradient(right, rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0))", background: "-moz-linear-gradient(right, rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0))", background: "linear-gradient(to right, rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0))" }) }, function () { $(this).css({ "background": "rgba(0, 0, 0, 0.0)" }) }); // 下一张 $(this).parents("div").find(".zoomer-next-img").css({ "display": "inline-block", "top": top + "px", "right": left + "px", "bottom": top + "px", "width": $(this).width() / 3 + "px" }).hover(function () { $(this).css({ background: "-webkit-linear-gradient(left, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.3))", background: "-o-linear-gradient(right, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.3))", background: "-moz-linear-gradient(right, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.3))", background: "linear-gradient(to right, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.3))" }) }, function () { $(this).css({ "background": "rgba(0, 0, 0, 0.0)" }) }); $(this).parents("div").find("div").css({"display": "none"}); $(this).css({"display": "inline-block", "marginTop": top + "px"}); }); // 图片加载失败事件 $overlay.find("img").error(function () { if (settings.failure && typeof settings.failure === 'function') { settings.failure($(this), $allImgs, $target, $overlay); } $(this).parents("div").find("div").html("加载失败!"); }); // 给模态框绑定点击事件 $overlay.click(function () { $overlay.remove(); }); // 上一张事件 $overlay.find(".zoomer-prev-img").click(function () { var index = $(this).data("index"); if (index === 0) { $overlay.remove(); return; } showModal($($allImgs[index - 1])); return false; }); // 下一张事件 $overlay.find(".zoomer-next-img").click(function () { var index = $(this).data("index"); if (index === $allImgs.length - 1) { $overlay.remove(); return; } showModal($($allImgs[index + 1])); return false; }); } } /** * 图片缩放 * * @param option * @returns {*} */ $.fn.zoomer = function (option) { return this.each(function () { $(this).data('zoomer', new Zoomer($(this), option)); }); }; /** * 默认配置 * * @type {{failure: null}} */ $.fn.zoomer.defaults = { // 图片加载失败回调 failure: null }})(window.jQuery);

zoomer下载zoomer.jszoomer.min.js

相关推荐

电脑快速打字技巧 - Type.fun在线打字练习
btbt365me

电脑快速打字技巧 - Type.fun在线打字练习

📅 08-13 👁️ 5517
「依伦/EREN品牌」依伦/EREN是哪个国家的品牌
123大写怎么写?人民币123元大写怎么写?
btbt365me

123大写怎么写?人民币123元大写怎么写?

📅 08-08 👁️ 3181
电脑中毒的症状有哪些 电脑中毒了怎么办
GBT36507-2018

电脑中毒的症状有哪些 电脑中毒了怎么办

📅 07-17 👁️ 1216
淘宝直播历史回放在哪里看?查看方法是什么?
365体育投注备用网站

淘宝直播历史回放在哪里看?查看方法是什么?

📅 07-25 👁️ 1389
正在阅读:YY频道设计符号大全YY频道设计符号大全