Answers:
加载图像后,您可以尝试:
BufferedImage createResizedCopy(Image originalImage,
int scaledWidth, int scaledHeight,
boolean preserveAlpha)
{
System.out.println("resizing...");
int imageType = preserveAlpha ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
BufferedImage scaledBI = new BufferedImage(scaledWidth, scaledHeight, imageType);
Graphics2D g = scaledBI.createGraphics();
if (preserveAlpha) {
g.setComposite(AlphaComposite.Src);
}
g.drawImage(originalImage, 0, 0, scaledWidth, scaledHeight, null);
g.dispose();
return scaledBI;
}
我刚刚发布了FWIW(Apache 2,托管在GitHub上)一个简单的Java图像缩放库,名为imgscalr(在Maven Central上提供)。
该库实现了几种不同的图像缩放方法(包括Chris Campbell的增量方法,并进行了一些小的改进),并且会根据您的要求为您选择最佳的方法,或者为您提供最快或外观最好的方法(如果您愿意的话)要求)。
用法非常简单,只是一堆静态方法。最简单的用例是:
BufferedImage scaledImage = Scalr.resize(myImage, 200);
所有操作都会保持图像的原始比例,因此在这种情况下,您要让imgscalr在200像素宽和200像素高的范围内调整图像大小,默认情况下,它将自动为此选择最佳外观和最快方法未指定。
我一开始就意识到这看起来像是自我提升,但是我花了相当多的时间搜索这个完全相同的主题,并不断提出不同的结果/方法/想法/建议,并决定坐下来写一篇一个简单的实现,可以解决80-85%的用例,在这些用例中您有图像并且可能需要缩略图-尽可能快或看起来更好(对于那些尝试过的用户,您会注意到即使使用BICUBIC插值对一个足够小的图像执行Graphics.drawImage,它仍然看起来像垃圾)。
new ImageScaler(img).resizeTo(...).rotate(...).cropTo(...).toOutputBuffer()
。我也喜欢您的方式,我认为这很简单。
Thumbnailator是具有流畅接口的Java开源图像大小调整库,已根据MIT许可进行分发。
我之所以写这个库,是因为用Java制作高质量的缩略图非常困难,而且生成的代码可能很混乱。使用Thumbnailator,可以使用简单的流畅API来表达相当复杂的任务。
一个简单的例子
举一个简单的例子,拍摄一张图像并将其尺寸调整为100 x 100(保留原始图像的宽高比),然后将其保存到文件中,可以在一条语句中完成:
Thumbnails.of("path/to/image")
.size(100, 100)
.toFile("path/to/thumbnail");
一个高级的例子
Thumbnailator的流畅界面简化了执行复杂的大小调整任务的过程。
假设我们要执行以下操作:
0.85
,thumbnail.
附加在开头转换为Thumbnailator后,我们可以执行以下操作:
Thumbnails.of(new File("path/to/directory").listFiles())
.size(100, 100)
.outputFormat("JPEG")
.outputQuality(0.85)
.toFiles(Rename.PREFIX_DOT_THUMBNAIL);
有关图像质量和速度的注意事项
该库还使用了由Chet Haase和Romain Guy在Filthy Rich Clients中强调的渐进双线性缩放方法,以生成高质量的缩略图,同时确保可接受的运行时性能。
您不需要库即可执行此操作。您可以使用Java本身来实现。
克里斯·坎贝尔(Chris Campbell)在缩放图像方面有出色而详尽的文章 -请参阅本文。
Chet Haase和Romain Guy在其著作《肮脏的富客户》(Filthy Rich Clients)中也有详尽而翔实的图像缩放文章。
Java Advanced Imaging现在是开源的,并提供了您需要的操作。
如果您要处理大图像或想要漂亮的结果,那么在Java中这并不是一件简单的任务。通过Graphics2D通过重新缩放操作来简单地完成操作不会创建高质量的缩略图。您可以使用JAI来做到这一点,但是要获得看起来不错的东西,它需要做的工作比您想像的还要多,并且JAI有一个讨厌的习惯,那就是用OutOfMemory错误使我们的JVM崩溃。
我建议您使用ImageMagick作为外部可执行文件,如果可以的话。它使用简单,可以正确完成工作,因此您不必这样做。
Java API不提供用于图像和降低图像质量的标准缩放功能。
因此,我尝试使用JavaCV中的cvResize,但似乎会引起问题。
我找到了一个很好的图像缩放库:只需在pom.xml中添加“ java-image-scaling”的依赖项即可。
<dependency>
<groupId>com.mortennobel</groupId>
<artifactId>java-image-scaling</artifactId>
<version>0.8.6</version>
</dependency>
在maven存储库中,您将获得此版本的最新版本。
例如 在你的java程序中
ResampleOp resamOp = new ResampleOp(50, 40);
BufferedImage modifiedImage = resamOp.filter(originalBufferedImage, null);
您可以尝试使用带有im4java的GraphicsMagick图像处理系统作为Java的命令行界面。
GraphicsMagick有很多优点,但有一个优点:
提到了Image Magick。有一个名为JMagick的JNI前端项目。这不是一个特别稳定的项目(众所周知,Image Magick本身会发生很大变化,甚至破坏兼容性)。也就是说,我们在生产环境中使用JMagick和兼容的Image Magick版本具有良好的经验,可以在高吞吐量,低延迟率下执行缩放。与我们之前尝试过的全Java图形库相比,速度要好得多。
您可以将Marvin(纯Java图像处理框架)用于这种操作:http : //marvinproject.sourceforge.net
Scale插件:http : //marvinproject.sourceforge.net/en/plugins/scale.html
事实证明,编写高性能的缩放器并不容易。我为一个开源项目ImageScaler做了一次。
原则上,“ java.awt.Image#getScaledInstance(int,int,int)”也可以完成这项工作,但是这样做有一个讨厌的错误-有关详细信息,请参阅我的链接。
我已经开发了一种可免费使用的类(AnimatedGifEncoder,GifDecoder和LWZEncoder)用于处理GIF动画的解决方案。
您可以下载jgifcode jar并运行GifImageUtil类。链接:http: //www.jgifcode.com
您可以使用以下受欢迎的产品:thumbnailator
如果您不想像上面测试过的@Riyad Kalla答案那样导入imgScalr,但我也可以很好地进行测试,尽管如此,您也可以在另一个问题上从Peter Walser答案 @Peter Walser 那里获取:
/**
* utility method to get an icon from the resources of this class
* @param name the name of the icon
* @return the icon, or null if the icon wasn't found.
*/
public Icon getIcon(String name) {
Icon icon = null;
URL url = null;
ImageIcon imgicon = null;
BufferedImage scaledImage = null;
try {
url = getClass().getResource(name);
icon = new ImageIcon(url);
if (icon == null) {
System.out.println("Couldn't find " + url);
}
BufferedImage bi = new BufferedImage(
icon.getIconWidth(),
icon.getIconHeight(),
BufferedImage.TYPE_INT_RGB);
Graphics g = bi.createGraphics();
// paint the Icon to the BufferedImage.
icon.paintIcon(null, g, 0,0);
g.dispose();
bi = resizeImage(bi,30,30);
scaledImage = bi;// or replace with this line Scalr.resize(bi, 30,30);
imgicon = new ImageIcon(scaledImage);
} catch (Exception e) {
System.out.println("Couldn't find " + getClass().getName() + "/" + name);
e.printStackTrace();
}
return imgicon;
}
public static BufferedImage resizeImage (BufferedImage image, int areaWidth, int areaHeight) {
float scaleX = (float) areaWidth / image.getWidth();
float scaleY = (float) areaHeight / image.getHeight();
float scale = Math.min(scaleX, scaleY);
int w = Math.round(image.getWidth() * scale);
int h = Math.round(image.getHeight() * scale);
int type = image.getTransparency() == Transparency.OPAQUE ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
boolean scaleDown = scale < 1;
if (scaleDown) {
// multi-pass bilinear div 2
int currentW = image.getWidth();
int currentH = image.getHeight();
BufferedImage resized = image;
while (currentW > w || currentH > h) {
currentW = Math.max(w, currentW / 2);
currentH = Math.max(h, currentH / 2);
BufferedImage temp = new BufferedImage(currentW, currentH, type);
Graphics2D g2 = temp.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.drawImage(resized, 0, 0, currentW, currentH, null);
g2.dispose();
resized = temp;
}
return resized;
} else {
Object hint = scale > 2 ? RenderingHints.VALUE_INTERPOLATION_BICUBIC : RenderingHints.VALUE_INTERPOLATION_BILINEAR;
BufferedImage resized = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = resized.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
g2.drawImage(image, 0, 0, w, h, null);
g2.dispose();
return resized;
}
}
尝试以下方法:
ImageIcon icon = new ImageIcon("image.png");
Image img = icon.getImage();
Image newImg = img.getScaledInstance(350, 350, java.evt.Image.SCALE_SMOOTH);
icon = new ImageIcon(img);
JOptionPane.showMessageDialog(null, "image on The frame", "Display Image", JOptionPane.INFORMATION_MESSAGE, icon);