Java で JPEG のサムネイルを作成するためのコードを教えてください。
私はこれが初めてなので、段階的な説明をいただければ幸いです。
Image img = ImageIO.read(new File("test.jpg")).getScaledInstance(100, 100, BufferedImage.SCALE_SMOOTH);
これにより、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"));
また、速度の問題が気になる場合 (多数の画像を拡大縮小する場合、上記の方法はかなり遅くなります)、これらの方法と次の宣言を使用します。
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 ライセンス) にカプセル化しました。
サムネイルを作成するサンプル コードは次のようになります。
BufferedImage img = ImageIO.read(...); // load image
BufferedImage scaledImg = Scalr.resize(img, 150);
画像のプロポーションが尊重され、ライブラリは、スケーリング (FASTEST、BALANCED、または QUALITY) による画像の変化量に基づいて、使用する必要がある方法で最善の推測を行い、サポートされている最適な Java2D 画像タイプが常に使用されます。 「黒い」結果や非常に見栄えの悪い出力 (例: 過度にディザリングされた GIF 画像) の問題を回避するためのスケーリング。
また、Java で可能な限り最高のサムネイルを出力するように強制する場合、API 呼び出しは次のようになります。
BufferedImage img = ImageIO.read(...); // load image
BufferedImage scaledImg = Scalr.resize(img, Method.QUALITY,
150, 100, Scalr.OP_ANTIALIAS);
ライブラリは Java2D 推奨のインクリメンタル スケーリングを使用して最高の外観を実現するだけでなく、サムネイルにオプションのアンチエイリアシング効果 (非常に微調整されたカーネルを使用した ConvolveOp) を適用して、画像を少しだけ柔らかくします。非常に大きな画像から非常に小さな画像に移行するときに見られるように、サムネイルがより均一になり、シャープまたはポピーではなくなります。
ライブラリ内のすべてのコメント (コード自体は大量にドキュメント化されています) を読んで、回避されたさまざまな JDK バグや、パフォーマンスやメモリ使用量を改善するために行われた最適化をすべて確認できます。私はこの実装の調整に多くの時間を費やし、Web アプリやその他の Java プロジェクトにデプロイしている人々から多くの良いフィードバックを受け取りました。
これは、画像の伸びやゆがみのない 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();
}
}
JMagickライブラリ (および Java でのImageMagickの実装) には、必要なものが含まれています。
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);
instead of BufferedImage bi = getCompatibleImage(w, h);
and deleting the getCompatibleImage method
(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)
私は何年も前に JAI を使用して、静的メソッドを持つ util クラスを作成しました。Java Advanced Imaging API は、画像を処理する Java で最も信頼性の高い API です。ベクトル補間は、Java の世界で Photoshop に最も近いものです。ここにそれらの1つがあります:
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;
}
Thumbnailator を使用しました。2行のコードで私の問題を解決しました。
ストレッチやライブラリを使用せずにサムネイルを作成する簡単な方法。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;
}
imagej api を使用して Java で画像をアップロードし、サムネイルを作成できる fotovault (sourceforge.net) というアプリケーションを作成しました。
以下の私のブログを読んでください
http://www.gingercart.com/Home/java-snippets/create-image-thumbnail-in-Java-using-imagej-api