title: ANDROID: Saving PreviewCallback image as a .jpg from a byte array results in a corrupt file
body: <p>I have been augmenting the QR scanning library Zxing to save a photo instantly upon scan. I was advised to do so within the onPreviewFrame method within PreviewCallback.java as thus:</p>
  
  <pre><code> public void onPreviewFrame(byte[] data, Camera camera) {
  Point cameraResolution = configManager.getCameraResolution();
  Handler thePreviewHandler = previewHandler;
  
  YuvImage im = new YuvImage(data, ImageFormat.NV21, 1200,
          800, null);
          Rect r = new Rect(0, 0, 1200, 800);
          ByteArrayOutputStream baos = new ByteArrayOutputStream();
          im.compressToJpeg(r, 50, baos);
  
          try {
              FileOutputStream output = new FileOutputStream("/sdcard/test_jpg.jpg");
              output.write(baos.toByteArray());
              output.flush();
              output.close();
  
              System.out.println("Attempting to save file");
              System.out.println(data);
          } catch (FileNotFoundException e) {
              System.out.println("Saving to file failed");
          } catch (IOException e) {
              System.out.println("Saving to file failed");
          }
  
  if (cameraResolution != null &amp;&amp; thePreviewHandler != null) {
    Message message = thePreviewHandler.obtainMessage(previewMessage, cameraResolution.x,
        cameraResolution.y, data);
    message.sendToTarget();
    previewHandler = null;
  
  } else {
    Log.d(TAG, "Got preview callback, but no handler or resolution available");
  }}
  </code></pre>
  
  <p>The result of running this code is a corrupt image at the set file directory. I believe this is due to the code being run every frame. Is there a way to limit this to every second or so if that will allow the full image to save, or is there a method I can use to cause the image to only save upon completed scan.</p>
  
  <p>I have a less favourable working alternative, in that I can successfully save the black and white image that is shown upon scan; colour is the preferable option of course.</p>
  
  <hr>
  
  <p>Update: Code changed to (in theory) accommodate camera resolution on any device. Image is still corrupt.</p>
  
  <pre><code>public void onPreviewFrame(byte[] data, Camera camera) {
  Point cameraResolution = configManager.getCameraResolution();
  Handler thePreviewHandler = previewHandler;
  
  android.hardware.Camera.Parameters parameters = camera.getParameters();
  android.hardware.Camera.Size size = parameters.getPictureSize();
  
  int height = size.height;
  int width = size.width;
  
  YuvImage im = new YuvImage(data, ImageFormat.NV21, width,
          height, null);
          Rect r = new Rect(0, 0, width, height);
          ByteArrayOutputStream baos = new ByteArrayOutputStream();
          im.compressToJpeg(r, 50, baos);
  
          try {
              FileOutputStream output = new FileOutputStream("/sdcard/test_jpg.jpg");
              output.write(baos.toByteArray());
              output.flush();
              output.close();
  
              System.out.println("Attempting to save file");
              System.out.println(data);
  
          } catch (FileNotFoundException e) {             
              System.out.println("Saving to file failed");                
          } catch (IOException e) {               
              System.out.println("Saving to file failed");                
          }    
  if (cameraResolution != null &amp;&amp; thePreviewHandler != null) {
    Message message = thePreviewHandler.obtainMessage(previewMessage, cameraResolution.x,
        cameraResolution.y, data);
    message.sendToTarget();
    previewHandler = null;
  
  } else {
    Log.d(TAG, "Got preview callback, but no handler or resolution available");
  }}
  </code></pre>
  
  <p>Having checked the width and height variable are correctly set to the Nexus 7's camera width and height of 1280x960. I am confident the issue comes from attempting to save the image every frame, as "Attempting to save to file" appears somewhat rapidly within the logcat; several times a second. It may also be worth noting that the corrupt image saved is square(ish).</p>
  
  <p>Thanks in advance.</p>