我想提取一个BufferedImage的矩形。
Javadoc建议使用getSubImage(x,y,w,h)和getData(矩形)。
getData很酷,但我不想只使用光栅。我希望subimage作为BufferedImage对象,但我还需要它的数据数组的修改版本,但javadoc说
public BufferedImage getSubimage(int x,int y,int w,int h):返回由指定矩形区域定义的子图像。 返回的BufferedImage与原始图像共享相同的数据阵列。
问:如何使用缩小的数据数组提取子图像?
答案 0 :(得分:6)
给定BufferedImage
图像,这里有3种创建“深度”副本子图像的方法:
// Create an image
BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_4BYTE_ABGR);
// Fill with static
new Random().nextBytes(((DataBufferByte) image.getRaster().getDataBuffer()).getData());
围绕从Raster
获得的getData(rect)
的深层副本创建图片。这涉及到WritableRaster
的转换,因此它可能会破坏某些Java实现或将来。应该非常快,因为你只复制一次数据:
// Get sub-raster, cast to writable and translate it to 0,0
WritableRaster data = ((WritableRaster) image.getData(new Rectangle(25, 25, 50, 50))).createWritableTranslatedChild(0, 0);
// Create new image with data
BufferedImage subOne = new BufferedImage(image.getColorModel(), data, image.isAlphaPremultiplied(), null);
另一个选项是,以“常规方式”创建子图像,然后将光栅复制到新图像中。涉及创建一个子栅格,仍然只复制一次(并且没有转换):
// Get subimage "normal way"
BufferedImage subimage = image.getSubimage(25, 25, 50, 50);
// Create empty compatible image
BufferedImage subTwo = new BufferedImage(image.getColorModel(), image.getRaster().createCompatibleWritableRaster(50, 50), image.isAlphaPremultiplied(), null);
// Copy data into the new, empty image
subimage.copyData(subTwo.getRaster());
最后,更简单的路线,只需在新的空图像上绘制子图像。可能会稍慢,因为它涉及渲染管道,但我认为它应该合理地执行。
// Get subimage "normal way"
BufferedImage subimage = image.getSubimage(25, 25, 50, 50);
// Create new empty image of same type
BufferedImage subThree = new BufferedImage(50, 50, image.getType());
// Draw the subimage onto the new, empty copy
Graphics2D g = subThree.createGraphics();
try {
g.drawImage(subimage, 0, 0, null);
}
finally {
g.dispose();
}
答案 1 :(得分:0)
很久以前我遇到了同样的问题,我不想要共享光栅。我找到的唯一解决方案是创建一个代表子图像的BufferedImage,然后将像素复制到子图像中。
为了让事情变得非常快,我直接访问DataBuffer并使用System.arraycopy()逐行创建数组副本