Хорошо задокументировано, что данные предварительного просмотра камеры Android возвращаются в NV21 (YUV 420). 2.2 добавлен класс YuvImage для декодирования данных. Проблема, с которой я столкнулся, заключается в том, что данные класса YuvImage выглядят поврежденными или неверными. Я использовал приложение Renderscript Sample под названием HelloCompute, которое преобразует Bitmap в монохромный Bitmap. Я использовал два метода для декодирования данных предварительного просмотра в Bitmap и передачи их в качестве входных данных в Renderscript:
Метод 1. Класс Android YuvImage:
YuvImage preview = new YuvImage(data, ImageFormat.NV21, width, height, null);
ByteArrayOutputStream mJpegOutput = new ByteArrayOutputStream(data.length);
preview.compressToJpeg(new Rect(0, 0, width, height), 100, mJpegOutput);
mBitmapIn = BitmapFactory.decodeByteArray( mJpegOutput.toByteArray(), 0, mJpegOutput.size());
// передаем mBitmapIn в RS
Метод 2 - Метод опубликованного декодера: Как написано здесь Дэвид Перлман
// work around for Yuv format </p>
mBitmapIn = Bitmap.createBitmap(
ImageUtil.decodeYUV420SP(data, width, height),
width,
height,
Bitmap.Config.ARGB_8888);
// pass mBitmapIn to RS
Когда изображение обрабатывается Renderscript и отображается, метод 1 является очень зернистым и не монохромным, тогда как метод 2 дает ожидаемый результат - монохромное изображение кадра предварительного просмотра. Я что-то делаю не так или класс YuvImage неприменим? Я тестирую это на Xoom под управлением 3.1.
Кроме того, я отображал растровые изображения, созданные обоими методами, на экране перед переходом в RS. Растровое изображение из метода 1 имеет заметные различия в освещении (я подозревал, что это произошло из-за сжатия JPeg), в то время как растровое изображение из метода 2 идентично кадру предварительного просмотра.