近日在制作一个网站(http://campus.cslg.cn)的过程中,对于校友录的相册部分需要生成缩略图。很多网站上为了改变图像的大小,往往直接指定<img>标记中的width和height属性,造成图像变形,效果惨不忍睹。
在网上搜索资料的过程中,找到了一篇比较好的讲 Java 2D图像处理的文章 Ultimate Java Image Manipulation (http://www.javalobby.org/articles/ultimate-image/#11)
在该作者提供的代码的基础上,增加了按照指定高度或者宽度缩放图像的方法,解决了图像显示的问题
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
public class ImageUtil {
/**
* 从磁盘文件装载图像
*
* @param ref
* @return
*/
public static BufferedImage loadImage(String ref) {
BufferedImage bimg = null;
try {
bimg = ImageIO.read(new File(ref));
} catch (Exception e) {
e.printStackTrace();
}
return bimg;
}
/**
* 将图像改为新的宽度和高度
*
* @param img
* @param newWidth
* @param newHeight
* @return
*/
public static BufferedImage resize(BufferedImage img, int newWidth,
int newHeight) {
int w = img.getWidth();
int h = img.getHeight();
BufferedImage dimg = new BufferedImage(newWidth, newHeight, img
.getType());
Graphics2D g = dimg.createGraphics();
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.drawImage(img, 0, 0, newWidth, newHeight, 0, 0, w, h, null);
g.dispose();
return dimg;
}
/**
* 将图像改为新的宽度
*
* @param img
* @param newWidth
* @return
*/
public static BufferedImage resizeWithNewWidth(BufferedImage img,
int newWidth) {
int w = img.getWidth();
int h = img.getHeight();
int newHeight = (int) ((double) h * newWidth / w);
BufferedImage dimg = new BufferedImage(newWidth, newHeight, img
.getType());
Graphics2D g = dimg.createGraphics();
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.drawImage(img, 0, 0, newWidth, newHeight, 0, 0, w, h, null);
g.dispose();
return dimg;
}
/**
* 将图像改为新的高度
*
* @param img
* @param newHeight
* @return
*/
public static BufferedImage resizeWithNewHeight(BufferedImage img,
int newHeight) {
int w = img.getWidth();
int h = img.getHeight();
int newWidth = (int) ((double) w * newHeight / h);
BufferedImage dimg = new BufferedImage(newWidth, newHeight, img
.getType());
Graphics2D g = dimg.createGraphics();
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.drawImage(img, 0, 0, newWidth, newHeight, 0, 0, w, h, null);
g.dispose();
return dimg;
}
public static void saveImage(String ref, BufferedImage img) {
BufferedOutputStream out;
try {
out = new BufferedOutputStream(new FileOutputStream(ref));
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(img);
int quality = 5;
quality = Math.max(0, Math.min(quality, 100));
param.setQuality((float) quality / 100.0f, false);
encoder.setJPEGEncodeParam(param);
encoder.encode(img);
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Saves a BufferedImage to the given file, pathname must not have any
* periods "." in it except for the one before the format, i.e.
* C:/images/fooimage.png
*
* @param img
* @param saveFile
*/
public static void saveImage(BufferedImage img, String ref) {
try {
String format = (ref.endsWith(".png")) ? "png" : "jpg";
ImageIO.write(img, format, new File(ref));
} catch (IOException e) {
e.printStackTrace();
}
}
public static BufferedImage loadTranslucentImage(String url,
float transperancy) {
// Load the image
BufferedImage loaded = loadImage(url);
// Create the image using the
BufferedImage aimg = new BufferedImage(loaded.getWidth(), loaded
.getHeight(), BufferedImage.TRANSLUCENT);
// Get the images graphics
Graphics2D g = aimg.createGraphics();
// Set the Graphics composite to Alpha
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
transperancy));
// Draw the LOADED img into the prepared reciver image
g.drawImage(loaded, null, 0, 0);
// let go of all system resources in this Graphics
g.dispose();
// Return the image
return aimg;
}
public static BufferedImage makeColorTransparent(String ref, Color color) {
BufferedImage image = loadImage(ref);
BufferedImage dimg = new BufferedImage(image.getWidth(), image
.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g = dimg.createGraphics();
g.setComposite(AlphaComposite.Src);
g.drawImage(image, null, 0, 0);
g.dispose();
for (int i = 0; i < dimg.getHeight(); i++) {
for (int j = 0; j < dimg.getWidth(); j++) {
if (dimg.getRGB(j, i) == color.getRGB()) {
dimg.setRGB(j, i, 0x8F1C1C);
}
}
}
return dimg;
}
public static BufferedImage horizontalflip(BufferedImage img) {
int w = img.getWidth();
int h = img.getHeight();
BufferedImage dimg = new BufferedImage(w, h, img.getType());
Graphics2D g = dimg.createGraphics();
g.drawImage(img, 0, 0, w, h, w, 0, 0, h, null);
g.dispose();
return dimg;
}
public static BufferedImage verticalflip(BufferedImage img) {
int w = img.getWidth();
int h = img.getHeight();
BufferedImage dimg = new BufferedImage(w, h, img.getColorModel()
.getTransparency());
Graphics2D g = dimg.createGraphics();
g.drawImage(img, 0, 0, w, h, 0, h, w, 0, null);
g.dispose();
return dimg;
}
public static BufferedImage rotate(BufferedImage img, int angle) {
int w = img.getWidth();
int h = img.getHeight();
BufferedImage dimg = new BufferedImage(w, h, img.getType());
Graphics2D g = dimg.createGraphics();
g.rotate(Math.toRadians(angle), w / 2, h / 2);
g.drawImage(img, null, 0, 0);
return dimg;
}
public static BufferedImage[] splitImage(BufferedImage img, int cols,
int rows) {
int w = img.getWidth() / cols;
int h = img.getHeight() / rows;
int num = 0;
BufferedImage imgs[] = new BufferedImage[w * h];
for (int y = 0; y < rows; y++) {
for (int x = 0; x < cols; x++) {
imgs[num] = new BufferedImage(w, h, img.getType());
// Tell the graphics to draw only one block of the image
Graphics2D g = imgs[num].createGraphics();
g.drawImage(img, 0, 0, w, h, w * x, h * y, w * x + w,
h * y + h, null);
g.dispose();
num++;
}
}
return imgs;
}
}
下面是用于改变图像大小的Servlet (使用格式: <img src="servlet/ImageResize?id=1&width=200&height=150"/>;可以指定高度、宽度或者宽度和高度)
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javax.naming.NamingException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.cslg.campus.database.DBPoolException;
import cn.cslg.campus.database.JndiBean;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
public class ImageResize extends HttpServlet {
private static final long serialVersionUID = -8774962472747611326L;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("image/jpeg");
int id = 0;
int height = 0;
int width = 0;
try {
try {
id = Integer.parseInt(request.getParameter("id"));
String h = request.getParameter("height");
String w = request.getParameter("width");
if (h != null && h.length() != 0)
height = Integer.parseInt(h);
if (w != null && w.length() != 0)
width = Integer.parseInt(w);
} catch (NumberFormatException e) {
return;
}
BufferedImage image = loadImage(id, width, height);
ServletOutputStream out = response.getOutputStream();
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
encoder.encode(image);
out.close();
} catch (Exception e) {
throw new ServletException(e);
}
}
public BufferedImage loadCachedImage(String fname, int width, int height)
throws DBPoolException, NamingException, SQLException {
BufferedImage image = null;
ServletContext application = this.getServletContext();
String folder = application.getRealPath("/photo/thumbnail");
String ext = fname.substring(fname.lastIndexOf('.'));
String pre = fname.substring(0, fname.lastIndexOf('.'));
String cachedName = folder + "/" + pre + "-" + width + "-" + height
+ ext;
File f = new File(cachedName);
if (f.exists())
image = ImageUtil.loadImage(cachedName);
return image;
}
public void saveCachedImage(BufferedImage image, String fname, int width,
int height) {
ServletContext application = this.getServletContext();
String folder = application.getRealPath("/photo/thumbnail");
String ext = fname.substring(fname.lastIndexOf('.'));
String pre = fname.substring(0, fname.lastIndexOf('.'));
String cachedName = folder + "/" + pre + "-" + width + "-" + height
+ ext;
ImageUtil.saveImage(image, cachedName);
}
public BufferedImage loadImage(int id, int width, int height)
throws DBPoolException, NamingException, SQLException {
ServletContext application = this.getServletContext();
String uploadFolder = application.getRealPath("/photo");
BufferedImage image = null;
Connection conn = null;
try {
conn = JndiBean.getConnection();
String sql = "select FileName from Album where PhotoId=" + id;
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql);
if (!rs.next())
return null;
String fname = rs.getString("FileName").trim();
String pname = uploadFolder + "/" + fname;
image = loadCachedImage(fname, width, height);
if (image == null) {
if (height != 0 && width != 0) {
image = ImageUtil.resize(ImageUtil.loadImage(pname), width,
height);
} else if (height != 0 && width == 0)
image = ImageUtil.resizeWithNewHeight(ImageUtil
.loadImage(pname), height);
else if (height == 0 && width != 0)
image = ImageUtil.resizeWithNewWidth(ImageUtil
.loadImage(pname), width);
saveCachedImage(image, fname, width, height);
}
return image;
} finally {
conn.close();
}
}
}
没有评论:
发表评论