【问题标题】:Android byte[] to image in Camera.onPreviewFrameAndroid byte[] 到 Camera.onPreviewFrame 中的图像
【发布时间】:2015-10-15 21:33:05
【问题描述】:

当尝试使用BitmapFactory.decodeByteArrayCamera.onPreviewFramebyte[] 转换为Bitamp 时出现错误SkImageDecoder::Factory returned null

以下是我的代码:

public void onPreviewFrame(byte[] data, Camera camera) {
    Bitmap bmp=BitmapFactory.decodeByteArray(data, 0, data.length);
}

【问题讨论】:

标签: android image byte decoding


【解决方案1】:

这很难找到!但是从 API 8 开始,在 android.graphics 中有一个 YuvImage 类。它不是 Image 的后代,因此您可以将其保存为 Jpeg,但您可以将其保存到内存流中,然后根据需要加载到 Bitmap Image 中。

import android.graphics.YuvImage;

@Override
public void onPreviewFrame(byte[] data, Camera camera) {
    try {
        Camera.Parameters parameters = camera.getParameters();
        Size size = parameters.getPreviewSize();
        YuvImage image = new YuvImage(data, parameters.getPreviewFormat(),
                size.width, size.height, null);
        File file = new File(Environment.getExternalStorageDirectory()
                .getPath() + "/out.jpg");
        FileOutputStream filecon = new FileOutputStream(file);
        image.compressToJpeg(
                new Rect(0, 0, image.getWidth(), image.getHeight()), 90,
                filecon);
    } catch (FileNotFoundException e) {
        Toast toast = Toast
                .makeText(getBaseContext(), e.getMessage(), 1000);
        toast.show();
    }
}

【讨论】:

  • 这是一个非常老套的解决方案。保存为 jpeg 然后立即解码?我想我宁愿使用自定义 YUV 函数。
  • @Timmmm 我同意不难发现的自定义 YUV 函数比通过 jpeg 保存和加载更好。但是,如果您只想保存到 jpeg,这仍然是最好的。我觉得很遗憾YuvImage 不是Image 的后代,那么它就不需要任何黑客或自我 YUV 编码。
【解决方案2】:

从 Android 3.0 开始,您可以使用 TextureViewTextureSurface 显示相机,然后使用 mTextureView.getBitmap() 检索友好的 RGB 预览帧。

the TextureView docs 中给出了如何做到这一点的一个非常简单的示例。请注意,您必须通过将 android:hardwareAccelerated="true" 放入清单中来将您的应用程序或活动设置为硬件加速。

【讨论】:

    【解决方案3】:

    找了很久才找到答案。在这里……

    我没有使用BitmapFactory,而是使用我的自定义方法将此byte[] data 解码为有效的图像格式。要将图像解码为有效的图像格式,需要通过调用camera.getParameters().getPictureFormat() 了解相机正在使用的图片格式。这将返回由ImageFormat 定义的常量。知道格式后,使用合适的编码器对图像进行编码。

    在我的例子中,byte[] dataYUV 格式,所以我寻找YUVBMP 的转换,这解决了我的问题。

    【讨论】:

    【解决方案4】:

    你可以试试这个: 此示例将相机帧发送到服务器

     @Override
            public void onPreviewFrame(byte[] data, Camera camera) {
            try {
                byte[] baos = convertYuvToJpeg(data, camera);
                StringBuilder dataBuilder = new StringBuilder();
                dataBuilder.append("data:image/jpeg;base64,").append(Base64.encodeToString(baos, Base64.DEFAULT));
                mSocket.emit("newFrame", dataBuilder.toString());
            } catch (Exception e) {
               Log.d("########", "ERROR");
            }
        }
    
    };
    
    
    public byte[] convertYuvToJpeg(byte[] data, Camera camera) {
    
        YuvImage image = new YuvImage(data, ImageFormat.NV21,
                camera.getParameters().getPreviewSize().width, camera.getParameters().getPreviewSize().height, null);
    
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        int quality = 20; //set quality
        image.compressToJpeg(new Rect(0, 0, camera.getParameters().getPreviewSize().width, camera.getParameters().getPreviewSize().height), quality, baos);//this line decreases the image quality
    
    
        return baos.toByteArray();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-06
      • 2014-10-04
      • 1970-01-01
      • 2010-11-17
      • 2010-10-09
      • 2018-07-07
      相关资源
      最近更新 更多