54

BufferedImagejavadocsに従って、成功せずにスケーリングしようとしましたが、ここに私のコードがあります:

BufferedImage image = MatrixToImageWriter.getBufferedImage(encoded);
Graphics2D grph = image.createGraphics();
grph.scale(2.0, 2.0);
grph.dispose();

なぜ機能しないのか理解できません。

4

7 に答える 7

76

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);

示されているフラグメントは、クロッピングではなくリサンプリングを示しています。この関連する回答は問題に対処します。関連するいくつかの例をここで調べます

于 2010-11-18T15:43:26.853 に答える
39

残念ながら、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() の危険性

于 2010-11-18T15:15:31.740 に答える
13

imgscar の使用 – Java 画像スケーリング ライブラリ:

BufferedImage image =
     Scalr.resize(originalImage, Scalr.Method.BALANCED, newWidth, newHeight);

これは私にとって十分に速いです。

于 2014-02-23T21:52:14.697 に答える
10

@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を生成します:
ここに画像の説明を入力してください

于 2010-11-18T15:07:18.277 に答える
8

外部ライブラリを使用してもかまわない場合は、Thumbnailatorで s のスケーリングを実行できますBufferedImage

Thumbnailator はJava 2D処理 (適切なレンダリング ヒントGraphics2Dの使用と設定など) を処理し、単純な流暢な API 呼び出しを使用して画像のサイズを変更できるようにします。

BufferedImage image = Thumbnails.of(originalImage).scale(2.0).asBufferedImage();

Thumbnailator は、その名前が示すように、画像の縮小を目的としていますが、デフォルトのリサイズ実装で双一次補間を使用して、画像を拡大することもできます。


免責事項: 私はThumbnailatorライブラリの管理者です。

于 2014-11-16T10:35:05.470 に答える
3

scale(..)動作が少し異なります。使用できますbufferedImage.getScaledInstance(..)

于 2010-11-18T15:02:45.853 に答える