3

我有一个字节数组,表示 Windows BMP 格式的图像,我希望我的库将它作为 . 呈现给 Java 应用程序BufferedImage而不复制像素数据。

主要问题是 JDK 中的所有实现都Raster以自上而下、从左到右的顺序存储图像像素,而 BMP 像素数据是自下而上、从左到右存储的。如果不对此进行补偿,则生成的图像将垂直翻转。

最明显的“解决方案”是将SampleModel'scanlineStride属性设置为负值,并将带偏移(或DataBuffer' 数组偏移)更改为指向左上角像素,即数组中最后一行的第一个像素. 不幸的是,这不起作用,因为如果给定负参数,所有SampleModel构造函数都会抛出异常。scanlineStride

我目前正在通过scanlineStride使用反射将字段强制为负值来解决它,但如果可能的话,我想以一种更清洁、更便携的方式来解决它。例如,是否有另一种方法可以欺骗RasterorSampleModel以自下而上的顺序排列像素但不破坏封装?或者是否有一个库可以包装Rasterand SampleModel,以相反的顺序呈现像素行?

我宁愿避免以下方法:

  • 复制整个图像(出于性能原因。代码必须每秒处理数百个大(> = 1Mpixels)图像,虽然整个图像必须可供应用程序使用,但它通常只能访问一个很小的(但难以预测) )图像的一部分。)
  • 修改DataBuffer以执行坐标变换(这实际上可行,但这是另一个“肮脏”的解决方案,因为缓冲区不需要了解扫描线/像素布局。)
  • 从头开始重新实现Raster和/或SampleModel接口(因为兼容性检查的实现方式(至少在 Sun JDK 中),需要特定的子类,SampleModel因此通用BottomUpSampleModel包装类不起作用。)
4

3 回答 3

1

我发现我可以只使用一个我命名的新类来实现这一点BottomUpComponentSampleModel。它在调用超类构造函数后扩展ComponentSampleModel和否定scanlineStride字段的值(幸运的是,它是protected而不是)。private所有像素地址计算都可以正常工作,尽管验证Raster.createWritableRaster没有(如果给它一个太小的数组,它可能无法检测到),但这不是一个严重的问题。

MultiPixelPackedSampleModel使用or时这不是必需的SinglePixelPackedSampleModel,因为它们确实接受否定的scanlineStride. 它们没有带偏移,但这可以通过在DataBuffer.

于 2010-03-26T11:24:29.917 回答
0

当访问图像的微小(但难以预测)部分时,让应用程序(或访问层)对其副本进行翻译和翻转工作怎么样?

于 2010-03-17T10:07:00.163 回答
0

更好的是,听起来应用程序不需要实际显示图像?何必一开始就想翻转它,让它在屏幕上看起来正确呢?只需编写逻辑以在您拥有的版本上工作?也不需要这样的 BufferedImage ,直接在数组上工作。

于 2010-03-17T10:35:46.753 回答