Android camera/picture orientation issues with Samsung Galaxy S3, S4, S5

后端 未结 4 844
你的背包
你的背包 2021-01-04 11:42

I am developing a camera application for Android API 16 to 21 which main and only purpose is to take portrait photo. I am able to take picture with several

4条回答
  •  独厮守ぢ
    2021-01-04 12:06

    I had a similar problem regarding the saved image.

    I used something similar to what is described here https://github.com/googlesamples/android-vision/issues/124 by user kinghsumit (the comment from Sep 15, 2016).

    I'll copy it here, just in case.

    private CameraSource.PictureCallback mPicture = new CameraSource.PictureCallback() {
        @Override
        public void onPictureTaken(byte[] bytes) {
           int orientation = Exif.getOrientation(bytes);
           Bitmap   bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
           switch(orientation) {
               case 90:
                   bitmapPicture= rotateImage(bitmap, 90);
                   break;
               case 180:
                   bitmapPicture= rotateImage(bitmap, 180);
                   break;
               case 270:
                   bitmapPicture= rotateImage(bitmap, 270);
                   break;
               case 0:
                   // if orientation is zero we don't need to rotate this
               default:
                   break;
           }
           //write your code here to save bitmap 
       }
    }
    
    public static Bitmap rotateImage(Bitmap source, float angle) {
        Matrix matrix = new Matrix();
        matrix.postRotate(angle);
        return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true);
    }
    

    Below class is used to get orientation from byte[] data.

    public class Exif {
        private static final String TAG = "CameraExif";
    
        // Returns the degrees in clockwise. Values are 0, 90, 180, or 270.
        public static int getOrientation(byte[] jpeg) {
            if (jpeg == null) {
                return 0;
            }
    
            int offset = 0;
            int length = 0;
    
            // ISO/IEC 10918-1:1993(E)
            while (offset + 3 < jpeg.length && (jpeg[offset++] & 0xFF) == 0xFF) {
                int marker = jpeg[offset] & 0xFF;
    
                // Check if the marker is a padding.
                if (marker == 0xFF) {
                    continue;
                }
                offset++;
    
                // Check if the marker is SOI or TEM.
                if (marker == 0xD8 || marker == 0x01) {
                    continue;
                }
                // Check if the marker is EOI or SOS.
                if (marker == 0xD9 || marker == 0xDA) {
                    break;
                }
    
                // Get the length and check if it is reasonable.
                length = pack(jpeg, offset, 2, false);
                if (length < 2 || offset + length > jpeg.length) {
                    Log.e(TAG, "Invalid length");
                    return 0;
                }
    
                // Break if the marker is EXIF in APP1.
                if (marker == 0xE1 && length >= 8 &&
                        pack(jpeg, offset + 2, 4, false) == 0x45786966 &&
                        pack(jpeg, offset + 6, 2, false) == 0) {
                    offset += 8;
                    length -= 8;
                    break;
                }
    
                // Skip other markers.
                offset += length;
                length = 0;
            }
    
            // JEITA CP-3451 Exif Version 2.2
            if (length > 8) {
                // Identify the byte order.
                int tag = pack(jpeg, offset, 4, false);
                if (tag != 0x49492A00 && tag != 0x4D4D002A) {
                    Log.e(TAG, "Invalid byte order");
                    return 0;
                }
                boolean littleEndian = (tag == 0x49492A00);
    
                // Get the offset and check if it is reasonable.
                int count = pack(jpeg, offset + 4, 4, littleEndian) + 2;
                if (count < 10 || count > length) {
                    Log.e(TAG, "Invalid offset");
                    return 0;
                }
                offset += count;
                length -= count;
    
                // Get the count and go through all the elements.
                count = pack(jpeg, offset - 2, 2, littleEndian);
                while (count-- > 0 && length >= 12) {
                    // Get the tag and check if it is orientation.
                    tag = pack(jpeg, offset, 2, littleEndian);
                    if (tag == 0x0112) {
                        // We do not really care about type and count, do we?
                        int orientation = pack(jpeg, offset + 8, 2, littleEndian);
                        switch (orientation) {
                            case 1:
                                return 0;
                            case 3:
                                return 180;
                            case 6:
                                return 90;
                            case 8:
                                return 270;
                        }
                        Log.i(TAG, "Unsupported orientation");
                        return 0;
                    }
                    offset += 12;
                    length -= 12;
                }
            }
    
            Log.i(TAG, "Orientation not found");
            return 0;
        }
    
        private static int pack(byte[] bytes, int offset, int length, boolean littleEndian) {
            int step = 1;
            if (littleEndian) {
                offset += length - 1;
                step = -1;
            }
    
            int value = 0;
            while (length-- > 0) {
                value = (value << 8) | (bytes[offset] & 0xFF);
                offset += step;
            }
            return value;
        }
    }
    

    It worked for me, except for the Nexus 5x, but that's because that device has a peculiar issue due to its construction.

    I hope this helps you!

提交回复
热议问题