我们正在构建一个处理图片上传的应用程序。我希望用户能够以给定的大小上传图像,比如128x128,然后让服务器自动生成其他大小,例如64x64,57x57和25x25。
是否有图书馆可以帮助我解决这个问题?
编辑:我应该注意,调整大小只应在上传时进行。当在浏览器中呈现新的图像大小时,它应该从缓存的副本中拉出 - 而不是再次调整大小。换句话说,不应该只生成一次不同的尺寸,而不是每次请求图像。
答案 0 :(得分:2)
This可能会有所帮助。 AFAIK,有多种方法可以做到这一点,具有不同的速度/图像质量。
答案 1 :(得分:2)
我已经使用ImageIO和ImageInfo库来实现类似的功能。到目前为止它们还算不错。
http://java.sun.com/javase/6/docs/api/javax/imageio/ImageIO.html
http://kickjava.com/src/imageinfo/ImageInfo.java.htm
我记得在获取图像大小时因本机java库存在一些性能问题,因此不得不使用ImageInfo。
希望这有帮助。
答案 2 :(得分:2)
乔希,
这正是我为imgscalr写的this app(Apache 2)所做的 - 到目前为止,从世界各地处理了几十万张图片并且没有报告损坏的结果。
当我第一次开始研究Java中的图像缩放(对于那个项目)时,我看到了你在这里搜索的内容...... 200个问题同样的问题,50个不同的方法,25个“错误”显然还有很多头痛。
我真的很喜欢解决这样的问题,所以我坐下来收集所有反馈,所有错误报告,所有提示,所有技巧以及人们遇到的所有问题,并将它们全部编译成超级简单,1-class API只为你做“一切正常”。
最简单的API用例如下所示:
BufferedImage scaledImg = Scalr.resize(img, 150);
但是考虑到你想要做一些非常小的不同尺寸,你需要使用QUALITY缩放方法,该方法采用Chris Campbell(Java2D团队)推荐的增量缩放技术并将预定义的ConvolveOp应用于缩小缩略图的结果因为它太小了。
示例:
BufferedImage img = ImageIO.read(...); // load image
BufferedImage scaledImg = Scalr.resize(img, Method.QUALITY,
50, Scalr.OP_ANTIALIAS);
如果你不想要,你不需要同时提供w / h,图像的比例总是得到尊重,并且边界用作边界框以确保图像至少适合它(但永远不会违反图像的比例这样做。)
如果你曾经使用过ConvolveOps尝试软化图像,你就会知道找到合适的内核,它看起来很好但又足够柔软以摆脱锯齿,你知道这是一个皇家PIA - 我在图书馆中predefined的一个结果是与巴西社交网站合作一周的结果,该网站使用图书馆来扩展个人资料图片,我认为我们已将其钉在上面。
当然你可以用它作为一个起点并提供你自己的,Scalr类允许你传递任何BufferedImageOp,它将自动应用于生成的缩放图像(并且可以在6年内工作) -old导致图像损坏的JDK错误。)
该库还为您提供了一系列其他“最佳实践”内容,例如确保尽快刷新增量映像以保持内存使用率并且不会丢弃VM,始终保持最佳映像 - 支持的图像类型,因此Java2D中的软件管道从未使用过(如果您使用手动代码,人们上传GIF时可能已经注意到它,最终看起来像垃圾 - imgscalr修复此问题)以及其他一些适合的区域我对“只做一切正确”的图书馆的要求。
希望有所帮助。
答案 3 :(得分:0)
来自a related source in the Swing tutorial:
/**
* Resizes an image using a Graphics2D object backed by a BufferedImage.
* @param srcImg - source image to scale
* @param w - desired width
* @param h - desired height
* @return - the new resized image
*/
private Image getScaledImage(Image srcImg, int w, int h){
BufferedImage resizedImg = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = resizedImg.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.drawImage(srcImg, 0, 0, w, h, null);
g2.dispose();
return resizedImg;
}
答案 4 :(得分:0)
来自我们的一个java门户页面的实用程序功能 (从几个论坛的例子编码,我不声称是作者)
希望这有帮助 Guillaume PATRY
/**
* Convenience method that returns a scaled instance of the
* provided {@code BufferedImage}.
*
* @param img the original image to be scaled
* @param targetWidth the desired width of the scaled instance,
* in pixels
* @param targetHeight the desired height of the scaled instance,
* in pixels
* @param hint one of the rendering hints that corresponds to
* {@code RenderingHints.KEY_INTERPOLATION} (e.g.
* {@code RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR},
* {@code RenderingHints.VALUE_INTERPOLATION_BILINEAR},
* {@code RenderingHints.VALUE_INTERPOLATION_BICUBIC})
* @param higherQuality if true, this method will use a multi-step
* scaling technique that provides higher quality than the usual
* one-step technique (only useful in downscaling cases, where
* {@code targetWidth} or {@code targetHeight} is
* smaller than the original dimensions, and generally only when
* the {@code BILINEAR} hint is specified)
* @return a scaled version of the original {@code BufferedImage}
*/
public BufferedImage getScaledInstance(
BufferedImage img,
int targetWidth,
int targetHeight,
Object hint,
boolean higherQuality) {
BufferedImage ret = (BufferedImage) img;
int w, h;
if (higherQuality) {
// Use multi-step technique: start with original size, then
// scale down in multiple passes with drawImage()
// until the target size is reached
w = img.getWidth();
h = img.getHeight();
} else {
// Use one-step technique: scale directly from original
// size to target size with a single drawImage() call
w = targetWidth;
h = targetHeight;
}
do {
if (higherQuality) {
if (w > targetWidth) {
w /= 2;
if (w < targetWidth) {
w = targetWidth;
}
} else {
w = targetWidth;
}
if (h > targetHeight) {
h /= 2;
if (h < targetHeight) {
h = targetHeight;
}
} else {
h = targetHeight;
}
}
BufferedImage tmp = null;
if (img.getType() == 0) {
tmp = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
} else {
tmp = new BufferedImage(w, h, img.getType());
}
Graphics2D g2 = tmp.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
g2.drawImage(ret, 0, 0, w, h, null);
g2.dispose();
ret = tmp;
} while (w != targetWidth || h != targetHeight);
return ret;
}