private Bitmap getScaledAndRotatedBitmap()

in src/android/CameraLauncher.java [1036:1132]


    private Bitmap getScaledAndRotatedBitmap(byte[] data, String mimeType) throws IOException {
        // If no new width or height were specified, and orientation is not needed return the original bitmap
        if (this.targetWidth <= 0 && this.targetHeight <= 0 && !(this.correctOrientation)) {
            Bitmap image = null;
            try {
                image = BitmapFactory.decodeStream(new ByteArrayInputStream(data));
            } catch (OutOfMemoryError e) {
                callbackContext.error(e.getLocalizedMessage());
            } catch (Exception e) {
                callbackContext.error(e.getLocalizedMessage());
            }
            return image;
        }

        int rotate = 0;
        try {
            try {
                if (JPEG_MIME_TYPE.equalsIgnoreCase(mimeType)) {
                    exifData = new ExifHelper();
                    exifData.createInFile(new ByteArrayInputStream(data));
                    exifData.readExifData();
                    // Use ExifInterface to pull rotation information
                    if (this.correctOrientation) {
                        ExifInterface exif = new ExifInterface(new ByteArrayInputStream(data));
                        rotate = exifToDegrees(exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED));
                    }
                }
            } catch (Exception oe) {
                LOG.w(LOG_TAG,"Unable to read Exif data: " + oe.toString());
                rotate = 0;
            }
        } catch (Exception e) {
            LOG.e(LOG_TAG,"Exception while getting input stream: " + e.toString());
            return null;
        }

        // figure out the original width and height of the image
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(new ByteArrayInputStream(data), null, options);

        //CB-2292: WTF? Why is the width null?
        if (options.outWidth == 0 || options.outHeight == 0) {
            return null;
        }

        // User didn't specify output dimensions, but they need orientation
        if (this.targetWidth <= 0 && this.targetHeight <= 0) {
            this.targetWidth = options.outWidth;
            this.targetHeight = options.outHeight;
        }

        // Setup target width/height based on orientation
        int rotatedWidth, rotatedHeight;
        boolean rotated = false;
        if (rotate == 90 || rotate == 270) {
            rotatedWidth = options.outHeight;
            rotatedHeight = options.outWidth;
            rotated = true;
        } else {
            rotatedWidth = options.outWidth;
            rotatedHeight = options.outHeight;
        }

        // determine the correct aspect ratio
        int[] widthHeight = calculateAspectRatio(rotatedWidth, rotatedHeight);

        // Load in the smallest bitmap possible that is closest to the size we want
        options.inJustDecodeBounds = false;
        options.inSampleSize = calculateSampleSize(rotatedWidth, rotatedHeight,  widthHeight[0], widthHeight[1]);
        Bitmap unscaledBitmap = BitmapFactory.decodeStream(new ByteArrayInputStream(data), null, options);;

        if (unscaledBitmap == null) {
            return null;
        }

        int scaledWidth = (!rotated) ? widthHeight[0] : widthHeight[1];
        int scaledHeight = (!rotated) ? widthHeight[1] : widthHeight[0];

        Bitmap scaledBitmap = Bitmap.createScaledBitmap(unscaledBitmap, scaledWidth, scaledHeight, true);
        if (scaledBitmap != unscaledBitmap) {
            unscaledBitmap.recycle();
            unscaledBitmap = null;
        }

        if (this.correctOrientation && (rotate != 0)) {
            Matrix matrix = new Matrix();
            matrix.setRotate(rotate);
            try {
                scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true);
                this.orientationCorrected = true;
            } catch (OutOfMemoryError oom) {
                this.orientationCorrected = false;
            }
        }
        return scaledBitmap;
    }