2012-10-19 54 views
2

我正在做一個遊戲,最近遇到了一個問題,當使用affinetransform旋轉緩衝圖像時發生。圖像圍繞自己的中心旋轉。例如,當旋轉45度時,向上和向左的角落被切斷,位置低於圖像的原始x或y位置的所有像素都不顯示。affinetransform旋轉,bufferedimages被剪切

這是我使用用於旋轉的BufferedImage的代碼:

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是得到返回的一個給角度到主要班級。

我想辦法解決這個問題將放大圖像文件,增加周圍的空白空間,所以我不使用切角。但是這會降低性能,如果可能的話,我寧願堅持適當的解決方案。希望一切都清楚!

// Snorbird

回答

1

的問題是你的源圖像是不完全的二次。 當您實現與at.rotate(-rad, width/2, height/2);的旋轉的AffineTransform,它是一樣的:

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

所以,當它執行的最後一行,將其轉換到原點。如果寬度大於y(反之亦然),則轉換的原點將轉換爲比長度更大的邊更小的距離。例如,如果您的寬度爲30,並且您的身高爲60,則原始點將設置爲(-15,-30),與原始設置的轉換位置相同(-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); 

希望它能幫助。