Search code examples
javaopencvbufferedimagesystem.array

I don't understand a code to load picture in java


I am working with OpenCV in java, but I don't understand part of a class that loads pictures in 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;
  }

Main class sends a Mat object to this class.

The result sends BufferedImage but I don't understand targetPixels because this class doesn't use it somewhere else. But whenever I comment targetPixels and System.arraycopy, result shows black picture.

I want to know what's targetPixels - and what does it do?


Solution

  • The point is less about that array, but the methods that get you there.

    You start here: getRaster(). That is supposed to return a WritableRaster ... and so on.

    That class is using from getDataBuffer() from the Raster class; and there we find:

    A class representing a rectangular array of pixels. A Raster encapsulates a DataBuffer that stores the sample values and a SampleModel that describes how to locate a given sample value in a DataBuffer.

    What happens in essence here: that Image object, in the end has an array of bytes that are supposed to contain certain information.

    That assignment:

    final byte[] targetPixels = ...
    

    retrieves a reference to that internal data; and then arrayCopy() is used to copy data into that array.

    For the record: that doesn't look like a good approach - as it only works when this copy action really affects the internals of that Image object. But what if that last call getData() would create a copy of the internal data?

    In other words: this code tries to gain direct access to internal data of some object; and then manipulate that internal data.

    Even if that works today, it is not robust; and might break easily in the future. The other thing: note that this code does a unconditional cast (DataBufferByte). That code throws a RuntimeException if the the buffer doesn't have exactly that type.

    Probably that is "all fine"; since it is all related to "AWT" classes which probably exist for ages; and will not change at all any more. But as said; this code has various potential issues.