0

I have a Galaxy Note device and I wrote an application that grabs uimages from the camera. I have set the layout to landscape and I am able to grab images with my device. The problem is when I run the same program on someone else's device. The program runs the same on the other device, but when saving a picture the content of the picture is wrong. You see slightly diagonal strpies instead of the image content. I think it's the result of the image being saved with the wrong pitch or resolution. The thumbnail of the "bugged" picture on the other device is for some kind of a reason corret. I have tried to find the difference between my device and the other device, but apart from one having a resolution of 1280x800 and the other of 800x480, I didn't find any difference. In both cases the Measur and Layout functions have a 90 degrees orientation and the correct landscape resolution. In both cases the image format is JPEG(by inquiring mCamera.getParameters().getPictureFormat()). I am stumped, I am don't know what to do, because everything seems the same except that one device spits the correct JPEG byte array, and the other gives me the correct data but with the wrong orientation. Or so it seems.

EDIT: I found that there is an issue even when I save the raw data straight into a JPEG file, so no display or decode is involved. I can see in the Gallery browser that the JPEG file has artifacts, is wrong somehow. My code for saving the camera data into a (JPEG) file is as following:

private File onJPGPreviewFrame(byte[] data, String Name) {
    FileOutputStream outStream = null;
    File f = null;
    try {
        if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { 
            File externalRoot = Environment.getExternalStorageDirectory(); 
            File tempDir = new File(externalRoot, Name); 
            tempDir.createNewFile();
            outStream = new FileOutputStream(tempDir);  
            outStream.write(data);
            outStream.close();
            f = tempDir;
        }

        Log.d(TAG, "onPreviewFrame - wrote bytes: " + data.length);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
    }
    return f;
}
user1097185
  • 1,058
  • 3
  • 13
  • 28
  • Each chipset manufacturer writes their own camera driver which decides how to encode the JPEG images and whether or not to include an EXIF thumbnail. There is no pitch information in a JPEG file, so if the displayed image is indicating incorrect pitch (diagonal lines), then it is 100% the fault of the decode/display logic. – BitBank Feb 09 '12 at 20:48
  • I forgot to mention that it's also up to the camera driver author whether or not they support the EXIF orientation tag. If they do, then programs which display the image may show it in the wrong orientation if they don't use the value in the EXIF tag. – BitBank Feb 09 '12 at 21:35
  • As I found out, the problem starts even before I am doing any decoding or any display. I just write the raw data into a file and the JPEG file, while viewed in the device's gallery, still look wrong. – user1097185 Feb 10 '12 at 17:57
  • Please send me a sample file and I'll see if I can figure out what's wrong (bitbank@pobox.com). – BitBank Feb 10 '12 at 18:16
  • I have found this http://stackoverflow.com/questions/5859876/android-jpeg-saved-from-camera-looks-corrupted When I comment out the setPreviewSize it works, like said in that question, but then I don't get the right preview size. I need to figure out how to set the preview size on my own. – user1097185 Feb 11 '12 at 18:28

1 Answers1

0

The device screen resolution has a different aspect ratio than the device's camera resolution. If you choose the preview to have the same aspect ratio as the camera's aspect ratio, then the jpeg byte array data will not be "bugged". The problem with this is that the preview is going to be distorted because it doesn't match the screen's aspet ratio. Here is some code I used to find the optimal aspect ratio:

private Size getOptimalPreviewSize(List<Size> sizes, int width, int height) 
{            
    Size optimalSize = null;                                 

    double targetRatio = (double) width / height;
    int Max = 0;

    for (Size size : sizes) 
    { 
        double ratio = (double) size.width / size.height;
        int m = size.width * size.height;
        if (m>Max && (ratio == targetRatio)) 
        {
            Max = m;
            optimalSize = size; 
        }                
    } 

    if (optimalSize == null) 
    { 
        // TODO : Backup in case we don't get a size. 
    } 

    return optimalSize; 
}
user1097185
  • 1,058
  • 3
  • 13
  • 28