title: Convert NV21 byte array into bitmap readable format
body: <p>Hey I'm creating small camera app I have implemented every things but I have one problem which is converting NV21 byte array into jpeg format<br>
  I have found many way but all of them even not working or work on some devices<br>
  <strong>firstly</strong>  i tried this snippet and it work on Xperia z2 5.2 but on galaxy s4 4.4.4 </p>
  
  <pre><code>bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
  </code></pre>
  
  <p>also this way works on same device and fail on the other  </p>
  
  <pre><code> int pich = camera.getParameters().getPreviewSize().height;
          int picw = camera.getParameters().getPreviewSize().width;
          int[] pix = new int[picw * pich];
          bitmap.getPixels(pix, 0, picw, 0, 0, picw, pich);
                      //  int R, G, B, Y;
                      for (int y = 0; y &lt; pich; y++) {
                          for (int x = 0; x &lt; picw; x++) {
                              int index = y * picw + x;
                            int R = (pix[index] &gt;&gt; 16) &amp; 0xff; 
                           int G = (pix[index] &gt;&gt; 8) &amp; 0xff;     
                      int B = pix[index] &amp; 0xff;
                     pix[index] = 0xff000000 | (R &lt;&lt; 16) | (G &lt;&lt; 8) | B;
                          }
                                    }
  </code></pre>
  
  <p><strong>secondly</strong> I tried many solutions to convert decode NV21 
  first one <code>renderscript</code> code </p>
  
  <pre><code>    public Bitmap convertYUV420_NV21toRGB8888_RenderScript(byte [] data,int W, int H, Fragment fragment) {
      // http://stackoverflow.com/questions/20358803/how-to-use-scriptintrinsicyuvtorgb-converting-byte-yuv-to-byte-rgba
      RenderScript rs;
      ScriptIntrinsicYuvToRGB yuvToRgbIntrinsic;
      rs = RenderScript.create(fragment.getActivity());
      yuvToRgbIntrinsic = ScriptIntrinsicYuvToRGB.create(rs, Element.U8_4(rs)); //Create an intrinsic for converting YUV to RGB.
  
      Type.Builder yuvType = new Type.Builder(rs, Element.U8(rs)).setX(data.length);
      Allocation in = Allocation.createTyped(rs, yuvType.create(), Allocation.USAGE_SCRIPT); //an Allocation will be populated with empty data when it is first created
  
      Type.Builder rgbaType = new Type.Builder(rs, Element.RGBA_8888(rs)).setX(W).setY(H);
      Allocation out = Allocation.createTyped(rs, rgbaType.create(), Allocation.USAGE_SCRIPT); //an Allocation will be populated with empty data when it is first created
  
      in.copyFrom(data);//Populate Allocations with data.
  
      yuvToRgbIntrinsic.setInput(in); //Set the input yuv allocation, must be U8(RenderScript).
      yuvToRgbIntrinsic.forEach(out); //Launch the appropriate kernels,Convert the image to RGB.
  
  
      Bitmap bmpout = Bitmap.createBitmap(W, H, Bitmap.Config.ARGB_8888);
      out.copyTo(bmpout); //Copy data out of Allocation objects.
      return bmpout;
  
  }
  </code></pre>
  
  <p>and also this code </p>
  
  <pre><code> void decodeYUV420SP(int[] rgb, byte[] yuv420sp, int width, int height) {
  
      final int frameSize = width * height;
  
      for (int j = 0, yp = 0; j &lt; height; j++) {
          int uvp = frameSize + (j &gt;&gt; 1) * width, u = 0, v = 0;
  
          for (int i = 0; i &lt; width; i++, yp++) {
  
              int y = (0xff &amp; ((int) yuv420sp[yp])) - 16;
  
              if (y &lt; 0)
  
                  y = 0;
  
              if ((i &amp; 1) == 0) {
  
                  v = (0xff &amp; yuv420sp[uvp++]) - 128;
  
                  u = (0xff &amp; 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 &lt; 0)
                  r = 0;
              else if (r &gt; 262143)
  
                  r = 262143;
              if (g &lt; 0)
                  g = 0;
              else if (g &gt; 262143)
  
                  g = 262143;
  
              if (b &lt; 0)
  
                  b = 0;
  
              else if (b &gt; 262143)
  
                  b = 262143;
  
              rgb[yp] = 0xff000000 | ((r &lt;&lt; 6) &amp; 0xff0000) | ((g &gt;&gt; 2) &amp; 0xff00) | ((b &gt;&gt; 10) &amp; 0xff);
          }
  
      }
  }
  </code></pre>
  
  <p>and finally I tried to save the image on sd card and then reopen it 
  but it also fail </p>
  
  <pre><code>File pictureFile = new File(filename);
              int pich = camera.getParameters().getPreviewSize().height;
              int picw = camera.getParameters().getPreviewSize().width;
              Rect rect = new Rect(0, 0,picw, pich);
              YuvImage img = new YuvImage(data, ImageFormat.NV21, picw, picw, null);
  
              try {
                  FileOutputStream fos = new FileOutputStream(pictureFile);
                  img.compressToJpeg(rect, 100, fos);
                  fos.write(data);
                  fos.close();
  </code></pre>
  
  <p>and this is the result with last 3 approach I had follow
  <a href="https://i.stack.imgur.com/J6mhi.jpg" rel="noreferrer"><img src="https://i.stack.imgur.com/J6mhi.jpg" alt="enter image description here"></a></p>