如何在Java中使用JPEG创build缩略图?
有人可以请帮助一些代码创buildJava的JPEG缩略图。
我是新来的,所以一步一步的解释,将不胜感激。
Image img = ImageIO.read(new File("test.jpg")).getScaledInstance(100, 100, BufferedImage.SCALE_SMOOTH);
这将创build一个100×100像素的缩略图作为图像对象。 如果你想把它写回磁盘,只需将代码转换为:
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"));
另外,如果您担心速度问题(如果要缩放许多图像,上述方法相当慢),请使用这些方法和以下声明:
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; }
然后打电话给:
BufferedImage scaled = scale(img,0.5);
其中0.5是缩放比例,img是包含正常大小图像的BufferedImage。
正如你可能已经发现“简单”和“好看的结果”是两个完全不同的东西。 我已经将这两个要求封装到一个非常简单的Java图像缩放库 (Apache 2许可证),只是为你做一切正确的。
创build缩略图的示例代码如下所示:
BufferedImage img = ImageIO.read(...); // load image BufferedImage scaledImg = Scalr.resize(img, 150);
您的图像比例是荣幸的,图书馆根据图像因缩放(FASTEST,BALANCED或QUALITY)引起的变化量,对其应使用的方法进行最佳猜测,并且始终使用支持的最佳Java2D图像types缩放以避免“黑色”结果或真正可怕的输出结果(例如过度抖动的GIF图像)。
另外,如果您想要强制它在Java中输出最好看的缩略图,那么API调用将如下所示:
BufferedImage img = ImageIO.read(...); // load image BufferedImage scaledImg = Scalr.resize(img, Method.QUALITY, 150, 100, Scalr.OP_ANTIALIAS);
该库不仅会使用Java2Dbuild议的增量缩放比例来为您提供最佳效果,还会对缩略图(具有非常精细调整的内核的ConvolveOp)应用可选的抗锯齿效果,以便稍微软化像素值之间的转换,使缩略图看起来更加一致,而不是像您从非常大的图像到非常小的图像时所看到的那样,不是锐利的或罂粟花的。
您可以通读库中的所有注释(代码本身大量文档),以查看解决所有不同的JDK错误或优化来改进性能或内存使用情况。 我花了很多时间来调整这个实现,并且在Web应用程序和其他Java项目中部署了很多好的反馈。
这是创build100 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(); } }
JMagick库(以及Java中ImageMagick的实现)将会有你所需要的。
上面的Java代码(使用scale / getCompatibleImage方法)对我来说很好,但是当我部署到服务器时,它停止工作,因为服务器没有与之关联的显示 – 任何有这个问题的人都可以通过使用:BufferedImage bi = new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB);
而不是BufferedImage bi = getCompatibleImage(w,h);
并删除getCompatibleImage方法
(后来注意 – 事实certificate,这对大多数图像很好,但我从我的公司营销部门得到了一堆32位彩色深度jpeg图像,而图书馆则抛出了一个不支持的图像格式例外: – imagemagick / jmagick开始看起来更有吸引力)
我创build了一个名为fotovault(sourceforge.net)的应用程序,可以使用imagej apis上传图像并在java中创build缩略图。
请阅读我的博客下面
http://www.gingercart.com/Home/java-snippets/create-image-thumbnail-in-java-using-imagej-api
我已经通过一个博客,你有以下选项 –
- 对于简单的RGB文件使用ImageScalr。 ImageIO类用于读取文件和ImageScalr来创build缩略图
- 要支持RGB + CYMK,请使用ImageIO和JAI(Java高级image processing)API读取文件,使用ImageScalr创build缩略图。
- 如果你不知道什么文件格式,你要处理的颜色模式,最安全的select是使用ImageMagick。
这里是链接 ,给出了代码片段的完整答案。
我用Thumbnailator! 它用两行代码解决了我的问题。
有许多image processing框架可用,只需几行即可完成。 下面的示例使用Marvin Framework以不同的分辨率生成缩略图(以宽度为参考)。 这三个缩略图是在92毫秒内生成的。
input:
输出:
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");
简单的方法来创build一个缩略图,而不需要拉伸或库。 与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; }
我已经使用JAI写了一个使用静态方法的util类。 Java Advanced Imaging API是Java中用于处理图像的最可靠的API。 在Java世界里vector插值是Photoshop最接近的东西。 这是其中之一:
public static ByteArrayOutputStream resize(InputStream inputStream , int IMG_WIDTH, int IMG_HEIGHT) throws Exception { BufferedImage originalImage = ImageIO.read(inputStream); int type = originalImage.getType() == 0 ? BufferedImage.TYPE_INT_ARGB : originalImage.getType(); BufferedImage resizedImage = new BufferedImage(IMG_WIDTH, IMG_HEIGHT, type); { Graphics2D g = resizedImage.createGraphics(); g.drawImage(originalImage, 0, 0, IMG_WIDTH, IMG_HEIGHT, null); g.dispose(); g.setComposite(AlphaComposite.Src); g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); } ByteArrayOutputStream bos = new ByteArrayOutputStream(); ImageIO.write(resizedImage, "png", bos); return bos; }
我知道这是一个很老的post。 我一直在寻找一个解决scheme来生成缩略图,所以最终使用这个
Thumbnails.of(originalImage).scale(0.25).asBufferedImage();
如果您使用手机将build议将比例设置为0.45
Thumbnails.of(originalImage).scale(0.45).asBufferedImage();
https://github.com/coobird/thumbnailator
使用Graphics2D和testing这两个选项的速度肯定快很多。