• 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);
                            }
                    }
            }

    我是天王盖地虎的分割线                                                                 

  • 相关阅读:
    JavaWeb--HttpSession案例
    codeforces B. Balls Game 解题报告
    hdu 1711 Number Sequence 解题报告
    codeforces B. Online Meeting 解题报告
    ZOJ 3706 Break Standard Weight 解题报告
    codeforces C. Magic Formulas 解题报告
    codeforces B. Sereja and Mirroring 解题报告
    zoj 1109 Language of FatMouse 解题报告
    hdu 1361.Parencodings 解题报告
    hdu 1004 Let the Balloon Rise 解题报告
  • 原文地址:https://www.cnblogs.com/yydcdut/p/3887250.html
Copyright © 2020-2023  润新知