In Ti 9.1.0 there was a change to the orientation handling of rotated images:
https://github.com/appcelerator/titanium_mobile/pull/11679
https://github.com/appcelerator/titanium_mobile/blob/7ce3ae11f2c886864ed7713b1e88324b60fdf8f6/android/titanium/src/java/org/appcelerator/titanium/TiBlob.java#L756-L758
while this fixes the rotation of the images in the example it brings some problems using av.imageview:
https://github.com/AndreaVitale/av.imageview/issues/92
One thing I see is that on my Android 10, Pixel 4 I always get the wrong orientation in e.media.width/height for portrait images when looking at images from camera or gallery but I don't know the orientation (e.g. a portrait image is exif orientation 6 (top, right) but the returned width value is higher).
In my opinion the images that are returned to my app should always be in the correct orientation AND the width/height value should represent that too.
var window = Ti.UI.createWindow({
title: "Image Test"
});
var AvImageview = require("av.imageview");
var img1 =AvImageview.createImageView({
width: Ti.UI.FILL,
height: 200,
top: 0,
contentMode: AvImageview.CONTENT_MODE_ASPECT_FILL,
});
var img2 =AvImageview.createImageView({
width: Ti.UI.FILL,
height: 200,
top: 200,
contentMode: AvImageview.CONTENT_MODE_ASPECT_FILL,
});
var img3 =Ti.UI.createImageView({
width: Ti.UI.SIZE,
height: 200,
top: 400,
autoRotate: true
});
var img4 =Ti.UI.createImageView({
width: Ti.UI.SIZE,
height: 200,
top: 600,
autoRotate: true
});
window.add(img1);
window.add(img2);
window.add(img3);
window.add(img4);
var dl = Ti.UI.createButton({
title: "gal",
bottom: 60,
});
dl.addEventListener("click", function(e) {
Ti.Media.openPhotoGallery({
success: function(e) {
var w = e.media.width;
var h = e.media.height;
var r = h / w;
w = 1024;
h = r * w;
var imageBlob = e.media.imageAsResized(w, h);
img1.image = e.media;
img2.image = imageBlob;
img3.image = e.media;
img4.image = imageBlob;
}
});
});
window.add(dl);
window.open();
Needs av.imageview (
https://github.com/AndreaVitale/av.imageview/releases/tag/Android-5.0.1)
9.0.3.GA
!ti903ga.jpg|thumbnail!
9.1.0.RC
!ti910rc.jpg|thumbnail!
1st and 3rd image are straight from the Gallery
2nd and 4th image are resized images.
[~michael], the real issue is that Google's image loading APIs ignore the JPEG's EXIF orientation when decoding it to a bitmap and simply load it as-is. Apple and Microsoft will pre-rotate it, but Google does not. The Titanium blob's "width" and "height" properties represent the actual width and height of the bitmap it wraps. In this case, it's for the unrotated image and it's technically correct. Titanium's
ImageView.image
property is the only image displaying API that will correctly rotate a JPEG. So, swapping the blob's width/height values would end up causing sizing issues in all of our other image displaying APIs such as "backgroundImage". I think a good *+interim+* solution would be to add a new "rotation" property toTi.Blob
which would provide the EXIF rotation. This is needed for people who are doing the math themselves, such as you. In your case, you know you need to swap width/height values when the rotation is 90 or 180 degrees. (On iOS, this new "rotation" property will always be zero since Apple pre-rotates it.) The BEST solution would be for us to load JPEGs ourselves via the "libjpeg" library and rotate it during the decoding process, but this would involve a major refactoring of our code (although I think it needs it). If we were to do this, then the blob's "rotation" property will always be zero, the blob's width/height properties would be what you expect, and then we can finally be done with this nonsense.Thank you for the great explanation! I've tested it with a js exif library, have to give it another go. it is just that the change in 9.1.0 (swapping the values for rotated images) https://github.com/appcelerator/titanium_mobile/blob/7ce3ae11f2c886864ed7713b1e88324b60fdf8f6/android/titanium/src/java/org/appcelerator/titanium/TiBlob.java#L756-L758 broke it for me and 9.0.3.GA is working. Perhaps it is a combination of that PR (since it fixes other parts) and an exif check? Here is a test image: http://migaweb.de/IMG_20200802_151801.jpg I hate handling images on Android :-D Especially on Samsung phones.
[~michael], I'm thinking about adding new properties "uprightWidth" and "uprightHeight" to
Ti.Blob
which will tell you the width/height of the JPEG after it's been rotated. This should make it more convenient to use. For iOS, theses properties will always matchwidth
andheight
since iOS always decodes JPEGs pre-rotated.I was trying to find a spot to do that already but wasn't successful :) And I had some problems with cleanbuild failing on 9.2.0 at the end (had to manually install it, not sure yet why) but I'll give it another go at the weekend.
[~michael], I have something working now. I just don't "love" the idea of adding these 2 new properties to
Ti.Blob
. Ideally you shouldn't have to worry about this in Titanium... but natively you do. Maybe a better solution might be to add a method to our "ti.imagefactory" module. Like animageGetUprightSize()
method? I'm a bit torn on this.Resolved by [TIMOB-28093]