BufferedImage
javadocsに従って、成功せずにスケーリングしようとしましたが、ここに私のコードがあります:
BufferedImage image = MatrixToImageWriter.getBufferedImage(encoded);
Graphics2D grph = image.createGraphics();
grph.scale(2.0, 2.0);
grph.dispose();
なぜ機能しないのか理解できません。
BufferedImage
javadocsに従って、成功せずにスケーリングしようとしましたが、ここに私のコードがあります:
BufferedImage image = MatrixToImageWriter.getBufferedImage(encoded);
Graphics2D grph = image.createGraphics();
grph.scale(2.0, 2.0);
grph.dispose();
なぜ機能しないのか理解できません。
AffineTransformOp
は、補間タイプを選択する柔軟性を提供します。
BufferedImage before = getBufferedImage(encoded);
int w = before.getWidth();
int h = before.getHeight();
BufferedImage after = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
AffineTransform at = new AffineTransform();
at.scale(2.0, 2.0);
AffineTransformOp scaleOp =
new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);
after = scaleOp.filter(before, after);
示されているフラグメントは、クロッピングではなくリサンプリングを示しています。この関連する回答は問題に対処します。関連するいくつかの例をここで調べます。
残念ながら、getScaledInstance() のパフォーマンスは、問題がなければ非常に貧弱です。
もう 1 つの方法は、新しい BufferedImage を作成し、元のイメージをスケーリングしたバージョンを新しいイメージに描画することです。
BufferedImage resized = new BufferedImage(newWidth, newHeight, original.getType());
Graphics2D g = resized.createGraphics();
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.drawImage(original, 0, 0, newWidth, newHeight, 0, 0, original.getWidth(),
original.getHeight(), null);
g.dispose();
newWidth、newHeight は新しい BufferedImage サイズを示し、適切に計算する必要があります。因子スケーリングの場合:
int newWidth = new Double(original.getWidth() * widthFactor).intValue();
int newHeight = new Double(original.getHeight() * heightFactor).intValue();
編集: パフォーマンスの問題を説明する記事を見つけました: Image.getScaledInstance() の危険性
imgscar の使用 – Java 画像スケーリング ライブラリ:
BufferedImage image =
Scalr.resize(originalImage, Scalr.Method.BALANCED, newWidth, newHeight);
これは私にとって十分に速いです。
@Bozhoが言うように、おそらくを使用したいと思うでしょうgetScaledInstance
。
ただし、どのように機能するかを理解するgrph.scale(2.0, 2.0)
には、次のコードを参照してください。
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
class Main {
public static void main(String[] args) throws IOException {
final int SCALE = 2;
Image img = new ImageIcon("duke.png").getImage();
BufferedImage bi = new BufferedImage(SCALE * img.getWidth(null),
SCALE * img.getHeight(null),
BufferedImage.TYPE_INT_ARGB);
Graphics2D grph = (Graphics2D) bi.getGraphics();
grph.scale(SCALE, SCALE);
// everything drawn with grph from now on will get scaled.
grph.drawImage(img, 0, 0, null);
grph.dispose();
ImageIO.write(bi, "png", new File("duke_double_size.png"));
}
}
与えられたduke.png:
duke_double_size.pngを生成します:
外部ライブラリを使用してもかまわない場合は、Thumbnailatorで s のスケーリングを実行できますBufferedImage
。
Thumbnailator はJava 2D処理 (適切なレンダリング ヒントGraphics2D
の使用と設定など) を処理し、単純な流暢な API 呼び出しを使用して画像のサイズを変更できるようにします。
BufferedImage image = Thumbnails.of(originalImage).scale(2.0).asBufferedImage();
Thumbnailator は、その名前が示すように、画像の縮小を目的としていますが、デフォルトのリサイズ実装で双一次補間を使用して、画像を拡大することもできます。
免責事項: 私はThumbnailatorライブラリの管理者です。
scale(..)
動作が少し異なります。使用できますbufferedImage.getScaledInstance(..)