2013-07-23 4 views
2

Я пытаюсь получить 16-битное цветное изображение, разрешение 80 х 60 от встроенной камеры (datasheet here). Я успешно могу получить 9600 (80 * 60 * 16/8) байтов с камеры, но у меня проблема с отображением изображения. Я использую следующий код для преобразования массива байтов в Bitmap:Android-изображение с 16-битным цветом в растровое изображение

bm = Bitmap.createBitmap(80, 60, Bitmap.Config.RGB_565); 
bm.copyPixelsFromBuffer(ByteBuffer.wrap(jpegBytes)); 

jpegBytes является массив байтов на изображение и оно имеет длину 9600 байт.

Прямо сейчас, я получаю изображения, которые выглядят так:

corrupted image

99% времени. Тем не менее, я могу получить неповрежденного изображения, которые выглядят следующим образом:

uncorrupted image

очень редко. Есть ли у кого-нибудь какие-либо предложения относительно того, почему это происходит? Спасибо!

UPDATE:

Похоже, все пиксели находятся в правильном месте, но иметь их значения RGB смешиваются. Например, белая часть между обеими фотографиями одинакова, потому что порядок RGB не имеет значения, чтобы получить белый цвет. Тем не менее, очевидно, что цвета смешиваются, потому что красный стул отображается как синие в поврежденном изображении и синий рюкзак отображается как зеленый в поврежденных изображениях

+0

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

+0

Согласно техническому описанию камеры, изображение должно быть передано в формате RGB_565. Мне удалось получить 4-битные и 8-битные изображения в оттенках серого с камеры и отобразить их с помощью ARGB_8888, но приложение вылетает, когда я использую ARGB_8888 для отображения 16-битного изображения. Это связано с тем, что в 16-битном изображении есть 2 байта на пиксель, а не 4 байта на пиксель, что требуется ARGB_8888. –

+0

Возможно, это проблема с порядком байтов. Что произойдет, если вы используете 'bm.copyPixelsFromBuffer (ByteBuffer.wrap (jpegBytes) .order (ByteOrder.LITTLE_ENDIAN));'? –

ответ

1

Использование Config.ARGB_8888 в растровой конфигурации

Из документов для public static final Bitmap.Config RGB_565:

Каждый пиксель хранится на 2 байта, и только RGB каналы кодируются: красный сохраняется с 5 битами точности (32 возможных значений), зеленый цвет хранится вместе с 6 битами точность (64 возможных значения) и синий - хранятся с точностью до 5 бит. Эта конфигурация может создавать незначительные визуальные артефакты в зависимости от конфигурации источника. Для примера , без сглаживания, результат может иметь зеленоватый оттенок. К следует применять улучшающие результаты сглаживание результатов. Эта конфигурация может быть полезна при использовании непрозрачных растровых изображений, которые не требуют высокого цвета. верность.

+0

Если данные в буфере не соответствуют формату ARGB_8888 (OP говорит, что это не так), это не сработает. –

+0

Согласно [datasheet] камеры (http://www.mouser.com/ds/2/451/uCAM-DS-rev7-3555.pdf), стр. 8 говорит, что 16-битное цветное изображение передается как необработанное 565 (RGB), поэтому Android RGB_565 должен теоретически работать. –

0

Я был с аналогичной проблемой, и это, как я решить:

(1) Проверьте массив байтов вы получили, посмотреть, если вам нужно повернуть его вспять, прежде чем завернуть его в ByteBuffer

(2) Проверьте порядок байтов ByteBuffer, посмотреть, если вам нужно изменить его на небольшой Endian (порядок байт по умолчанию является большой обратный порядок байт)

в моем случае, я должен первый обратный массив байтов, изменить ByteBuffer к маленькому конечному, тогда я могу получить правильное изображение.

псевдокод:

byte[] imageData ; (byte array received) 
reverseByteArray(imageData); 

Bitmap bitmap = Bitmap.createBitmap(imgWidth, imgHeight,Bitmap.Config.RGB_565); 

ByteBuffer buffer = ByteBuffer.wrap(imageData); 
ByteBuffer newBuffer = ByteBuffer.allocate(buffer.capacity()); 
newBuffer.order(ByteOrder.LITTLE_ENDIAN); 
for (int i = 0; i < buffer.capacity(); i++) { 
      byte b = buffer.get(i); 
      newBuffer.put(b); 
     } 
newBuffer.flip(); 
bitmap.copyPixelsFromBuffer(newBuffer); 
setImage(bitmap); 

//------ 
public static void reverseByteArray(byte[] array) { 
     if (array == null) { 
      return; 
     } 
     int i = 0; 
     int j = array.length - 1; 
     byte tmp; 
     while (j > i) { 
      tmp = array[j]; 
      array[j] = array[i]; 
      array[i] = tmp; 
      j--; 
      i++; 
     } 
    } 
Смежные вопросы