如何在 Java 中从 JPEG 中创建缩略图?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1069095/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do you create a thumbnail image out of a JPEG in Java?
提问by
Can someone please help with some code for creating a thumbnail for a JPEG in Java.
有人可以帮忙用一些代码来为 Java 中的 JPEG 创建缩略图。
I'm new at this, so a step by step explanation would be appreciated.
我是新手,所以一步一步的解释将不胜感激。
回答by Savvas Dalkitsis
Image img = ImageIO.read(new File("test.jpg")).getScaledInstance(100, 100, BufferedImage.SCALE_SMOOTH);
This will create a 100x100 pixels thumbnail as an Image object. If you want to write it back to disk simply convert the code to this:
这将创建一个 100x100 像素的缩略图作为 Image 对象。如果要将其写回磁盘,只需将代码转换为:
BufferedImage img = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
img.createGraphics().drawImage(ImageIO.read(new File("test.jpg")).getScaledInstance(100, 100, Image.SCALE_SMOOTH),0,0,null);
ImageIO.write(img, "jpg", new File("test_thumb.jpg"));
Also if you are concerned about speed issues (the method described above is rather slow if you want to scale many images) use these methods and the following declaration :
此外,如果您担心速度问题(如果您想缩放许多图像,上述方法会相当慢),请使用这些方法和以下声明:
private BufferedImage scale(BufferedImage source,double ratio) {
int w = (int) (source.getWidth() * ratio);
int h = (int) (source.getHeight() * ratio);
BufferedImage bi = getCompatibleImage(w, h);
Graphics2D g2d = bi.createGraphics();
double xScale = (double) w / source.getWidth();
double yScale = (double) h / source.getHeight();
AffineTransform at = AffineTransform.getScaleInstance(xScale,yScale);
g2d.drawRenderedImage(source, at);
g2d.dispose();
return bi;
}
private BufferedImage getCompatibleImage(int w, int h) {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gd = ge.getDefaultScreenDevice();
GraphicsConfiguration gc = gd.getDefaultConfiguration();
BufferedImage image = gc.createCompatibleImage(w, h);
return image;
}
And then call :
然后调用:
BufferedImage scaled = scale(img,0.5);
where 0.5 is the scale ratio and img is a BufferedImage containing the normal-sized image.
其中 0.5 是缩放比例,img 是一个包含正常大小图像的 BufferedImage。
回答by mfloryan
The JMagicklibrary (and implementation of ImageMagickin Java) will have what you need.
该JMagick库(和执行的ImageMagick在Java中)将有你需要的东西。
回答by Kem Mason
the Java code above (with the scale / getCompatibleImage methods) worked great for me, but when I deployed to a server, it stopped working, because the server had no display associated with it -- anyone else with this problem can fix it by using: BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
上面的 Java 代码(使用 scale / getCompatibleImage 方法)对我来说非常有用,但是当我部署到服务器时,它停止工作,因为服务器没有与之关联的显示 - 遇到此问题的任何其他人都可以通过使用来修复它: BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
instead of BufferedImage bi = getCompatibleImage(w, h);
而不是 BufferedImage bi = getCompatibleImage(w, h);
and deleting the getCompatibleImage method
并删除 getCompatibleImage 方法
(later note -- it turns out this works great for most images, but I got a bunch from my companys marketing department that are 32 bit color depth jpeg images, and the library throws an unsupported image format exception for all of those :( -- imagemagick / jmagick are starting to look more appealing)
(稍后注意 - 事实证明这对大多数图像都非常有效,但是我从我公司的营销部门那里得到了一堆 32 位颜色深度 jpeg 图像,并且该库为所有这些图像抛出了一个不受支持的图像格式异常:( - - imagemagick / jmagick 开始看起来更有吸引力)
回答by Riyad Kalla
As you might have found out "easy" and "good looking result" are two very different things. I have encapsulated both of these requirements into a very simple java image scaling library(Apache 2 license) that just does everything right for you.
正如您可能已经发现的那样,“简单”和“好看的结果”是两种截然不同的东西。我已经将这两个要求封装到一个非常简单的java 图像缩放库(Apache 2 许可)中,它可以为您做一切正确的事情。
Example code to create a thumbnail looks like this:
创建缩略图的示例代码如下所示:
BufferedImage img = ImageIO.read(...); // load image
BufferedImage scaledImg = Scalr.resize(img, 150);
Your image proportions are honored, the library makes a best-guess at the method it should use based on the amount of change in the image due to scaling (FASTEST, BALANCED or QUALITY) and the best supported Java2D image types are always used to do the scaling to avoid the issue of "black" results or really terrible looking output (e.g. overly dithered GIF images).
您的图像比例受到尊重,该库根据缩放(最快、平衡或质量)导致的图像变化量对其应该使用的方法进行最佳猜测,并且始终使用最受支持的 Java2D 图像类型缩放以避免“黑色”结果或看起来非常糟糕的输出(例如过度抖动的 GIF 图像)问题。
Also, if you want to force it to output the best looking thumbnail possible in Java, the API call would look like this:
此外,如果您想强制它输出 Java 中最好看的缩略图,API 调用将如下所示:
BufferedImage img = ImageIO.read(...); // load image
BufferedImage scaledImg = Scalr.resize(img, Method.QUALITY,
150, 100, Scalr.OP_ANTIALIAS);
Not only will the library use the Java2D recommended incremental scaling for you to give you the best looking result, it will also apply an optional antialiasing effect to the thumbnail (ConvolveOp with a very fine-tuned kernel) to every-so-slightly soften the transitions between pixel values so make the thumbnail look more uniform and not sharp or poppy as you might have seen when you go from very large images down to very small ones.
该库不仅会使用 Java2D 推荐的增量缩放来为您提供最佳效果,还会对缩略图应用可选的抗锯齿效果(ConvolveOp 具有非常微调的内核)以稍微柔化缩略图像素值之间的过渡,使缩略图看起来更均匀,而不是像从非常大的图像到非常小的图像时所看到的那样清晰或罂粟花。
You can read through all the comments in the library (the code itself is doc'ed heavily) to see all the different JDK bugs that are worked around or optimizations that are made to improve the performance or memory usage. I spent a LOT of time tuning this implementation and have had a lot of good feedback from folks deploying it in web apps and other Java projects.
您可以通读库中的所有注释(代码本身被大量记录),以查看所有不同的 JDK 错误或为提高性能或内存使用而进行的优化。我花了很多时间调整这个实现,并从人们那里得到了很多很好的反馈,这些反馈将它部署到 Web 应用程序和其他 Java 项目中。
回答by Ali Imran
This is simple way of creating a 100 X 100 thumbnail without any stretch or skew in image.
这是创建 100 X 100 缩略图的简单方法,图像没有任何拉伸或倾斜。
private void saveScaledImage(String filePath,String outputFile){
try {
BufferedImage sourceImage = ImageIO.read(new File(filePath));
int width = sourceImage.getWidth();
int height = sourceImage.getHeight();
if(width>height){
float extraSize= height-100;
float percentHight = (extraSize/height)*100;
float percentWidth = width - ((width/100)*percentHight);
BufferedImage img = new BufferedImage((int)percentWidth, 100, BufferedImage.TYPE_INT_RGB);
Image scaledImage = sourceImage.getScaledInstance((int)percentWidth, 100, Image.SCALE_SMOOTH);
img.createGraphics().drawImage(scaledImage, 0, 0, null);
BufferedImage img2 = new BufferedImage(100, 100 ,BufferedImage.TYPE_INT_RGB);
img2 = img.getSubimage((int)((percentWidth-100)/2), 0, 100, 100);
ImageIO.write(img2, "jpg", new File(outputFile));
}else{
float extraSize= width-100;
float percentWidth = (extraSize/width)*100;
float percentHight = height - ((height/100)*percentWidth);
BufferedImage img = new BufferedImage(100, (int)percentHight, BufferedImage.TYPE_INT_RGB);
Image scaledImage = sourceImage.getScaledInstance(100,(int)percentHight, Image.SCALE_SMOOTH);
img.createGraphics().drawImage(scaledImage, 0, 0, null);
BufferedImage img2 = new BufferedImage(100, 100 ,BufferedImage.TYPE_INT_RGB);
img2 = img.getSubimage(0, (int)((percentHight-100)/2), 100, 100);
ImageIO.write(img2, "jpg", new File(outputFile));
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
回答by Mouli
I have created a application called fotovault (sourceforge.net) which can upload images and create thumbnails in java using imagej apis.
我创建了一个名为 fotovault (sourceforge.net) 的应用程序,它可以使用 imagej api 在 java 中上传图像和创建缩略图。
Please read my blog below
请阅读我下面的博客
http://www.gingercart.com/Home/java-snippets/create-image-thumbnail-in-java-using-imagej-api
http://www.gingercart.com/Home/java-snippets/create-image-thumbnail-in-java-using-imagej-api
回答by Gagan
I have gone through a blog according to which you have following options -
我浏览了一个博客,根据该博客您有以下选项-
- For simple RGB files use ImageScalr . ImageIO class is used for reading files and ImageScalr to create thumbnails
- For supporting RGB + CYMK, use ImageIO and JAI (Java Advanced Imaging) API for reading files and ImageScalr to create thumbnail.
- In case you don't know what file formats, color mode you are going to deal with, safest option is to use ImageMagick.
- 对于简单的 RGB 文件,请使用 ImageScalr 。ImageIO 类用于读取文件,ImageScalr 用于创建缩略图
- 为了支持 RGB + CYMK,使用 ImageIO 和 JAI(Java Advanced Imaging)API 读取文件和 ImageScalr 创建缩略图。
- 如果您不知道要处理什么文件格式、颜色模式,最安全的选择是使用 ImageMagick。
Here is linkthat gives a complete answer with code snippets.
这是提供代码片段完整答案的链接。
回答by martins.tuga
I've used Thumbnailator! It solved my problem with two lines of code.
我用过缩略图!它用两行代码解决了我的问题。
回答by Gabriel Ambrósio Archanjo
There are many image processing frameworks available that you can do this with just a few lines. The example below generates the thumbnails in different resolutions (given a width as reference) using Marvin Framework. The three thumbnails were generated in 92 ms.
有许多可用的图像处理框架,您只需几行代码即可完成此操作。下面的示例使用Marvin Framework生成不同分辨率的缩略图(给定宽度作为参考)。这三个缩略图是在92 毫秒内生成的。
input:
输入:
output:
输出:
import static marvin.MarvinPluginCollection.*;
MarvinImage image = MarvinImageIO.loadImage("./res/input.jpg");
MarvinImage scaledImage = new MarvinImage(1,1);
scale(image, scaledImage, 250);
MarvinImageIO.saveImage(scaledImage, "./res/output_x250.jpg");
scale(image, scaledImage, 150);
MarvinImageIO.saveImage(scaledImage, "./res/output_x150.jpg");
scale(image, scaledImage, 50);
MarvinImageIO.saveImage(scaledImage, "./res/output_x50.jpg");
回答by Johannes J
Simple way to create a thumbnail without stretching or a library. Works with transparency in pngs, too.
无需拉伸或库即可创建缩略图的简单方法。也适用于 png 中的透明度。
public File createThumbnail(String imageUrl, String targetPath) {
final int imageSize = 100;
File thumbnail = new File(targetPath);
try {
thumbnail.getParentFile().mkdirs();
thumbnail.createNewFile();
BufferedImage sourceImage = ImageIO.read(new File(imageUrl));
float width = sourceImage.getWidth();
float height = sourceImage.getHeight();
BufferedImage img2;
if (width > height) {
float scaledWidth = (width / height) * (float) imageSize;
float scaledHeight = imageSize;
BufferedImage img = new BufferedImage((int) scaledWidth, (int) scaledHeight, sourceImage.getType());
Image scaledImage = sourceImage.getScaledInstance((int) scaledWidth, (int) scaledHeight, Image.SCALE_SMOOTH);
img.createGraphics().drawImage(scaledImage, 0, 0, null);
int offset = (int) ((scaledWidth - scaledHeight) / 2f);
img2 = img.getSubimage(offset, 0, imageSize, imageSize);
}
else if (width < height) {
float scaledWidth = imageSize;
float scaledHeight = (height / width) * (float) imageSize;
BufferedImage img = new BufferedImage((int) scaledWidth, (int) scaledHeight, sourceImage.getType());
Image scaledImage = sourceImage.getScaledInstance((int) scaledWidth, (int) scaledHeight, Image.SCALE_SMOOTH);
img.createGraphics().drawImage(scaledImage, 0, 0, null);
int offset = (int) ((scaledHeight - scaledWidth) / 2f);
img2 = img.getSubimage(0, offset, imageSize, imageSize);
}
else {
img2 = new BufferedImage(imageSize, imageSize, sourceImage.getType());
Image scaledImage = sourceImage.getScaledInstance(imageSize, imageSize, Image.SCALE_SMOOTH);
img2.createGraphics().drawImage(scaledImage, 0, 0, null);
}
ImageIO.write(img2, "png", thumbnail);
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return thumbnail;
}