1

画像のサイズを変更しようとしています。BufferedImageとして保存します。画像を拡大縮小しなくても問題なく動作します。

次のコードでは、ファイル名が渡され、BufferedImageに変換されます。これは正常に機能しますg.drawImage(img, x, y, null);。ここで、imgはBufferedImageです。

public Sprite(String filename){
    ImageIcon imgIcon = new ImageIcon(filename);
    int width = imgIcon.getIconWidth();
    int height = imgIcon.getIconHeight();
    BufferedImage bimg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
    Graphics bg = bimg.getGraphics();
    bg.drawImage(imgIcon.getImage(), 0, 0, null);
    bg.dispose();
    this.sprite = bimg;
}

ここでの次の方法は機能しません。ファイル名とサイズ変更幅が必要です。g.drawImage(img, x, y, null);サイズを変更してからBufferedImageに変換しますが、imgがBufferedImageである場合は再度使用しても機能しません。

public Sprite(String filename, int width){
    ImageIcon imgIcon = new ImageIcon(filename);
    Image img = imgIcon.getImage();
    float h = (float)img.getHeight(null);
    float w = (float)img.getWidth(null);
    int height = (int)(h * (width / w));
    Image imgScaled = img.getScaledInstance(width, height, Image.SCALE_SMOOTH);

    BufferedImage bimg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
    Graphics bg = bimg.getGraphics();
    bg.drawImage(imgScaled, 0, 0, null);
    bg.dispose();
    this.sprite = bimg;
}

だから私の質問は、なぜ2番目のブロックが機能しないのですか?

4

2 に答える 2

1

以下を確認してください。

Image imgScaled = img.getScaledInstance(width, height, Image.SCALE_SMOOTH);

であるかどうかnullimgScaledかかわらず、私にとっては、あなたが持っていると思いますnull

どちらの場合も忘れてしまいましたが、画像の読み込みがブロックされている場合と、ブロックされていないメソッドがある場合があります。つまり、API関数が返され、画像はまだ読み込まれていません。通常、オブザーバーを使用する必要があります。私が言ったように、それはいつか忘れましたが、私はそれらの状況に遭遇しました!

于 2012-12-12T22:28:15.577 に答える
1

丸めの問題があります...

Java は、指定した値に基づいて除算の結果を返します...

例えば...

int width = 100;
int w = 5;
int result = width / w
// result = 0, but it should be 0.5

Java は内部変換を行い、値を に戻しintます。これは単に 10 進数値を切り捨てます。

代わりに、Java が結果を 10 進数値として返すようにする必要があります...

int result = width / (float)w
// result = 0.5

したがって、スケール計算int height = (int)(h * (width / w))は実際に返されます0

私はより多くの線に沿って計算を使用します

int height = Math.round((h * (width / (float)w)))

申し訳ありませんが、このすべての「技術的な」せせらぎをよく覚えていませんが、これはアイデアの一般的な冗談です;)

更新しました

ImageIconバックグラウンド スレッドを使用して実際に画像ピクセルを読み込みますが、コンストラクターを呼び出すとすぐに戻ります。これは、画像データが今後しばらく利用できない可能性があることを意味します。

ImageIO.read(new File(filename))代わりに使用してください。これは、画像データが読み込まれるまでブロックされ、BufferedImage非常に扱いやすい を返します。

于 2012-12-12T22:43:52.403 に答える