Преобразование 4-битного массива в шкале серого в Bitmap Android

Я извлекаю необработанное изображение с камеры, и характеристики изображения выглядят следующим образом:

  • Разрешение 80 x 60
  • 4-битный оттенок серого

Я получаю изображение как массив байтов и имею массив длиной 2400 (1/2 * 80 * 60). Следующий шаг – преобразовать массив байтов в битмап. Я уже использовал

BitmapFactory.decodeByteArray(bytes, 0, bytes.length) 

Но это не привело к отображению отображаемого изображения. Я просмотрел этот пост и скопировал приведенный ниже код в свое приложение для Android, но получил ошибку «Ошибка не достаточно большой для пикселей».

 byte [] Src; //Comes from somewhere... byte [] Bits = new byte[Src.length*4]; //That's where the RGBA array goes. int i; for(i=0;i<Src.length;i++) { Bits[i*4] = Bits[i*4+1] = Bits[i*4+2] = ~Src[i]; //Invert the source bits Bits[i*4+3] = -1;//0xff, that's the alpha. } //Now put these nice RGBA pixels into a Bitmap object Bitmap bm = Bitmap.createBitmap(Width, Height, Bitmap.Config.ARGB_8888); bm.copyPixelsFromBuffer(ByteBuffer.wrap(Bits)); 

В нижней части потока исходный плакат имел ту же ошибку, что и у меня. Однако его проблема была исправлена ​​с помощью кода, вставленного выше. Есть ли у кого-нибудь предложения о том, как я должен преобразовать исходное изображение или массив RGBA в растровое изображение?

Спасибо!

ОБНОВИТЬ:

Я последовал за предложением Geobits, и это мой новый код

 byte[] seperatedBytes = new byte[jpegBytes.length * 8]; for (int i = 0; i < jpegBytes.length; i++) { seperatedBytes[i * 8] = seperatedBytes[i * 8 + 1] = seperatedBytes[i * 8 + 2] = (byte) ((jpegBytes[i] >> 4) & (byte) 0x0F); seperatedBytes[i * 8 + 4] = seperatedBytes[i * 8 + 5] = seperatedBytes[i * 8 + 6] = (byte) (jpegBytes[i] & 0x0F); seperatedBytes[i * 8 + 3] = seperatedBytes[i * 8 + 7] = -1; //0xFF } 

Теперь я могу получить битмап, используя эту команду

 Bitmap bm = BitmapFactory.decodeByteArray(seperatedBytes, 0, seperatedBytes.length); 

Но битмап имеет размер 0 КБ.

Изображение, которое я получаю, является сырым изображением с этой камеры . К сожалению, получение предварительно сжатого JPEG-изображения не является вариантом, потому что мне нужно 4-битное серое.

    Если входящее изображение находится только в 2400 байт, это означает, что на каждый байт приходится по два пикселя (по 4 бита). Вы предоставляете только байтовый буфер 2400 * 4 = 9600 байт, когда ARGB_8888 требуется 4 байта на пиксель, или 60 * 80 * 4 = 19200 .

    Вам нужно разбить каждый входящий байт на верхнее / нижнее значение nibble, а затем применить его к следующим 8 байтам (исключая альфу). Вы можете увидеть этот ответ на примере разделения байтов.

    В основном:

    • Разделите входящий байт i на два куска, ia и ib
    • Примените ia к исходящим байтам i*8 через (i*8)+2
    • Примените ib к исходящим байтам (i*8)+4 через (i*8)+6
    • Байты (i*8)+3 и (i*8)+7 являются альфа ( 0xFF )

    Если у вас есть нужный размерный байтовый буфер, вы можете без проблем использовать decodeByteArry() .

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

    Итак, первое, что вам нужно сделать, это отделить ваши значения оттенков серого в один байт каждый, так как BitmapFactory.decodeByteArray, вероятно, не сможет обрабатывать ваши «половинные байты». Это можно легко выполнить с помощью бит-операций. Чтобы получить первый 4-бит вашего байта `0bxxxxxxxx`, вам нужно сдвинуть вправо 4 раза:` 0bxxxxxxxx >> 4`, что приведет к `0b0000xxxx`. Второе значение может быть получено поразрядным или с шаблоном `0b00001111`:` 0b00001111 ^ 0bxxxxxxxx`, который приведет к `0b0000xxxx`. (Подробную информацию о битовых операциях см. Здесь: Бит-операции )

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

    Я не уверен, что этого достаточно для «BitmapFactory.decodeByteArray», или если вам нужно повторять каждый байт 4 раза для каждого RGBA-канала, что увеличит размер вашего байтового массива снова в четыре раза по сравнению с исходным размером , Надеюсь, я ничего не пропустил, и мои предложения помогают;)