Метод 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 в вашем коде.
Надеюсь, что поможет!