{ "id": "174123", "key": "AC-6365", "fields": { "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false }, "project": { "id": "12217", "key": "AC", "name": "Appcelerator - INBOX", "projectCategory": { "id": "10000", "description": "", "name": "Customer Service" } }, "resolution": { "id": "8", "description": "", "name": "Needs more info" }, "resolutiondate": "2019-11-02T21:00:38.000+0000", "created": "2019-09-12T10:04:58.000+0000", "labels": [], "versions": [], "issuelinks": [], "assignee": { "name": "shossain", "key": "shossain", "displayName": "Shak Hossain", "active": false, "timeZone": "America/Los_Angeles" }, "updated": "2019-11-02T21:00:38.000+0000", "status": { "description": "A resolution has been taken, and it is awaiting verification by reporter. From here issues are either reopened, or are closed.", "name": "Resolved", "id": "5", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "components": [], "description": "There are lots of issues raised on this topic. However, it seems like there is no clear solution, fix or way to work with this.\r\n\r\nHaving used modules like fh.imagefactory in the past to solve/work with this issue is no longer an option, since this module generates errors when for example using saved images from the web (e.g. a website logo).\r\n\r\nAlso; setting autorotate - true to the imageview doesn't fix it.\r\n\r\nIt seems like it has to do with the presence or absence of exif information with respect to the orientation (looking/reading through other issues).\r\n\r\nCode that still leads to a rotated image below. This is the case both when taking a new photo with the Galaxy S6 camera, as well as selecting a previously made photo with the camera from the gallery using Ti.Media.openPhotoGallery()\r\n\r\n\r\n{code:javascript}\r\nTi.Media.showCamera({\r\n\t\tsuccess : function(event) {\r\n\t\t\tcallback(rotateAndResize(event.media));\r\n\t\t},\r\n\t\tallowEditing: false,\r\n\t\tmediaTypes: [ Ti.Media.MEDIA_TYPE_PHOTO ],\r\n\t\tsaveToPhotoGallery: true\r\n\t});\r\n\r\nfunction rotateAndResize (media, width, quality) {\r\n\t\r\n var quality = 0.5;\r\n var width = Alloy.CFG.size_450;\r\n \r\n var newMedia = require('/libs/Image').resizeIfNecessary(media, width, quality);\r\n \r\n return require('/libs/Image').cropToSquare(newMedia, width, quality);\r\n}\r\n\r\n// Image.js lib\r\n\r\nif (!ImageFactory)\r\n\t\tImageFactory = require('ti.imagefactory');\r\n\r\n\tvar width = blob.width;\r\n\tvar height = blob.height;\r\n\tvar maxWidth = maxSize;\r\n\tvar maxHeight = maxSize;\r\n\r\n\tvar ratio = width / height;\r\n\r\n\tvar newWidth = width,\r\n\t newHeight =\r\n\t height;\r\n\r\n\tif (width > maxWidth) {\r\n\t\tnewWidth = maxWidth;\r\n\t\tnewHeight = +((newWidth / ratio).toFixed());\r\n\t\tif (newHeight > maxHeight) {\r\n\t\t\tnewHeight = maxHeight;\r\n\t\t\tnewWidth = +((newHeight * ratio).toFixed());\r\n\t\t}\r\n\t} else if (height > maxHeight) {\r\n\t\tnewHeight = maxHeight;\r\n\t\tnewWidth = +((newHeight * ratio).toFixed());\r\n\t}\r\n\r\n\tif (width != newWidth || height != newHeight || quality !== 1) {\r\n\t\tvar blob = ImageFactory.imageAsResized(blob, {\r\n\t\t\twidth : newWidth,\r\n\t\t\theight : newHeight,\r\n\t\t\tformat : ImageFactory.JPEG\r\n\t\t});\r\n\t\tif (!blob) return;\r\n\t\tvar blob = ImageFactory.compress(blob, quality);\r\n\t}\r\n\r\n\treturn blob;\r\n};\r\n\r\nfunction resizeCompressAndroid(blob, size, quality){\t\r\n\tvar filename = 'android_resize_image.jpg';\r\n\tvar path = Ti.Filesystem.applicationCacheDirectory;\r\n\tvar file = Ti.Filesystem.getFile(path, filename);\r\n\tfile.write(blob);\r\n\tvar nativePath = file.nativePath;\r\n\tfile = null;\r\n\t\r\n\tquality = Math.round(quality*100) ? Math.round(quality*100) : 60;\r\n\t\r\n\tvar fh = require('fh.imagefactory');\r\n\t\r\n\tfh.rotateResizeImage(nativePath, size, quality);\r\n\t\r\n\tfh = null;\r\n\tvar file = Ti.Filesystem.getFile(path, filename);\r\n\tvar returnFile = file.read();\r\n\treturn returnFile;\r\n};\r\n\r\nfunction cropToSquare(blob, size, quality){\r\n\tvar newSize, x, y;\r\n\t\r\n\tif (blob.height > blob.width){\r\n\t\tnewSize = blob.width;\r\n\t\tx = 0;\r\n\t\ty = (blob.height - newSize)/2;\r\n\t}\r\n\telse if (blob.height < blob.width){\r\n\t\tnewSize = blob.height;\r\n\t\ty = 0;\r\n\t\tx = (blob.width - newSize)/2;\r\n\t} else {\r\n\t\t// already is square\r\n\t\tif (blob.with > size) return blob;\r\n\t\t// square but too big\r\n\t\treturn resizeIfNecessary(blob, size,quality);\r\n\t}\r\n\t\r\n\treturn require('ti.imagefactory').imageAsCropped(blob, {\r\n\t\twidth : newSize,\r\n\t\theight : newSize,\r\n\t\tx: x,\r\n\t\ty: y\r\n\t});\r\n}\r\n\r\nmodule.exports = {\r\n\tresizeIfNecessary : resizeIfNecessary,\r\n\tcropToSquare: cropToSquare\r\n};\r\n\r\n\r\n\r\n{code}\r\n", "attachment": [], "flagged": false, "summary": "Android camera image rotated 90 degrees", "creator": { "name": "thijsalbers", "key": "thijsalbers", "displayName": "Thijs", "active": true, "timeZone": "America/Los_Angeles" }, "subtasks": [], "reporter": { "name": "thijsalbers", "key": "thijsalbers", "displayName": "Thijs", "active": true, "timeZone": "America/Los_Angeles" }, "environment": "SDK Version 8.0.0 GA\r\nTargeting Samsung S6 - Android 7.0\r\nModule: ti.imagefactory 4.0.0", "comment": { "comments": [ { "id": "451334", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "An {{ImageView}}'s \"autorotate\" property does work. When setting it to {{true}}, the software will read the JPEG file's EXIF information (if it has any) to see if it has an orientation/rotation value. If it does, the {{ImageView}} will automatically rotate it. If you assigned the JPEG returned by {{showCamera()}} directly to the {{ImageView}}, then this would have worked. The issue is that the code you are using to resize and copy to a new image file is stripping-off the EXIF information.\r\n\r\nUnfortunately, \"ti.imagefactory\" does not support reading/writing EXIF information.\r\n\r\nThere is a pending PR for \"ti.imagefactory\" to add a method to save the photo as an \"upright\" image. The EXIF information will still be lost, but it orientation setting will no longer be needed anymore. You can build your own version of this module and use that for now. Just note that we currently disagree with its method name {{fixOrientation()}} and a better solution would be to provide APIs that can read/write EXIF information.\r\nhttps://github.com/appcelerator-modules/ti.imagefactory/pull/32\r\n", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2019-09-12T18:17:45.000+0000", "updated": "2019-09-12T18:17:45.000+0000" }, { "id": "452144", "author": { "name": "rmitro", "key": "rmitro", "displayName": "Rakhi Mitro", "active": false, "timeZone": "America/Los_Angeles" }, "body": "Hello!\r\n\r\nHope you are doing fine today.\r\n\r\nWould you please reply us regarding previous reviews? We are looking forward to your response.\r\n\r\n", "updateAuthor": { "name": "rmitro", "key": "rmitro", "displayName": "Rakhi Mitro", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2019-10-20T10:14:58.000+0000", "updated": "2019-10-20T10:14:58.000+0000" }, { "id": "452252", "author": { "name": "sdarda", "key": "sdarda", "displayName": "Sharif AbuDarda", "active": false, "timeZone": "Asia/Dhaka" }, "body": "Hello [~thijsalbers], Can you please follow up here on the previous comment? Let us know the status of your issue. Thanks.", "updateAuthor": { "name": "sdarda", "key": "sdarda", "displayName": "Sharif AbuDarda", "active": false, "timeZone": "Asia/Dhaka" }, "created": "2019-10-24T22:48:12.000+0000", "updated": "2019-10-24T22:48:12.000+0000" } ], "maxResults": 3, "total": 3, "startAt": 0 } } }