title: Android Convert Raw data to Png image color is not good?
body: <p>I have tried to convert the pure raw data to png image. i am not able to get the correct output image with exact color. </p>
  
  <p>for reference i have attached the both raw file as well as image . please advice me to get the image with correct color.  i have added both image and raw file .</p>
  
  <p><strong>CODE</strong></p>
  
  <pre><code>File screensPath = new File(SCREENSHOT_FOLDER);
              screensPath.mkdirs();
  
              // construct screenshot file name
              StringBuilder sb = new StringBuilder();
              sb.append(SCREENSHOT_FOLDER);
              sb.append(Math.abs(UUID.randomUUID().hashCode()));  // hash code of UUID should be quite random yet short
              sb.append(".png");
              String file = sb.toString();
  
              // fetch the screen and save it
              Screenshot ss = null;
              try {
                  ss = retreiveRawScreenshot();
              } catch (Exception e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
              }
              if(ss!=null)
              {
              writeImageFile(ss, file);
              }
  
              incre++;
  
  
  
   private Screenshot retreiveRawScreenshot() throws Exception {
          try {
  
  
               InputStream    is = new FileInputStream("/mnt/sdcard/screenshots/ss"+incre+".raw");
              // retrieve response -- first the size and BPP of the screenshot
  
              StringBuilder sb = new StringBuilder();
              int c;
              while ((c = is.read()) != -1) {
                  if (c == 0) break;
                  sb.append((char)c);
              }
  
          //========================================= not used =====================================
              // parse it
              String[] screenData = sb.toString().split(" ");
              if (screenData.length &gt;= 3) {
                  System.out.println("$$$$$$$$$$$$$$$$$$$$$$$$$$$ ");
                  Screenshot ss = new Screenshot();
                  ss.width = Integer.parseInt(screenData[0]);
                  ss.height = Integer.parseInt(screenData[1]);
                  ss.bpp = Integer.parseInt(screenData[2]);
                  System.out.println("$$$$$$$$$$$$$$$$$$$$$$$$$$$ ");
                  // retreive the screenshot
                  // (this method - via ByteBuffer - seems to be the fastest)
                  ByteBuffer bytes = ByteBuffer.allocate (ss.width * ss.height * ss.bpp / 8);
                  is = new BufferedInputStream(is);   // buffering is very important apparently
  
                  byte[] rgbsnew = null;
                  toRGB565(bytes.array(), ss.width, ss.height, rgbsnew);
  
  
              //  is.read(bytes.array());             // reading all at once for speed
                  is.read(rgbsnew);               // reading all at once for speed
  
                  bytes.position(0);                  // reset position to the beginning of ByteBuffer
  
                  ss.pixels =ByteBuffer.wrap(rgbsnew);
  
                  // convert byte-buffer to integer
  
                  return ss;
              }
       //========================================= not used ==========================================        
              Screenshot ss = new Screenshot();
              ss.width = 320;
              ss.height = 480;
              ss.bpp = 16;
              ByteBuffer bytes = ByteBuffer.allocate (ss.width * ss.height * ss.bpp / 8);
              is = new BufferedInputStream(is);   // buffering is very important apparently
              is.read(bytes.array());             // reading all at once for speed
              bytes.position(0);                  // reset position to the beginning of ByteBuffer
              ss.pixels = bytes;
  
              //============================= newly tried to set raw to image view ==============================
              /*mRawImage = new RawImage();
              mRawImage.readHeader(1, bytes);
  
           // Receive framebuffer data.
              byte[] data = new byte[mRawImage.size];
              bytes = ByteBuffer.wrap(data);         
              mRawImage.data = data;
  
              Bitmap bmp=BitmapFactory.decodeByteArray(mRawImage.data,0,mRawImage.data.length);
  
              imageView1.setImageBitmap(bmp);*/
  
  
            //============================newly tried to set raw to image view  ===============================
              return ss;
          }
          catch (Exception e) {
  
          //  throw new Exception(e);
              return null;
          }
          finally {}
  
          //return null;
      }
  
      class Screenshot {
          public Buffer pixels;
          public int width;
          public int height;
          public int bpp;
  
          public boolean isValid() {
              if (pixels == null || pixels.capacity() == 0 || pixels.limit() == 0) return false;
              if (width &lt;= 0 || height &lt;= 0)  return false;
              return true;
          }
      }
  
  
      private void writeImageFile(Screenshot ss, String file) {
          //if (ss == null || !ss.isValid())      throw new IllegalArgumentException();
          //if (file == null || file.length() == 0)   throw new IllegalArgumentException();
  
          // resolve screenshot's BPP to actual bitmap pixel format
          Bitmap.Config pf;
          switch (ss.bpp) {
              //case 16:  pf = Config.RGB_565; break;
  
              case 16:    pf = Config.RGB_565; break;
              case 32:    pf = Config.ARGB_8888; break;
              default:    pf = Config.ARGB_8888; break;
          }
  //=====================================================================
          /*int[] rgb24 = new int[ss.pixels.capacity()];
          int i = 0;
          for (;i&lt;320*480;i++)
          {
              //uint16_t pixel16 = ((uint16_t *)gr_framebuffer[0].data)[i];
              //int pixel16=(IntBuffer)
                      int pixel16=Integer.parseInt(ss.pixels.position(i).toString());
  
  
  
  
              // RRRRRGGGGGGBBBBBB -&gt; RRRRRRRRGGGGGGGGBBBBBBBB
              // in rgb24 color max is 2^8 per channel (*255/32 *255/64 *255/32)
              rgb24[3*i+2]   = (255*(pixel16 &amp; 0x001F))/ 32;      //Blue
              rgb24[3*i+1]   = (255*((pixel16 &amp; 0x07E0) &gt;&gt; 5))/64;    //Green
              rgb24[3*i]     = (255*((pixel16 &amp; 0xF800) &gt;&gt; 11))/32;   //Red
          }
          //ss.pixels=rgb24;
  *///=====================================================================       
  
          // create appropriate bitmap and fill it wit data
          Bitmap bmp = Bitmap.createBitmap(ss.width, ss.height, pf);
          bmp.copyPixelsFromBuffer(ss.pixels);
  
          // handle the screen rotation
          int rot = getScreenRotation();
          if (rot != 0) {
              Matrix matrix = new Matrix();
              matrix.postRotate(-rot);
              bmp = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), matrix, true);
          }
  
          // save it in PNG format
          FileOutputStream fos;
          try {
              fos = new FileOutputStream(file);
          } catch (FileNotFoundException e) {
              throw new InvalidParameterException();
          }
          bmp.compress(CompressFormat.PNG, 100, fos);
      }
  
      private int getScreenRotation()  {
          WindowManager wm = (WindowManager)getSystemService(WINDOW_SERVICE);
          Display disp = wm.getDefaultDisplay();
  
          // check whether we operate under Android 2.2 or later
          try {
              Class&lt;?&gt; displayClass = disp.getClass();
              Method getRotation = displayClass.getMethod("getRotation");
              int rot = ((Integer)getRotation.invoke(disp)).intValue();
  
                  switch (rot) {
                      case Surface.ROTATION_0:    return 0;
                      case Surface.ROTATION_90:   return 90;
                      case Surface.ROTATION_180:  return 180;
                      case Surface.ROTATION_270:  return 270;
                      default:                    return 0;
                  }
          } catch (NoSuchMethodException e) {
              // no getRotation() method -- fall back to dispation()
              int orientation = disp.getOrientation();
  
              // Sometimes you may get undefined orientation Value is 0
              // simple logic solves the problem compare the screen
              // X,Y Co-ordinates and determine the Orientation in such cases
              if(orientation==Configuration.ORIENTATION_UNDEFINED){
  
                  Configuration config = getResources().getConfiguration();
                  orientation = config.orientation;
  
                  if(orientation==Configuration.ORIENTATION_UNDEFINED){
                      //if height and widht of screen are equal then
                      // it is square orientation
                      if(disp.getWidth()==disp.getHeight()){
                          orientation = Configuration.ORIENTATION_SQUARE;
                      }else{ //if widht is less than height than it is portrait
                          if(disp.getWidth() &lt; disp.getHeight()){
                              orientation = Configuration.ORIENTATION_PORTRAIT;
                          }else{ // if it is not any of the above it will defineitly be landscape
                              orientation = Configuration.ORIENTATION_LANDSCAPE;
                          }
                      }
                  }
              }
  
              return orientation == 1 ? 0 : 90; // 1 for portrait, 2 for landscape
          } catch (Exception e) {
              return 0; // bad, I know ;P
          }
      }
  
      //===========================================================================
      /**
       * Converts semi-planar YUV420 as generated for camera preview into RGB565
       * format for use as an OpenGL ES texture. It assumes that both the input
       * and output data are contiguous and start at zero.
       * 
       * @param yuvs the array of YUV420 semi-planar data
       * @param rgbs an array into which the RGB565 data will be written
       * @param width the number of pixels horizontally
       * @param height the number of pixels vertically
       */
  
      //we tackle the conversion two pixels at a time for greater speed
      private void toRGB565(byte[] yuvs, int width, int height, byte[] rgbs) {
          //the end of the luminance data
          final int lumEnd = width * height;
          //points to the next luminance value pair
          int lumPtr = 0;
          //points to the next chromiance value pair
          int chrPtr = lumEnd;
          //points to the next byte output pair of RGB565 value
          int outPtr = 0;
          //the end of the current luminance scanline
          int lineEnd = width;
  
          while (true) {
  
              //skip back to the start of the chromiance values when necessary
              if (lumPtr == lineEnd) {
                  if (lumPtr == lumEnd) break; //we've reached the end
                  //division here is a bit expensive, but's only done once per scanline
                  chrPtr = lumEnd + ((lumPtr  &gt;&gt; 1) / width) * width;
                  lineEnd += width;
              }
  
              //read the luminance and chromiance values
              final int Y1 = yuvs[lumPtr++] &amp; 0xff; 
              final int Y2 = yuvs[lumPtr++] &amp; 0xff; 
              final int Cr = (yuvs[chrPtr++] &amp; 0xff) - 128; 
              final int Cb = (yuvs[chrPtr++] &amp; 0xff) - 128;
              int R, G, B;
  
              //generate first RGB components
              B = Y1 + ((454 * Cb) &gt;&gt; 8);
              if(B &lt; 0) B = 0; else if(B &gt; 255) B = 255; 
              G = Y1 - ((88 * Cb + 183 * Cr) &gt;&gt; 8); 
              if(G &lt; 0) G = 0; else if(G &gt; 255) G = 255; 
              R = Y1 + ((359 * Cr) &gt;&gt; 8); 
              if(R &lt; 0) R = 0; else if(R &gt; 255) R = 255; 
              //NOTE: this assume little-endian encoding
              rgbs[outPtr++]  = (byte) (((G &amp; 0x3c) &lt;&lt; 3) | (B &gt;&gt; 3));
              rgbs[outPtr++]  = (byte) ((R &amp; 0xf8) | (G &gt;&gt; 5));
  
              //generate second RGB components
              B = Y2 + ((454 * Cb) &gt;&gt; 8);
              if(B &lt; 0) B = 0; else if(B &gt; 255) B = 255; 
              G = Y2 - ((88 * Cb + 183 * Cr) &gt;&gt; 8); 
              if(G &lt; 0) G = 0; else if(G &gt; 255) G = 255; 
              R = Y2 + ((359 * Cr) &gt;&gt; 8); 
              if(R &lt; 0) R = 0; else if(R &gt; 255) R = 255; 
              //NOTE: this assume little-endian encoding
              rgbs[outPtr++]  = (byte) (((G &amp; 0x3c) &lt;&lt; 3) | (B &gt;&gt; 3));
              rgbs[outPtr++]  = (byte) ((R &amp; 0xf8) | (G &gt;&gt; 5));
          }
      }
  </code></pre>
  
  <p>Thanks . 
                     <img src="https://i.stack.imgur.com/KD5GT.png" alt="Image"><a href="http://www.netsdi.com/Autoracing/ss10.zip" rel="nofollow noreferrer">RAW file </a></p>