2015-07-16 35 views
1

У меня есть изображение, снятое камерой, в формате RAW BGRA (массив байтов). Как сохранить его на диск, как файл JPG/PNG?Java - конвертировать RAW в JPG/PNG

Я попытался с ImageIO.write из Java API, но я получил ошибку IllegalArgumentException (изображение = нуль)

КОД:

try 
{ 
    InputStream input = new ByteArrayInputStream(img); 
    BufferedImage bImageFromConvert = ImageIO.read(input); 

    String path = "D:/image.jpg"; 

    ImageIO.write(bImageFromConvert, "jpg", new File(path)); 
} 
catch(Exception ex) 
{ 
    System.out.println(ex.toString()); 
} 

Обратите внимание, что "IMG" является RAW массив, и что не имеет значения.

+1

Если 'ImageIO.write (...)' жалуется, что 'image == null', это означает, что у вас нет изображения. Можете ли вы показать код, который вы используете для чтения на необработанном изображении, возможно? – haraldK

+0

Редактировать: код добавлен – ssnake

ответ

1

Проблема в том, что ImageIO.read делает не поддержка сырья RGB (или BGRA в вашем случае) пикселей. Он ожидает, что формат файла , как BMP, PNG или JPEG и т.д.

В коде выше, это приводит к bImageFromConvert стать null, и это является причиной возникновения этой ошибки.

Если у вас есть byte массив в формате BGRA, попробуйте следующее:

// You need to know width/height of the image 
int width = ...; 
int height = ...; 

int samplesPerPixel = 4; 
int[] bandOffsets = {2, 1, 0, 3}; // BGRA order 

byte[] bgraPixelData = new byte[width * height * samplesPerPixel]; 

DataBuffer buffer = new DataBufferByte(bgraPixelData, bgraPixelData.length); 
WritableRaster raster = Raster.createInterleavedRaster(buffer, width, height, samplesPerPixel * width, samplesPerPixel, bandOffsets, null); 

ColorModel colorModel = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), true, false, Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE); 

BufferedImage image = new BufferedImage(colorModel, raster, colorModel.isAlphaPremultiplied(), null); 

System.out.println("image: " + image); // Should print: image: [email protected]<hash>: type = 0 ... 

ImageIO.write(image, "PNG", new File(path)); 

Обратите внимание, что JPEG не хороший формат для хранения изображений с альфа-каналом. Хотя это возможно, большинство программ не отобразит его правильно. Поэтому я предлагаю использовать PNG вместо этого.

В качестве альтернативы вы можете удалить альфа-канал и использовать JPEG.

+1

Да, удалите альфу! Какая камера может фотографировать с альфа-информацией? (Выбор между JPEG и PNG зависит от того, является ли определенная потеря данных предпочтительной по сравнению с окончательным размером файла.) – usr2564301

+1

@ Jongware Хорошая точка. Мне тоже было интересно об этом. Возможно, камера использует 32-битное выравнивание по соображениям производительности. – haraldK

+0

Спасибо, я попробовал ваш код, но он сохраняет на диск прозрачное изображение, если я выберу формат PNG или темное изображение, если я выберу формат JPG. Как я могу это решить? – ssnake

Смежные вопросы