2

私はゲームを作成していますが、最近、affinetransform を使用してバッファリングされた画像を回転させるときに発生する問題に遭遇しました。画像は、独自の中心を中心に回転します。たとえば、45 度回転すると、上向きと左向きの角が切り取られ、画像の元の x または y 位置より下にあるすべてのピクセルが表示されなくなります。

これは、バッファリングされた画像を回転させるために使用するコードです:

setRad();
AffineTransform at = new AffineTransform();
at.rotate(-rad, width/2, height/2);
AffineTransformOp op = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);
bImage = op.filter(startImage, null);

setRad() は x と y の速度に応じて角度を返します。 startImage は
ロードされた画像
です。 bImage はメイン クラスに返される画像です。

これを解決する方法は、画像ファイルを拡大し、その周りに空のスペースを追加することであると考えたので、角が切り取られないようにしました。しかし、これはパフォーマンスをいくらか低下させるので、可能であれば適切な解決策に固執したいと思います. それがすべて明確であることを願っています!

//スノーバード

4

1 に答える 1

1

問題は、ソース イメージが正確に 2 次でないことです。で AffineTransform 回転を実装するとat.rotate(-rad, width/2, height/2);、次と同じになります。

at.translate(width/2,height/2);
at.rotate(rads);
at.translate(-width/2,-height/2);

したがって、最後の行を実行すると、原点に変換されます。幅が y よりも大きい場合 (またはその逆)、変換の原点は長さの長い側よりも短い距離に変換されます。

たとえば、幅が 30 で高さが 60 の場合、原点は、変換が最初に設定された場所から (-15,-30) として設定されます。なので、例えば90度平行移動すると、画像は「幅」60、「高さ」30になりますが、原点によると、画像の元の下部は(-30,0)に描画され、そのため、X 軸の -15 で AffineTransform をオーバーフローします。次に、画像のこの部分がカットされます。

これを修正するには、代わりに次のコードを使用できます。

    double degreesToRotate = 90;
    double locationX =bufferedImage.getWidth() / 2;
    double locationY = bufferedImage.getHeight() / 2;

    double diff = Math.abs(bufferedImage.getWidth() - bufferedImage.getHeight());

    //To correct the set of origin point and the overflow
    double rotationRequired = Math.toRadians(degreesToRotate);
    double unitX = Math.abs(Math.cos(rotationRequired));
    double unitY = Math.abs(Math.sin(rotationRequired));

    double correctUx = unitX;
    double correctUy = unitY;

    //if the height is greater than the width, so you have to 'change' the axis to correct the overflow
    if(bufferedImage.getWidth() < bufferedImage.getHeight()){
        correctUx = unitY;
        correctUy = unitX;
    }

    int posAffineTransformOpX = posX-(int)(locationX)-(int)(correctUx*diff);
    int posAffineTransformOpY = posY-(int)(locationY)-(int)(correctUy*diff);

    //translate the image center to same diff that dislocates the origin, to correct its point set
    AffineTransform objTrans = new AffineTransform();
    objTrans.translate(correctUx*diff, correctUy*diff);
    objTrans.rotate(rotationRequired, locationX, locationY);

    AffineTransformOp op = new AffineTransformOp(objTrans, AffineTransformOp.TYPE_BILINEAR);

    // Drawing the rotated image at the required drawing locations
    graphic2dObj.drawImage(op.filter(bufferedImage, null), posAffineTransformOpX, posAffineTransformOpY, null);

それが役立つことを願っています。

于 2016-04-06T19:51:58.197 に答える