BitmapFactory.decodeByteArray()返回NULL

Ryo*_*far 20 java format camera android image

我正在使用相机的previewCallback尝试抓取图像.这是我正在使用的代码

private Camera.PreviewCallback mPrevCallback = new Camera.PreviewCallback() 
{
        public void onPreviewFrame( byte[] data, Camera Cam ) {
                Log.d("CombineTestActivity", "Preview started");
                Log.d("CombineTestActivity", "Data length = " 
                        + data.length );
                currentprev = BitmapFactory.decodeByteArray( data, 0, 
                        data.length );

               if( currentprev == null )
                   Log.d("CombineTestActivity", "currentprev is null" );

                Log.d("CombineTestActivity", "Preview Finished" );

        }
};
Run Code Online (Sandbox Code Playgroud)

数据的长度总是与576000相同.

此外,我尝试更改相机的参数,以便图像以不同的格式返回.这就是我这样做时的样子.

mCamera = Camera.open();
camParam = mCamera.getParameters();
camParam.setPreviewFormat( ImageFormat.RGB_565 );
mCamera.setParameters( camParam );
    mCamera.setPreviewCallback( mPrevCallback );
Run Code Online (Sandbox Code Playgroud)

但是,当我更改预览格式并将其保留为默认值NV21时,BitmapFactory.decodeByteArray将返回null.我也尝试将预览格式更改为JPEG类型.我甚至在ddms中得到了一个调试语句,这就是我得到的

"D/skia(14391):--- SkImageDecoder :: Factory返回null"

Qix*_*Qix 41

好吧,希望这会有所帮助.

搜索互联网寻找快速解决方案,并找到了完美的东西.

这适用于Android 2.1

感谢此页面中的 off3nsiv3 .

// Convert to JPG
Size previewSize = camera.getParameters().getPreviewSize(); 
YuvImage yuvimage=new YuvImage(data, ImageFormat.NV21, previewSize.width, previewSize.height, null);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
yuvimage.compressToJpeg(new Rect(0, 0, previewSize.width, previewSize.height), 80, baos);
byte[] jdata = baos.toByteArray();

// Convert to Bitmap
Bitmap bmp = BitmapFactory.decodeByteArray(jdata, 0, jdata.length);
Run Code Online (Sandbox Code Playgroud)

只需对off3nsiv3的代码进行一些修改就可以了.与手动解码相比,FPS仍然非常高.

对于上面的代码,80是jpeg质量(0从100,100是最好的).


小智 7

你可以尝试这个,它正在工作......

mCamera.setOneShotPreviewCallback(new Camera.PreviewCallback() {
                @Override
                public void onPreviewFrame(byte[] data, Camera camera) {
                    Camera.Parameters parameters = camera.getParameters();
                    int format = parameters.getPreviewFormat();
                    //YUV formats require more conversion
                    if (format == ImageFormat.NV21 || format == ImageFormat.YUY2 || format == ImageFormat.NV16) {
                        int w = parameters.getPreviewSize().width;
                        int h = parameters.getPreviewSize().height;
                        // Get the YuV image
                        YuvImage yuv_image = new YuvImage(data, format, w, h, null);
                        // Convert YuV to Jpeg
                        Rect rect = new Rect(0, 0, w, h);
                        ByteArrayOutputStream output_stream = new ByteArrayOutputStream();
                        yuv_image.compressToJpeg(rect, 100, output_stream);
                        byte[] byt = output_stream.toByteArray();
                        FileOutputStream outStream = null;
                        try {
                            // Write to SD Card
                            File file = createFileInSDCard(FOLDER_PATH, "Image_"+System.currentTimeMillis()+".jpg");
                            //Uri uriSavedImage = Uri.fromFile(file);
                            outStream = new FileOutputStream(file);
                            outStream.write(byt);
                            outStream.close();
                        } catch (FileNotFoundException e) {
                            e.printStackTrace();
                        } catch (IOException e) {
                            e.printStackTrace();
                        } finally {
                        }
                    }
                }
Run Code Online (Sandbox Code Playgroud)


Chi*_*aur 3

我正在尝试做同样的事情。根据此处此处的讨论,听起来人们decodeByteArray()从 Android 2.1/2.2 开始还没有运气处理 NV21 格式。它绝对无法在我的模拟器或我的 Droid Incredible 上工作,尽管我认为这会调用本机代码,因此它可能会在某些手机上工作,具体取决于驱动程序?

作为替代方案,您可以尝试用 Java 自行解码 NV21(请参阅上面的链接以获取示例),尽管这对于大多数情况来说显然太慢而无用。我在尝试发送不同的格式时也没有太多运气CameraPreview,并且我预计这对于尝试编写可跨不同硬件移植的代码会出现问题。如果您在 NDK 中编写 NV21 解码方法,您可能会稍微提高帧速率。

显然,由于尝试处理时的竞争条件,也存在稳定性问题CameraPreview,尽管我自己还没有证实这个问题。我认为您可以避免这种情况,并通过使用setPreviewCallbackWithBuffer()Android 2.1/2.2 中添加的缓冲预览回调方法来提高帧速率。这是在 2.1 中添加的,但一直隐藏到 2.2 为止。 要在 2.1 中使用它,您需要解决隐藏问题。

有些人建议MediaRecorder使用CameraPreview. 不幸的是,MediaRecorder似乎提供的预览帧比 更少CameraPreview,所以我不能推荐该路线。