2

我正在使用 java 中的 OpenCV,但我不了解在 java 中加载图片的类的一部分:

public class ImageProcessor {
  public BufferedImage toBufferedImage(Mat matrix){
    int type = BufferedImage.TYPE_BYTE_GRAY;
    if ( matrix.channels() > 1 ) {
        type = BufferedImage.TYPE_3BYTE_BGR;
    }
    int bufferSize = matrix.channels()*matrix.cols()*matrix.rows();
    byte [] buffer = new byte[bufferSize];
    matrix.get(0,0,buffer); // get all the pixels
    BufferedImage image = new BufferedImage(matrix.cols(),matrix.rows(),type);                    
    final byte[] targetPixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
    System.arraycopy(buffer, 0, targetPixels, 0, buffer.length);  
    return image;
  }

主类向该类发送一个Mat对象。

结果发送BufferedImage但我不明白 targetPixels 因为这个类没有在其他地方使用它。但是每当我评论 targetPixels 和 System.arraycopy 时,结果都会显示黑色图片。

我想知道什么是targetPixels- 它有什么作用?

4

3 回答 3

2

重点不是关于那个数组,而是让你到达那里的方法。

你从这里开始:getRaster()。那应该返回一个WritableRaster ...等等。

该类使用来自Raster 类的getDataBuffer();我们发现:

表示像素矩形阵列的类。Raster 封装了一个存储样本值的 DataBuffer 和一个描述如何在 DataBuffer 中定位给定样本值的 SampleModel。

这里本质上发生了什么:那个Image对象,最后有一个字节数组,应该包含某些信息。

那个任务:

final byte[] targetPixels = ...

检索对该内部数据的引用;然后arrayCopy()用于将数据复制到该数组中。

作为记录:这看起来不是一个好方法 - 因为它在此复制操作真正影响该 Image 对象的内部时才有效。但是,如果最后一次调用getData()会创建内部数据的副本呢?

换句话说:这段代码试图直接访问某个对象的内部数据;然后操纵该内部数据。

即使这在今天有效,但它并不健壮;并且将来可能很容易破裂。另一件事:请注意,此代码执行无条件强制转换(DataBufferByte)。如果缓冲区不完全具有该类型,则该代码将引发 RuntimeException。

可能那是“一切都好”;因为它都与可能存在多年的“AWT”类有关;并且不会再改变了。但如前所述;此代码有各种潜在问题。

于 2017-04-04T09:18:48.110 回答
0

targetPixels是新图像的主要图像数据(即像素)。实际图像是在将像素数据复制 buffer到时创建的targetPixels

于 2017-04-04T09:17:56.760 回答
0

targetPixels 是新创建的 BufferedImage 中的字节数组,这些字节是空的,因此您需要使用 System.arraycopy.. 将缓冲区中的字节复制到其中。:)

于 2017-04-04T09:21:41.967 回答