我有一个以Windows BMP格式表示图像的字节数组,我希望我的库以BufferedImage
,的形式将它呈现给Java应用程序而不用复制像素数据。
主要问题是JDK中Raster
的所有实现都以自上而下,从左到右的顺序对像素进行成像,而BMP像素数据则自下而上,从左到右存储。如果未对此进行补偿,则生成的图像将垂直翻转。
最明显的“解决方案”是将SampleModel
的{{1}}属性设置为负值,并将波段偏移量(或scanlineStride
的数组偏移量)更改为点到左上角的像素,即阵列中最后一行的第一个像素。不幸的是,这不起作用,因为如果给出负DataBuffer
参数,所有SampleModel
构造函数都会抛出异常。
我目前正在通过使用反射强制scanlineStride
字段为负值来解决它,但如果可能的话,我希望以更干净,更便携的方式进行。
例如是否有另一种方法来欺骗scanlineStride
或Raster
以自下而上的顺序排列像素但不破坏封装?或者是否有一个库将包裹SampleModel
和Raster
,以相反的顺序呈现像素行?
我宁愿避免以下方法:
SampleModel
以执行坐标转换(这实际上有效但是另一个“脏”解决方案,因为缓冲区不需要知道扫描线/像素布局。)DataBuffer
和/或Raster
接口(因为实现了兼容性检查的方式(至少在Sun JDK中),需要SampleModel
的特定子类所以通用SampleModel
包装类不起作用。)答案 0 :(得分:1)
我发现我只能使用一个新类来实现它,我将其命名为BottomUpComponentSampleModel
。它扩展ComponentSampleModel
并在调用超类构造函数后否定scanlineStride
字段的值(幸运的是,protected
而不是private
)。所有的像素地址计算都可以正常工作,尽管Raster.createWritableRaster
中的验证没有(它可能无法检测到你是否给它一个太小的数组),但这不是一个严重的问题。
MultiPixelPackedSampleModel
或SinglePixelPackedSampleModel
不需要这样做,因为它们接受否定scanlineStride
。它们没有波段偏移,但可以通过在DataBuffer
上设置偏移来解决这个问题。
答案 1 :(得分:0)
当访问图像的微小(但难以预测)部分时,让应用程序(或访问层)在其副本上进行翻译和翻转工作会怎样?
答案 2 :(得分:0)
更好,听起来应用程序不需要实际显示图像? 为什么要首先将它翻转以便在屏幕上显示正确?只需编写逻辑来处理您拥有的版本? 不需要那样的BufferedImage,直接在数组上工作。