不能总是从Camera2Raw示例程序中获取原始文件的问题。

问题描述 投票:0回答:1

我在使用AndroidStudio自带的示例程序时遇到了一个问题。我只在S8上试过,所以我不确定这是这个特定设备的问题还是通用的。

如果我尝试在一次拍摄中拍摄多张照片,通过将mPendingUserCaptures设置为像4这样的数字,特别是如果我手动将曝光时间设置为一个低值(通常低于30ms左右),我总是得到4张JPG图像,但有时我只得到3个原始文件(最后一个丢失).问题是在ImageSaver类中,它并不总是为RAW文件调用,但总是为JPG调用。

我想知道,有没有人经历过这样的事情,当一个RAW图像有时不会到达?

android-camera2
1个回答
0
投票

好了,所以经过几个星期的狩猎这个错误的和关闭,我终于找到了发生了什么事.我在这里发布的解决方案,只是为了防止别人绊倒周围这个问题。

有时函数 public void onImageAvailable(ImageReader reader) { dequeueAndSaveImage(mRawResultQueue, mRawImageReader); }会被连续调用两次。

代码是这样的。

    Map.Entry<Integer, ImageSaver.ImageSaverBuilder> entry = pendingQueue.firstEntry();
    ImageSaver.ImageSaverBuilder builder = entry.getValue();

这就产生了一个巨大的问题,因为有时两个图像会被添加到同一个TreeMap条目中,所以如果我们有4个条目,最后一个条目将永远不会得到它的图像。

The fixed code (I left my extra logs there) looks like this:

   private void dequeueAndSaveImage(TreeMap<Integer, ImageSaver.ImageSaverBuilder> pendingQueue, RefCountedAutoCloseable<ImageReader> reader) {
        synchronized (mCameraStateLock) {

            ImageSaver.ImageSaverBuilder builder=null;
            Map.Entry<Integer, ImageSaver.ImageSaverBuilder> entry;
            int key=4;//shut up, stupid java shit
            for (Map.Entry<Integer, ImageSaver.ImageSaverBuilder> ent : pendingQueue.entrySet()) {
                builder = ent.getValue();
                if(builder.mImage==null) {
                    key = ent.getKey();
                    break;
                }

            }

            //Map.Entry<Integer, ImageSaver.ImageSaverBuilder> entry = pendingQueue.firstEntry();
            //ImageSaver.ImageSaverBuilder builder = entry.getValue();
            Log.w(TAG, "StartingdequeueAndSaveImage, builder: " + builder);

            if(builder.mImage!=null)
            {
                Log.w(TAG, "!!!!!!!!!!!!!!!!!!!!Builder: " + builder + " already has an image!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
            }

            // Increment reference count to prevent ImageReader from being closed while we
            // are saving its Images in a background thread (otherwise their resources may
            // be freed while we are writing to a file).
            if (reader == null || reader.getAndRetain() == null) {
                Log.e(TAG, "Paused the activity before we could save the image," + " ImageReader already closed.");
                pendingQueue.remove(key);
                return;
            }

            Image image;
            try {
                image = reader.get().acquireNextImage();
            } catch (IllegalStateException e) {
                Log.e(TAG, "Too many images queued for saving, dropping image for request: " + key);
                pendingQueue.remove(key);
                return;
            }

            builder.setRefCountedReader(reader).setImage(image);

            if(image==null)Log.e(TAG, "Cacatul de imagine e null...... Sa ma fut in mortii lor.");

            handleCompletionLocked(key, builder, pendingQueue);
            Log.e(TAG, "Call handled completed in deque" + pendingQueue);
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.