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; i255){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)