{ "id": "175456", "key": "TIMOB-28093", "fields": { "issuetype": { "id": "4", "description": "An improvement or enhancement to an existing feature or task.", "name": "Improvement", "subtask": false }, "project": { "id": "10153", "key": "TIMOB", "name": "Titanium SDK/CLI", "projectCategory": { "id": "10100", "description": "Titanium and related SDKs used in application development", "name": "Client" } }, "fixVersions": [ { "id": "21051", "description": "", "name": "Release 9.2.0", "archived": false, "released": true, "releaseDate": "2020-09-23" } ], "resolution": { "id": "1", "description": "A fix for this issue is checked into the tree and tested.", "name": "Fixed" }, "resolutiondate": "2020-09-10T13:24:02.000+0000", "created": "2020-08-20T21:41:13.000+0000", "priority": { "name": "Medium", "id": "3" }, "labels": [ "android", "blob", "exif", "iOS", "image", "jpeg", "orientation" ], "versions": [], "issuelinks": [ { "id": "58643", "type": { "id": "10003", "name": "Relates", "inward": "relates to", "outward": "relates to" }, "outwardIssue": { "id": "175422", "key": "AC-6582", "fields": { "summary": "Android: Image orientation handling", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "issuetype": { "id": "4", "description": "An improvement or enhancement to an existing feature or task.", "name": "Improvement", "subtask": false } } } } ], "assignee": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "updated": "2020-09-10T13:24:02.000+0000", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "components": [ { "id": "10202", "name": "Android", "description": "Android Platform" } ], "description": "*Summary:*\r\nWhen a Titanium {{Blob}} wraps an image, its \"width\" and \"height\" properties provide the \"decoded\" image's dimensions. Unfortunately, Android's native image loading APIs ignore a JPEG's EXIF orientation, meaning the image is loaded as-is (no rotation applied). While our {{ImageView}} and other APIs will correctly handle the EXIF orientation, the blob's \"width\" and \"height\" is for the unrotated image which makes it difficult to do manual layouts (ex: calculate letterbox scaling).\r\n\r\n*Proposed Solution:*\r\nAdd the following properties to Titanium {{Blob}}:\r\n* uprightWidth\r\n* uprightHeight\r\n\r\nThe above properties will return what the image width and height should be when a JPEG's EXIF orientation is applied onscreen. If the image is not a JPEG or the JPEG has no EXIF orientation, then these properties will return the same values as \"width\" and \"height\".\r\n\r\nAnd since iOS loads images in the upright positions, the above properties will always return the same values as \"width\" and \"height\".\r\n\r\n*Use-Case:*\r\nDevelopers need the image's actual width and height to do things like letterbox scaling. For example...\r\n{code:javascript}\r\nvar scale = Math.min(\r\n\tTi.UI.convertUnits(window.size.width, Ti.UI.UNIT_PX) / imageBlob.width,\r\n\tTi.UI.convertUnits(window.size.height, Ti.UI.UNIT_PX) / imageBlob.height);\r\nimageView.image = imageBlob;\r\nimageView.width = imageBlob.width * scale;\r\nimageView.height = imageBlob.height * scale;\r\n{code}\r\n\r\nIf the JPEG is loaded sideways (ie: its EXIF orientation is ignored), then the above will scale the image wrong.\r\n\r\n*Note:*\r\nThis is an interim solution. A better solution would be to completely refactor Titanium's image loading code and decode the image in the upright position (pre-rotated). This will be a huge undertaking that is best done in a major Titanium release version. But when we do this, Android's \"uprightWidth\" and \"uprightHeight\" properties will match \"width\" and \"height\" just like iOS.\r\n", "attachment": [ { "id": "67496", "filename": "DownloadImageBlobTest.js", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2020-08-21T00:12:10.000+0000", "size": 2904, "mimeType": "application/x-javascript" } ], "flagged": false, "summary": "TiAPI: Add properties \"uprightWidth\" and \"uprightHeight\" to Ti.Blob", "creator": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "subtasks": [], "reporter": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "environment": null, "comment": { "comments": [ { "id": "456539", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "PR (master): https://github.com/appcelerator/titanium_mobile/pull/11936", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2020-08-21T00:22:58.000+0000", "updated": "2020-08-21T00:22:58.000+0000" }, { "id": "456541", "author": { "name": "michael", "key": "michael", "displayName": "Michael Gangolf", "active": true, "timeZone": "Europe/Berlin" }, "body": "[~jquick] Awesome! Will try that in my app later today", "updateAuthor": { "name": "michael", "key": "michael", "displayName": "Michael Gangolf", "active": true, "timeZone": "Europe/Berlin" }, "created": "2020-08-21T06:20:56.000+0000", "updated": "2020-08-21T06:20:56.000+0000" }, { "id": "456549", "author": { "name": "michael", "key": "michael", "displayName": "Michael Gangolf", "active": true, "timeZone": "Europe/Berlin" }, "body": "Merged it into my custom 9_1_x and works fine! Now I now if I have to switch my values or not (y)", "updateAuthor": { "name": "michael", "key": "michael", "displayName": "Michael Gangolf", "active": true, "timeZone": "Europe/Berlin" }, "created": "2020-08-21T14:50:31.000+0000", "updated": "2020-08-21T14:50:31.000+0000" }, { "id": "456600", "author": { "name": "smohammed", "key": "smohammed", "displayName": "Samir Mohammed", "active": true, "timeZone": "America/Los_Angeles" }, "body": "FR Passed, Waiting on Jenkins build and 9_3_X build.", "updateAuthor": { "name": "smohammed", "key": "smohammed", "displayName": "Samir Mohammed", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2020-08-26T14:18:44.000+0000", "updated": "2020-08-26T14:18:44.000+0000" }, { "id": "456818", "author": { "name": "smohammed", "key": "smohammed", "displayName": "Samir Mohammed", "active": true, "timeZone": "America/Los_Angeles" }, "body": "*Closing ticket*. Improvement verified in SDK version {{9.2.0.v20200908050955}}, and {{9.3.0.v20200908051946}}.\r\n\r\n*Test and other information can be found at:*\r\nhttps://github.com/appcelerator/titanium_mobile/pull/11936", "updateAuthor": { "name": "smohammed", "key": "smohammed", "displayName": "Samir Mohammed", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2020-09-10T13:22:56.000+0000", "updated": "2020-09-10T13:22:56.000+0000" } ], "maxResults": 6, "total": 6, "startAt": 0 } } }