3

This is my code. This question is somewhat related from this question: Trying to scale down a Bitmap in Android not working

I commented out the options.inSampleSize and I still get the rotation (counter-clockwise 90 degrees seemingly). This seems like a fairly simple scaling down of an image, from Google documentation, and I'm not sure how I'm getting a rotated image.

Bitmap myBitmap = null;
        @Override
        protected byte[] doInBackground(Object... params) {


            final BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            //myImageByteArray is 4016 wide
            myBitmap = BitmapFactory.decodeByteArray(myImageByteArray, 0, myImageByteArray.length, options);
            if (options.outHeight > options.outWidth) {
                //options.inSampleSize = calculateInSampleSize(options, 640, 960);
            } else {
                //options.inSampleSize = calculateInSampleSize(options, 960, 640);
            }

            options.inJustDecodeBounds = false;

            //myImageByteArray is 4016 wide
            myBitmap = BitmapFactory.decodeByteArray(myImageByteArray, 0, myImageByteArray.length, options);

            //This log statement outputs around 1000 now. 
            Log.d("bitmap", myBitmap.getWidth()+"");
            ByteArrayOutputStream bAOS = new ByteArrayOutputStream();
            myBitmap.compress(CompressFormat.JPEG, 50, bAOS);

}

The byte[] is originally from Commonsware CWAC Camera library, and I've tried taking a look at: Android Reduce Size Of Camera Picture

UPDATE:

I have started pulling away more code to try to make it more apparent where this rotation could be coming from. I have it narrowed down to this. (This code still causes rotation)

Bitmap myBitmap = null;
        @Override
        protected byte[] doInBackground(Object... params) {
            final BitmapFactory.Options options = new BitmapFactory.Options();

            myBitmap = BitmapFactory.decodeByteArray(myImageByteArray, 0, myImageByteArray.length, options);      
            ByteArrayOutputStream bAOS = new ByteArrayOutputStream();
            myBitmap.compress(CompressFormat.JPEG, 50, bAOS);

}
Community
  • 1
  • 1
  • Presumably, it is rotated by 90 degrees before scaling it. How have you confirmed that it is not? – CommonsWare Jan 10 '14 at 16:58
  • Yes, I have confirmed that IT IS the correct orientation before scaling it. –  Jan 10 '14 at 17:01
  • @CommonsWare I have updated my question from some further testing of mine. Do you think it could be the `.compress()` method doing this? –  Jan 10 '14 at 17:26
  • I rather doubt it. How **precisely** have you "confirmed that IT IS the correct orientation before scaling it"? Hint: if the answer is "I viewed the image in an image viewer", that's the wrong answer. "I viewed the image in an image viewer *and* confirmed that there were no EXIF headers in the image that would cause the image viewer to rotate the image" would be better. You might consider uploading "before" and "after" images somewhere and linking to them from your answer. – CommonsWare Jan 10 '14 at 17:29
  • I am sending the original byte[] to a server and displaying it and it is perfect. After scaling and compressing it, I do `byte[] arr = bAOS.toByteArray();` and I send that byte[] to a server and I display it, and it comes out rotated. Also, @CommonsWare, would your library return a byte[] with an EXIF header? –  Jan 10 '14 at 17:36
  • "would your library return a byte[] with an EXIF header?" -- quite possibly, depending upon device. I try to normalize this, rotating the image myself and removing the EXIF header, but I don't know all devices that need this work done. You need to examine your image files and see if there's an EXIF header on the original that is controlling the orientation. – CommonsWare Jan 10 '14 at 17:40
  • @CommonsWare I was testing this on my device (G2 with CM), but borrowed my SO S3 and it worked fine. I guess maybe the library is removing the exif on the S3 and not on the G2. –  Jan 10 '14 at 18:01
  • G2 == LG G2? Can you give me a specific device model? Also note that some behaviors will differ for CyanogenMod. – CommonsWare Jan 10 '14 at 18:12
  • device=vs980 (That's the vzw model) –  Jan 10 '14 at 18:19
  • I am tracking the G2 issue here: https://github.com/commonsguy/cwac-camera/issues/97 – CommonsWare Jan 10 '14 at 18:24
  • Thanks. Is there any place to add devices that we have personally tested to that list on the readme? Or do you personally test all of those devices? –  Jan 10 '14 at 18:38
  • The ones on the `README` are personally tested, by me and my army of trained killer dust bunnies, here in my Secret Mountain Lair(TM) (location: a secret). I have some long-term plans for trying to make it easier to contribute device configuration information like this, but that's queued up behind figuring out a more stable sequence of calling the various hardware APIs (to try to resolve the various device bugs), which may have rippling impacts on other aspects of the library. – CommonsWare Jan 10 '14 at 18:45
  • Gotcha. Yes, being able to contribute information like that would be key. Many Android phones... only one @CommonsWare. Excited for the next releases. Thanks –  Jan 10 '14 at 18:48

1 Answers1

0

It's probable that the issue here is that the image is not being rotated per-se, but that the image is being displayed with a rotation and your transform is clearing (or at least not carrying forward) the metadata the OS would use to show it oriented correctly. There's not a lot you can do about that, because the OS doesn't put that data in the image itself

If that's not the case, then what you have is byte-order issue. One format is giving you data left-to-right and the other is top-to-bottom. You need to reorder the bytes.

Adam McCormick
  • 1,654
  • 18
  • 22
  • I have confirmed that the original byte[] is in the proper orientation. Can you explain further on why you think one format is giving me data LTR and the other TTB? Or how would I go about re-ordering the bytes? –  Jan 10 '14 at 17:08
  • To reorder the bytes, you just have to iterate through the array and populate a new array by row instead of column. So declare a new byte array of the same size as bAOS (call it target for sake of this explanation), then for each index i in the bAOS byte array (arr.), `target[i%width*height + i/width] = arr[i]` you may have to flip width and height depending on which format wants its bytes TTB and which wants them LTR. FWIW, that is a transpose of the image, so if the image is now mirrored, then byte order probably wasn't the issue – Adam McCormick Jan 12 '14 at 02:22