在最近项目中,因为特殊需要,底层相机往外输出了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 { }
相关推荐
从camera的onPreviewFrame捕捉到预览帧保存成视频,然后合并成视频
Camera预览时需要对yuv帧做水平翻转处理,直接在onPreviewFrame(byte[] data, Camera camera)里调用Mirror函数,处理完后的图片和预览效果成水平翻转关系。 nv21的镜像算法: private void Mirror(byte[] src, int...
获取Android手机摄像头的视频数据,像打开了相机的效果一样
主要介绍了Android编程中调用Camera时预览画面有旋转问题的解决方法,涉及Android针对Camera调用摄像头源码部分的相关修改技巧,需要的朋友可以参考下
您基本上必须覆盖 onPreviewFrame(byte[] data, Camera cam) 方法并将默认 YUV 转换为 RGB: int[] rgb = ImageProcessing.decodeYUV420SPtoRGB(data, width, height); 创建一个用于运动检测代码的对象:
Android SDK支持內置攝像頭的連接。使用相機拍攝的照片是相對比較容易。設置攝像頭預覽正常工作 在我們的主要活動中,我們創建預覽對象。此對象將創建Camera對象和返回它的CameraDemo活動。
屏幕录像机屏幕录像机屏幕录像机屏幕录像机屏幕录像机
该隐相机介绍CainCamera是一个集美颜相机,图片编辑,短视频编辑等功能的综合性开源APP,目前主要介绍美颜相机,短视频编辑功能的实现,图片编辑功能暂时还没时间处理。于学习如何实现相机的实时美颜,动态滤镜,...
1 需求 公司的多款工具类app都用到了相机扫码功能。...为了方便查看扫码识别速度,我们在相机预览的回调方法onPreviewFrame中添加了如下代码来打印耗时: @Override public void onPreviewFrame(byte[] d
主要是在手机客户端(Android)通过实现Camera.PreviewCallback接口,在其onPreviewFrame重载函数里面获取摄像头当前图像数据,然后通过Socket将图像数据和相关的用户名、命令等数据传输到服务器程序中。服务器端...