我正在制作游戏,最近遇到了使用仿射变换旋转缓冲图像时出现的问题。图像围绕自己的中心旋转。例如,当旋转45度时,向上和向左的角被切掉,所有位于低于图像原始x或y位置的像素都不会显示。
这是我用来旋转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
答案 0 :(得分: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)变换原始设置的位置。因此,当你将它翻译成90度时,图像将以“宽度”60和“高度”30结束,但根据原点,图像原始底部将被绘制在(-30,0),所以它在-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);
希望有所帮助。