Растровое изображение из Camera2 байта огромно - PullRequest
0 голосов
/ 25 июня 2019

Я использую пример Google, приведенный здесь .Я изменил OnImageAvailableListener следующим образом:

private final ImageReader.OnImageAvailableListener mOnImageAvailableListener
        = reader -> {
            Image image = reader.acquireLatestImage();
            ByteBuffer buffer = image.getPlanes()[0].getBuffer();
            byte[] bytes = new byte[buffer.remaining()];
            buffer.get(bytes);
            image.close();

            String pictureId = "asdasd";

            Bitmap bitmap = createMutableBitmap(bytes);
            StorageClass.getInstance().put(pictureId, bitmap);


            Intent intent = new Intent(Camera2MainActivity.this, TPCameraPreviewSnapActivity.class);
            intent.setType("image/*");
            intent.putExtra("pictureId", pictureId);

            startActivityForResult(intent, 1123);
        };

Там, где начинаются новые намерения, используется PhotoView для отображения растрового изображения.StorageClass обеспечивает статический способ обмена большими данными (например, этими растровыми изображениями) между намерениями.

Кроме того, метод createMutableBitmap:

public static Bitmap createMutableBitmap(byte[] data){
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inMutable = true;
    Log.d(TAG, "BT1: " + data.length);
    Bitmap mutableBitmap = BitmapFactory.decodeByteArray(data, 0, data.length, options);
    Log.d(TAG, "BT2: " + mutableBitmap.getByteCount());
    return mutableBitmap;
}

После выполнения этого кода вHuawei P30 Pro Я получаю вывод примерно так:

W/ImageReader_JNI: Unable to acquire a buffer item, very likely client tried to acquire more than maxImages buffers
E/ion: ioctl c0044901 failed with code -1: Invalid argument
D/Camera2BasicFragment: BT1: 1019119
W/ServiceManagement: getService: unable to call into hwbinder service for vendor.huawei.hardware.jpegdec@1.0::IJpegDecode/default.
D/HwAppInnerBoostImpl: asyncReportData rs.tp.camera2verifiedbypi,1,1,10,0 interval=2774
D/Camera2BasicFragment: BT2: 159694848

Независимо от того, как я изменяю качество изображения JPEG, число 159694848 выскакивает.159694848 байт - это ~ 160 МБ.

Впоследствии, при попытке установить Bitmap в качестве источника для

`PhotoView`, I get an exception:
E/BitmapDrawable: Canvas: trying to use a recycled bitmap
W/System.err: java.lang.RuntimeException: Canvas: trying to draw too large(159694848bytes) bitmap.

Этот пример с моими изменениями отлично работает на всех других телефонах, которые я пробовал, но онипод управлением Android 8 или ниже.

Итак, в чем причина этой проблемы и как ее устранить?

Ответы [ 2 ]

2 голосов
/ 26 июня 2019

Какое разрешение JPEG вы захватываете?Растровое изображение размером 160 МБ, предполагающее наличие внутренней памяти ARGB, составляет 4 байта на пиксель, поэтому 160/4 = 40 миллионов пикселей.

От https://www.gsmarena.com/huawei_p30_pro-9635.php, Huawei P30 Pro действительно имеет основную камеру на 40 Мп(при использовании в режиме Quad-Bayer), так что это все согласованно.

Тем не менее, компоненты Android View на самом деле не ожидают прохождения Bitmap на 40 мегапикселей;поскольку разрешение экрана составляет всего 1080 x 2340 пикселей = 2,5 Мп, нет нужды пытаться нарисовать 40 Мп на этом экране.

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

0 голосов
/ 25 июня 2019

Растровое изображение всегда бескомпромиссное, оно не имеет ничего общего со сжатием JPEG.Растровое изображение в формате ARGB всегда будет количеством пикселей x 4 для его размера (1 байт каждый для альфа, красного, зеленого, синего).Поэтому, если у вас есть растровое изображение размером 1000x1000 пикселей, оно всегда будет иметь размер 4 МБ при загрузке в память.Сжатие JPEG применяется только к файлам, хранящимся на диске, изображения в памяти всегда распакованы.

Вы можете использовать меньшие растровые изображения, используя 4 бита на канал, за счет цветопередачи или можете изменить их размер.

...