【问题标题】:BufferedImage : extract subimage with same dataBufferedImage : 提取具有相同数据的子图像
【发布时间】:2016-04-06 21:29:07
【问题描述】:

我想提取一个 BufferedImage 的矩形。

Javadoc 提出 getSubImage(x,y,w,h) 和 getData(rectangle)。

getData 很酷,但我不只想要栅格。我希望子图像作为 BufferedImage 对象,但我还需要它的数据数组的修改版本,但 javadoc 说

public BufferedImage getSubimage(int x,int y,int w,int h) :返回由指定矩形区域定义的子图像。 返回的 BufferedImage 与原始图像共享相同的数据数组

问:如何提取具有缩小数据数组的子图像?

【问题讨论】:

  • 提取子图像,绘制它做另一个 BufferedImage,修改你的心内容
  • 计算效率高吗?
  • 我不知道,它很简单,而且可以为您提供一个 BufferedImage,它是子图像的副本,但在更改时不会影响原始图像。试一试,做一些你自己的比较,看看什么适合你

标签: java bufferedimage raster


【解决方案1】:

给定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());

围绕您从getData(rect) 获得的Raster 的深层副本创建一个图像。这涉及转换为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();
}

【讨论】:

  • 感谢全面的回复!
【解决方案2】:

很久以前我也遇到过同样的问题,我不想要共享栅格。我找到的唯一解决方案是创建一个表示子图像的 BufferedImage,然后将像素复制到子图像中。

为了获得真正快速的结果,我直接访问 DataBuffer 并使用 System.arraycopy() 制作数组副本(逐行)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-29
    • 2013-11-06
    • 1970-01-01
    • 2020-06-26
    • 2011-10-19
    • 2017-12-14
    • 1970-01-01
    相关资源
    最近更新 更多