zoukankan      html  css  js  c++  java
  • Android -- 获取摄像头帧数据解码

    由于Android下摄像头预览数据只能  ImageFormat.NV21 格式的,所以解码时要经过一翻周折.

    Camera mCamera = Camera.open();
    
    Camera.Parameters p = mCamera.getParameters();
    
    p.setPreviewFormat(ImageFormat.NV21);
    
    /*这是唯一值,也可以不设置。有些同学可能设置成 PixelFormat 下面的一个值,其实是不对的,具体的可以看官方文档*/
    
    mCamera.setParameters(p);
    
    mCamera.startPreview();

    下面是解码核心部分:

    @Override
      public void onPreviewFrame(byte[] data, Camera camera) {        
          Size size = camera.getParameters().getPreviewSize();        
          try{
              YuvImage image = new YuvImage(data, ImageFormat.NV21, size.width, size.height, null);
              if(image!=null){
                  ByteArrayOutputStream stream = new ByteArrayOutputStream();
                  image.compressToJpeg(new Rect(0, 0, size.width, size.height), 80, stream);
                  Bitmap bmp = BitmapFactory.decodeByteArray(stream.toByteArray(), 0, stream.size());
     
                       stream.close();
              }
          }catch(Exception ex){
              Log.e("Sys","Error:"+ex.getMessage());
          }
      }

    代码很简单。就是把YUV数据转成 Bitmap 就行了,系统提供 YuvImage 类。

    yuv420sp转RGB                                                                       

    /**
             * 解码
             * 
             * @param rgb
             * @param yuv420sp
             * @param width
             * @param height
             */
            static public void decodeYUV420SP(int[] rgb, byte[] yuv420sp, int width, int height) {
                    final int frameSize = width * height;
    
                    for (int j = 0, yp = 0; j < height; j++) {
                            int uvp = frameSize + (j >> 1) * width, u = 0, v = 0;
                            for (int i = 0; i < width; i++, yp++) {
                                    int y = (0xff & ((int) yuv420sp[yp])) - 16;
                                    if (y < 0)
                                            y = 0;
                                    if ((i & 1) == 0) {
                                            v = (0xff & yuv420sp[uvp++]) - 128;
                                            u = (0xff & yuv420sp[uvp++]) - 128;
                                    }
    
                                    int y1192 = 1192 * y;
                                    int r = (y1192 + 1634 * v);
                                    int g = (y1192 - 833 * v - 400 * u);
                                    int b = (y1192 + 2066 * u);
    
                                    if (r < 0)
                                            r = 0;
                                    else if (r > 262143)
                                            r = 262143;
                                    if (g < 0)
                                            g = 0;
                                    else if (g > 262143)
                                            g = 262143;
                                    if (b < 0)
                                            b = 0;
                                    else if (b > 262143)
                                            b = 262143;
    
                                    rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000) | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff);
                            }
                    }
            }

    我是天王盖地虎的分割线                                                                 

  • 相关阅读:
    python基础之字符串和字节的转换
    python学习笔记(三)字符串方法、读写文件、json处理以及函数
    python学习笔记(二):list,字典,字符串,元组,文件
    python学习笔记(一):python入门
    接口测试:jmeter学习笔记:数据库操作和压测
    接口测试:postman和jmeter随记
    设计模式之建造者模式
    设计模式之外观模式
    设计模式之模板模式
    设计模式之原型模式
  • 原文地址:https://www.cnblogs.com/yydcdut/p/3887250.html
Copyright © 2011-2022 走看看