Android Camera setPictureFormat и массив данных в onPictureTaken - PullRequest
2 голосов
/ 19 ноября 2011

Здравствуйте, я только что написал небольшое приложение для Android, которое берет изображение с камеры, и мне было интересно, что на самом деле делает метод параметров камеры setPictureFormat () и какое влияние он оказывает.Насколько я знаю camera.takePicture () на самом деле предоставляет только данные в обратном вызове JPEG.Так что я думаю, что массив данных, который поступает в onPictureTaken (), в любом случае является данными JPEG?Так почему я должен установить для этого параметра значение PixelFormat.RGB_565, например?И есть ли способ напрямую интерпретировать массив данных непосредственно в onPictureTaken () без, например, BitmapFactory.decodeByteArray?Что я нахожу довольно странным, так это то, что у меня полученное изображение с разрешением 2448 * 3264 соответствует 7990272 пикселям.Однако базовые данные, которые создали это изображение, имеют длину только около 2000000 пикселей.Если бы кто-нибудь мог уточнить это для меня, это было бы очень ценно.

1 Ответ

10 голосов
/ 19 ноября 2011

Метод setPictureFormat() применяет формат пикселей для байтовых массивов, возвращаемых в необработанных обратных вызовах и обратных вызовах postView, которые вы передаете takePicture(). Как упоминается в документации, эти обратные вызовы МОГУТ даже не происходить на оборудовании, у которого нет буферов для его поддержки, но если они произойдут, данные будут отформатированы в соответствии с этим параметром. Вы правы, что обратный вызов JPEG передает данные, уже сжатые в формат JPEG.

В вашем примере размер необработанного байтового массива будет варьироваться в зависимости от выбранного формата пикселей. Вы правы, что 2448 * 3264 = 7,990,272 пикселей, но каждый пиксель представлен числом байтов в массиве. Например, форматы, такие как NV16 или RGB_565, имеют 16 бит (2 байта) для представления каждого пикселя. Это означает, что фактическая длина необработанного байтового массива будет 15 980 554 (~ 15 МБ), что является очень большим объемом данных, сохраняемых в памяти за один раз (это почти весь размер кучи исходного G1). Вот почему не все устройства буферизируют и возвращают необработанные данные изображения.

Когда вы проверяете длину данных, возвращаемых в обратном вызове JPEG, вы смотрите на сжатые данные изображения JPEG, которые больше не являются необработанными растровыми изображениями. По этой причине результат будет намного меньше. Если бы вы раздули эти данные изображения JPEG обратно в растровое изображение (например, используя BitmapFactory), размер снова увеличился бы. Помните об этом, поскольку изображение такого размера, загруженное в память в виде растрового изображения ARGB_8888 (4 байта на пиксель), будет занимать ~ 32 МБ. Это простой путь к исключению OutOfMemoryException в вашем коде.

Надеюсь, что поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...