`
wang_peng1
  • 浏览: 3944259 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

onPreviewFrame 相机输出格式转换yuv420p保存成图片

 
阅读更多
在最近项目中,因为特殊需要,底层相机往外输出了i420 也就是yuv420p,输出的bytes 需要转成换h264,同时某个时间还需要保存一张图片,如何将i420 转jpeg ?可以ffmpeg 也可以libjpeg 但是我不需要这些库,仅仅为了一个图片 加载一个库 没有必要,同时对图片处理眉头特殊需求,所以 目前的方式是: i420 -argb-jpeg

public static void generateWarnPic(final byte[] picData,final int width,final int height){

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    String fileName = System.currentTimeMillis() + ".jpg";
                    File file = new File(GlobalDefineUtil.WARN_PIC_PATH + fileName);

                    if(!file.getParentFile().exists()){
                        file.getParentFile().mkdirs();
                    }

                    int [] argb=ColorConversion.I420toARGB(picData,width, height);
                    Bitmap bitmap = Bitmap.createBitmap(argb,width,height, Bitmap.Config.ARGB_8888);



                    FileOutputStream fileOutputStream;
                    try {
                        fileOutputStream = new FileOutputStream(file);
                        bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fileOutputStream);

                        fileOutputStream.close();
                    } catch (IOException e) {

                    }

                    //update db
//                    WarnPicDao dao = new WarnPicDao();
//                    dao.updateImages(fileName);
                } catch (Exception e) {
                    Log.i("yy", e.getMessage());
                }

            }
        }).start();

    }


public static int[] I420toARGB(byte[] yuv, int width, int height)
    {

        boolean invertHeight=false;
        if (height<0)
        {
            height=-height;
            invertHeight=true;
        }

        boolean invertWidth=false;
        if (width<0)
        {
            width=-width;
            invertWidth=true;
        }



        int iterations=width*height;
//if ((iterations*3)/2 > yuv.length){throw new IllegalArgumentException();}
        int[] rgb = new int[iterations];

        for (int i = 0; i<iterations;i++)
        {
	/*int y = yuv[i] & 0x000000ff;
	int u = yuv[iterations+(i/4)] & 0x000000ff;
	int v = yuv[iterations + iterations/4 + (i/4)] & 0x000000ff;*/
            int nearest = (i/width)/2 * (width/2) + (i%width)/2;

            int y = yuv[i] & 0x000000ff;
            int u = yuv[iterations+nearest] & 0x000000ff;


            int v = yuv[iterations + iterations/4 + nearest] & 0x000000ff;

            //int b = (int)(1.164*(y-16) + 2.018*(u-128));
            //int g = (int)(1.164*(y-16) - 0.813*(v-128) - 0.391*(u-128));
            //int r = (int)(1.164*(y-16) + 1.596*(v-128));

            //double Y = (y/255.0);
            //double Pr = (u/255.0-0.5);
            //double Pb = (v/255.0-0.5);



	/*int b = (int)(1.164*(y-16)+1.8556*(u-128));

	int g = (int)(1.164*(y-16) - (0.4681*(v-128) + 0.1872*(u-128)));
	int r = (int)(1.164*(y-16)+1.5748*(v-128));*/

            int b = (int)(y+1.8556*(u-128));

            int g = (int)(y - (0.4681*(v-128) + 0.1872*(u-128)));

            int r = (int)(y+1.5748*(v-128));


	/*double B = Y+1.8556*Pb;

	double G = Y - (0.4681*Pr + 0.1872*Pb);
	double R = Y+1.5748*Pr;*/

            //int b = (int)B*255;
            //int g = (int)G*255;
            //int r = (int)R*255;





            if (b>255){b=255;}
            else if (b<0 ){b = 0;}
            if (g>255){g=255;}
            else if (g<0 ){g = 0;}
            if (r>255){r=255;}
            else if (r<0 ){r = 0;}

	/*rgb[i]=(byte)b;
	rgb[i+1]=(byte)g;
	rgb[i+2]=(byte)r;*/
            int targetPosition=i;

            if (invertHeight)
            {
                targetPosition=((height-1)-targetPosition/width)*width   +   (targetPosition%width);
            }
            if (invertWidth)
            {
                targetPosition=(targetPosition/width)*width    +    (width-1)-(targetPosition%width);
            }


            rgb[targetPosition] =  (0xff000000) | (0x00ff0000 & r << 16) | (0x0000ff00 & g << 8) | (0x000000ff & b);
        }
        return rgb;

    }

 如果你输出格式是nv21 或者 yuy2 转图片就很简单了

FileOutputStream outStream = null;
                        try {
                            YuvImage yuvimage = new YuvImage(bytes,ImageFormat.YUY2,camera.getParameters().getPreviewSize().width,camera.getParameters().getPreviewSize().height,null);
                            ByteArrayOutputStream baos = new ByteArrayOutputStream();
                            yuvimage.compressToJpeg(new Rect(0,0,camera.getParameters().getPreviewSize().width,camera.getParameters().getPreviewSize().height), 80, baos);

                            outStream = new FileOutputStream("/mnt/sdcard/" +System.currentTimeMillis()+".jpg");
                            outStream.write(baos.toByteArray());
                            outStream.flush();
                            outStream.close();


                        } catch (FileNotFoundException e) {
                            e.printStackTrace();
                            Log.i("yy", "1111111111111111111");
                        } catch (IOException e) {
                            e.printStackTrace();
                        } finally {
                        }

 

分享到:
评论

相关推荐

    Android camera实时预览 实时处理,人脸识别示例

    在Android中,相机预览的帧数据默认为YUV_420_888格式。因此,我们需要将这些数据转换成RGB或Bitmap格式,以便进一步处理。这可以通过`YuvImage`类完成,它可以从YUV数据创建一个Bitmap对象,然后我们可以利用这个...

    Android 实时滤镜 高斯模糊

    一种常见的方法是使用`YUV420sp`到`RGB`的转换算法。 ```java public static int[] yuvToRgb(byte[] yuv420sp, int width, int height) { // 转换代码... } ``` 接下来,我们要对转换后的图像应用高斯模糊。高斯...

    android一个采集图像 并可以把预览回调传回数据做处理

    通常,这些数据是YUV格式,需要转换为RGB或其他格式进行处理。例如,可以使用`YUV_420_888`到`Bitmap`的转换代码,然后执行图像处理算法,如滤波、识别等。 6. **拍照和录制视频**: 当需要保存图像或录制视频时,...

    android camera 数据预览和处理代码

    在`onPreviewFrame`回调中,我们将接收到YUV格式的原始图像数据。YUV是一种常见的图像编码格式,包含亮度(Y)和两个色度分量(U和V)。为了处理这些数据,我们需要将其转换为更常见的RGB格式。可以使用OpenCV库或者...

    安卓Android源码——camera,修改过可以在4.0系统上运行。.zip

    `SurfaceTexture`类在此过程中起着关键作用,它可以接收相机的YUV数据并转换为OpenGL纹理,用于在SurfaceView或TextureView上显示。 6. **图像处理和编码**:在Android 4.0中,图像捕获和编码主要由`Camera`类的`...

    Android实时视频采集编码传输解码播放的方案调研.pdf

    - **原理**:将原始YUV420SP视频帧压缩转换为JPEG格式,JPEG传输。 - **优点**:压缩效率较高,适用于图像质量要求较高的场景。 - **缺点**:不适合运动剧烈的视频流,因为JPEG主要采用帧内压缩。 3. **H.264/...

    PreviewCallback纠正图像方向

    当相机捕获到一帧图像时,它会调用这个接口的onPreviewFrame方法,传递一个包含原始YUV格式的byte数组。这个回调可以用来实时显示预览图像,或者进行一些图像处理,比如我们在这里关注的方向校正。 图像方向的纠正...

    android条码扫描程序源码

    - **Bitmap处理**:将相机捕获的YUV格式帧数据转换为`Bitmap`,便于处理。 - **DecodingProcess**:ZXing库中的解码过程,通过`LuminanceSource`和`BinaryBitmap`接口将图像数据转换成适合解码的形式,然后使用`...

    android-motion-detector:这是 Justin Wetherell 的原始 android-motion-detection 库的 Gradle 版本

    您基本上必须覆盖 onPreviewFrame(byte[] data, Camera cam) 方法并将默认 YUV 转换为 RGB: int[] rgb = ImageProcessing.decodeYUV420SPtoRGB(data, width, height); 创建一个用于运动检测代码的对象:

    android 二维码扫描 支持横竖屏切换Demo

    // 将YUV数据转换成Bitmap Bitmap bitmap = YuvImage.convertYUVToBitmap(data, previewWidth, previewHeight, camera.getParameters().getPreviewFormat()); // 使用ZXing解码 Result result = decode(bitmap);...

    Android 人脸识别功能使用源码.zip

    - 使用`Camera.getParameters().getPreviewFormat()`确定数据格式,然后根据格式转换数据到RGB或灰度图像。 - 创建`android.media.FaceDetector`实例,传入图像数据、宽度、高度和期望检测的最大人脸数。 2. **...

    Android 开发 API人脸检测实例教程-IT计算机-毕业设计.zip

    这个过程涵盖了Android的Camera API使用、数据格式转换、图像处理以及Vision API的集成,对于Android毕业设计或论文研究具有很高的参考价值。在实践中,还可以进一步优化性能,例如采用异步处理、减少计算量或利用...

    安卓Andriod源码——二维码扫描案例.zip

    在`onPreviewFrame()`方法中,需要将YUV格式的图像数据转换为RGB,然后传递给ZXing的解码器进行解码。 6. **解码流程**: - ZXing库提供了解码器,如MultiFormatReader,它可以识别多种条码和二维码格式。将图像...

Global site tag (gtag.js) - Google Analytics