0

I've been mulling over this problem for over a week now. I'm working on an android app that has to send a photo to a server and receive it back some time later. When I send the photo, however, I need it to be orientated correctly. I found this answer on Stack Overflow that provided some code which worked for me, however, it creates duplicated bitmaps, as did other various methods I used in the past.

Here's the method I'm using, is there any way to make it so it doesn't create a duplicated image? I have a feeling the

srcBitmap = Bitmap.createBitmap(srcBitmap, 0, 0, srcBitmap.getWidth(),srcBitmap.getHeight(), matrix, true);

line is what's doing it.

private Uri scaleImage(Context context, Uri photoUri) throws IOException {

    int MAX_IMAGE_DIMENSION = 3605;
    InputStream is = context.getContentResolver().openInputStream(photoUri);
    BitmapFactory.Options dbo = new BitmapFactory.Options();
    dbo.inJustDecodeBounds = true;
    BitmapFactory.decodeStream(is, null, dbo);
    is.close();

    int rotatedWidth, rotatedHeight;
    int orientation = getOrientation(context, photoUri);

    if (orientation == 90 || orientation == 270) {
        rotatedWidth = dbo.outHeight;
        rotatedHeight = dbo.outWidth;
    } else {
        rotatedWidth = dbo.outWidth;
        rotatedHeight = dbo.outHeight;
    }

    Bitmap srcBitmap;
    is = context.getContentResolver().openInputStream(photoUri);
    if (rotatedWidth > MAX_IMAGE_DIMENSION || rotatedHeight > MAX_IMAGE_DIMENSION) {
        float widthRatio = ((float) rotatedWidth) / ((float) MAX_IMAGE_DIMENSION);
        float heightRatio = ((float) rotatedHeight) / ((float) MAX_IMAGE_DIMENSION);
        float maxRatio = Math.max(widthRatio, heightRatio);

        // Create the bitmap from file
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inSampleSize = (int) maxRatio;
        srcBitmap = BitmapFactory.decodeStream(is, null, options);
    } else {
        srcBitmap = BitmapFactory.decodeStream(is);
    }
    is.close();

    /*
     * if the orientation is not 0 (or -1, which means we don't know), we
     * have to do a rotation.
     */
    if (orientation > 0) {
        Matrix matrix = new Matrix();
        matrix.postRotate(orientation);

        srcBitmap = Bitmap.createBitmap(srcBitmap, 0, 0, srcBitmap.getWidth(),
                srcBitmap.getHeight(), matrix, true);
    }

    String type = context.getContentResolver().getType(photoUri);
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    if (type.equals("image/png")) {
        srcBitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
    } else if (type.equals("image/jpg") || type.equals("image/jpeg")) {
        srcBitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
    }
    byte[] bMapArray = baos.toByteArray();
    baos.close();
    is.close();
    return getImageUri(this,BitmapFactory.decodeByteArray(bMapArray, 0, bMapArray.length));
}

public static int getOrientation(Context context, Uri photoUri) {
    /* it's on the external media. */
    Cursor cursor = context.getContentResolver().query(photoUri,
            new String[] { MediaStore.Images.ImageColumns.ORIENTATION }, null, null, null);

    if (cursor.getCount() != 1) {
        return -1;
    }

    cursor.moveToFirst();
    return cursor.getInt(0);
}
Community
  • 1
  • 1
  • I don't think thats the line! That should only produce a Bitmap in memory! – bdavies6086 Feb 22 '16 at 21:06
  • This is probably the case. I suspected it might be because all the other implementations I've tried had the same line. Either way, the duplication problem still occurs. – Ian Cunningham Feb 22 '16 at 21:23
  • Yeah, Im using quite a similar line of code and don't seem to be having the problem! Then again though I return an actual Bitmap and not a Uri – bdavies6086 Feb 22 '16 at 21:28
  • It definitely isn't that line, that produces an in memory bitmap. The problem would have to be caused by writing it to a file- anywhere you're calling compress. – Gabe Sechan Feb 22 '16 at 22:02
  • @bdavies6086 would you mind sharing the method you're using? Does it rotate and scale an image? – Ian Cunningham Feb 22 '16 at 22:20
  • @GabeSechan How would you recommend fixing this, then? Also, I suspect it might not be that line, either. I just copy and pasted the bitmap.compress line 4 times and it only duplicated once. – Ian Cunningham Feb 22 '16 at 22:36
  • 1
    The problem is that you're writing it to a URI- a file. And that means the media scanner will eventually find it, and it will still find the original. Either delete the original (and keep only the rotated) or don't write it to file. Actually all your code after the orientation check seems a bit clunky- why do you need to get the MIME type, you don't need to keep it the same type. Decide whether to send JPG or PNG and do one of the two. And compressing it then decoding it is a 100% waste of CPU, it looks like you copy pasting solutions without understanding them. – Gabe Sechan Feb 22 '16 at 23:20

0 Answers0