Я не понимаю код для загрузки изображения в Java

Я работаю с OpenCV в Java, но я не понимаю часть класса, который загружает изображения в 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 - и что это делает?

3 ответа

Решение

Дело не столько в этом массиве, сколько в методах, которые помогут вам.

Вы начинаете здесь: getRaster (). Это должно вернуть WritableRaster... и так далее.

Этот класс используется из getDataBuffer() из класса Raster; и там мы находим:

Класс, представляющий прямоугольный массив пикселей. Растр инкапсулирует DataBuffer, который хранит значения выборки, и SampleModel, который описывает, как найти данное значение выборки в DataBuffer.

Что происходит по сути здесь: этот объект Image, в конце концов, имеет массив байтов, которые должны содержать определенную информацию.

Это назначение:

final byte[] targetPixels = ...

извлекает ссылку на эти внутренние данные; а потом arrayCopy() используется для копирования данных в этот массив.

Для записи: это не выглядит хорошим подходом - так как он работает только тогда, когда это действие копирования действительно влияет на внутреннюю часть этого объекта Image. Но что, если этот последний звонок getData() создаст копию внутренних данных?

Другими словами: этот код пытается получить прямой доступ к внутренним данным какого-либо объекта; а затем манипулировать этими внутренними данными.

Даже если это работает сегодня, это не надежно; и может легко сломаться в будущем. Другое дело: обратите внимание, что этот код выполняет безусловное приведение (DataBufferByte), Этот код генерирует исключение RuntimeException, если буфер не имеет именно этот тип.

Вероятно, это "все хорошо"; поскольку все это связано с классами "AWT", которые, вероятно, существуют целую вечность; и больше не изменится. Но, как сказал; этот код имеет различные потенциальные проблемы.

targetPixels это основные данные изображения (то есть пиксели) вашего нового изображения. Фактическое изображение создается, когда пиксельные данные копируются из buffer в targetPixels,

targetPixels - это массив байтов из вашего недавно созданного BufferedImage, эти байты пусты, поэтому вам нужно скопировать байты из буфера в него с помощью System.arraycopy..:)

Другие вопросы по тегам