我有一个类Bitmap,它只包含一个rgba值的像素数组,我已经在互联网上搜索过无效的答案。
我怎样才能创建一个叫做的函数,比如说;
private int[] pixels;
private int width;
private int height;
/**
*Rotates this image around (x, y) by theta degrees
*/
public void rotate(int theta, int x, int y){
// Code to rotate 1D array here
}
答案 0 :(得分:2)
首先,无法进行旋转 - 您需要将旋转后的图像绘制到不同的缓冲区中。要模拟就地旋转,仍然需要获取数组的副本。
此外,除非旋转180°,否则旋转矩形图像的结果将占据比原始图像更大的矩形,因此当绘制回原始缓冲区时,其角将被剪掉。
无论如何,这是一种方法,通过将像素数组包装在BufferedImage中并调用AWT的帮助(import java.awt。*和java.awt.image。*):
/** Creates an RGBA BufferedImage backed by the specified pixel array. */
static BufferedImage asBufferedImage(int[] pixels, int width, int height) {
ColorModel cm = ColorModel.getRGBdefault();
int[] bandMasks = new int[] { 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 };
DataBuffer dataBuffer = new DataBufferInt(pixels, pixels.length);
WritableRaster raster = Raster.createPackedRaster(
dataBuffer,
width,
height,
width,
bandMasks,
null);
return new BufferedImage(cm, raster, false, null);
}
/** Rotates this image clockwise by an angle in degrees about the point (x, y). */
public void rotate(double theta, double x, double y) {
BufferedImage srcImage = asBufferedImage(pixels.clone(), width, height);
BufferedImage dstImage = asBufferedImage(pixels, width, height);
Arrays.fill(pixels, 0x00000000);
Graphics2D g = dstImage.createGraphics();
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.setComposite(AlphaComposite.Src);
g.transform(AffineTransform.getRotateInstance(theta * (Math.PI / 180), x, y));
g.drawImage(srcImage, null, 0, 0);
g.dispose();
}
方法asBufferedImage()
返回由相同像素数组支持的新BufferedImage,因此通过像素数组或BufferedImage进行的更改正在修改相同的内容。我们这样做,所以我们可以使用Java的图形管道数组。我们通过pixels.clone()
获取源图像的副本,以便阅读。 Arrays.fill
调用会将目标缓冲区清除为透明黑色,因此我们不会在两侧看到原始图像的部分内容。 setRenderingHints
电话是可选的;它打开了双线性抗锯齿,所以它看起来更好,虽然它确实在速度上花费。 setComposite(AlphaComposite.Src)
调用是一项次要优化,可防止混合。默认合成模式SrcOver会将新像素与图像中已有的像素混合,而Src只需替换现有像素。由于我们知道图像缓冲区被清除为透明黑色,因此混合或不混合具有相同的效果。 AffineTransform是一个封装2D坐标变换的矩阵,在这种情况下是一个关于点的旋转,我们用它来变换Graphics对象绘制的内容。然后我们画它!
答案 1 :(得分:0)
你可以扩展Point,然后使用translate(dx,dy)方法做你想做的事情,例如:
public class MyPixel extends Point{
//Your implementation of 'pixel' here
}
public class Bitmap{
private Vector<MyPixel> pixels;
//Implement constructors
public void rotate(int theta){
for(MyPixel p : pixels){
int dx; //Calculate those using theta - they are the change of the x and y coordinates of
int dy; //The point p you will translate.
p.translate(dx,dy);
}
}
public static void main(String[] args){
Bitmap bmp = new Bitmap();
bmp.rotate(30);
}