{ "id": "112198", "key": "TIMOB-13436", "fields": { "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "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": "15400", "description": "2013 Sprint 08 API", "name": "2013 Sprint 08 API", "archived": true, "released": true, "releaseDate": "2013-04-22" }, { "id": "15106", "description": "2013 Sprint 08", "name": "2013 Sprint 08", "archived": true, "released": true, "releaseDate": "2013-04-22" }, { "id": "14982", "description": "Release 3.2.0", "name": "Release 3.2.0", "archived": false, "released": true, "releaseDate": "2013-12-19" } ], "resolution": { "id": "1", "description": "A fix for this issue is checked into the tree and tested.", "name": "Fixed" }, "resolutiondate": "2013-04-18T21:48:34.000+0000", "created": "2013-04-04T16:57:08.000+0000", "priority": { "name": "High", "id": "2" }, "labels": [ "triage" ], "versions": [], "issuelinks": [], "assignee": { "name": "srahim", "key": "srahim", "displayName": "Sabil Rahim", "active": true, "timeZone": "America/Los_Angeles" }, "updated": "2013-10-23T22:45:12.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": "10206", "name": "iOS", "description": "iOS Platform" } ], "description": "*Steps to Reproduce*\r\n- create a project with Alloy with a single CoverFlowView\r\n- add a couple of images\r\n- when a user clicks one of the images, modify the actual image as follows\r\n a) create a view with the actual image as background\r\n b) add a label text wit some text (i.e. Date())\r\n c) save the view as image back to the original image file\r\n d) do a setImage () reloading the image with correct index\r\n\r\n*Actual Result*\r\nWhen the images are loaded the first time, they show up perfect\r\nWhen an image is peformed, only the top half of that image shows in the coverflowview\r\nWhen the app is killed and restarted, the correct images appear.\r\nThe click even works perfect as the images are correctly changed\r\n\r\n*Expected Result*\r\nWhen an image is changed, it should display the full changed image. Not the top half. I have isolated this problem in a separate project and the results are the same.\r\n\r\nh3. Appc Support Team Notes\r\n\r\nThe attached project references the data directory. I have modified it to reference the resources folder; now simply drop the images into assets/iphone. I have also modified the index.xml; before the cover flow was being created off-screen.\r\n\r\n*index.xml*\r\n\r\n{code}\r\n\r\n\t\r\n \r\n \r\n\t\r\n\r\n{code}\r\n\r\n*index.js*\r\n{code}\r\nvar hover = $.getView('COVERFLOW');\r\n// pointer to CoverFlowView on screen\r\nvar images = [];\r\nvar imagefiles = [];\r\nvar dir = Titanium.Filesystem.getFile(Ti.Filesystem.resourcesDirectory);\r\n// Open the data folder\r\nvar dirItems = dir.getDirectoryListing();\r\n// get a list of all files in this folder\r\nvar filename = null;\r\n// contains the filename\r\nvar imagefile = null;\r\n// contains the full image file name\r\nvar wissel = false;\r\n\r\n// loop through the directory listing selecting all .JPG files\r\nTi.API.info(dirItems);\r\nfor (var i = 0; i < dirItems.length; i++) {\r\n\t// check if the file contains .JPG as extension\r\n\t// convert to string first\r\n\tfilename = dirItems[i].toString();\r\n\t// if this is a .JPG file, then process it\r\n\tif (filename.indexOf('.JPG') >= 0) {\r\n\t\t// add image to coverflow view\r\n\t\tvar p = {};\r\n\t\tp.imageFile = Titanium.Filesystem.resourcesDirectory + filename;\r\n\t\tp.command = 'Add';\r\n\t\tAddImageToCoverFlowView(p);\r\n\t\t// save filename for later\r\n\t\timagefiles.push(filename);\r\n\t}\r\n}\r\n\r\nfunction modifyImage(e) {\r\n\t// just change the time in the center of the image\r\n\tif (e.index < images.length) {\r\n\t\tvar imageFile = Titanium.Filesystem.getFile(Titanium.Filesystem.resourcesDirectory, imagefiles[e.index]);\r\n\t\tif (imageFile.exists()) {\r\n\t\t\t// read the image first\r\n\t\t\tvar image = imageFile.read();\r\n\t\t\timageFile = null;\r\n\t\t\t// release the file handle\r\n\t\t\t// create a view to put the image in the background\r\n\t\t\tvar vw = Ti.UI.createView({\r\n\t\t\t\tbackgroundImage : image,\r\n\t\t\t\twidth : 320,\r\n\t\t\t\theight : 200,\r\n\t\t\t});\r\n\t\t\t// get the current date time\r\n\t\t\tvar txt = new Date();\r\n\t\t\t// create a label to put the date in\r\n\t\t\tvar label = Ti.UI.createLabel({\r\n\t\t\t\ttext : txt,\r\n\t\t\t\twidth : Ti.UI.SIZE,\r\n\t\t\t\theight : Ti.UI.SIZE,\r\n\t\t\t\tbackgroundColor : \"#fff\",\r\n\t\t\t\tcolor : \"#000\",\r\n\t\t\t\tfont : {\r\n\t\t\t\t\tfontSize : 20,\r\n\t\t\t\t\tfontFamily : 'HelveticaNeue-Bold'\r\n\t\t\t\t},\r\n\t\t\t\tminimumFontSize : 8,\r\n\t\t\t\ttextAlign : 'center'\r\n\t\t\t});\r\n\t\t\t// add the label to the view\r\n\t\t\tvw.add(label);\r\n\t\t\t// get an image of the new view\r\n\t\t\tvar newImage = vw.toImage();\r\n\t\t\t// overwrite the old image\r\n\t\t\tvar imageFile = Titanium.Filesystem.getFile(Titanium.Filesystem.resourcesDirectory, imagefiles[e.index]);\r\n\t\t\tif (imageFile.exists()) {\r\n\t\t\t\timageFile.write(newImage);\r\n\t\t\t} else {\r\n\t\t\t\talert('cannot find image');\r\n\t\t\t}\r\n\t\t\t// cleanup view and label\r\n\t\t\tvw.remove(label);\r\n\t\t\tvw = null;\r\n\t\t\tlabel = null;\r\n\t\t\tnewImage = null;\r\n\t\t\ttxt = null;\r\n\t\t\t// now the image is ready to be resaved on the coverflow\r\n\t\t\tvar p = {};\r\n\t\t\tp.imageFile = Titanium.Filesystem.applicationDataDirectory + imagefiles[e.index];\r\n\t\t\tp.command = 'Change';\r\n\t\t\tp.index = e.index;\r\n\t\t\tAddImageToCoverFlowView(p);\r\n\t\t}\r\n\t}\r\n}\r\n\r\nwin1 = $.getView('win');\r\nwin1.open();\r\n\r\nfunction AddImageToCoverFlowView(p) {\r\n\tTi.API.info(p);\r\n\t// check if it is a change or add\r\n\tif ('command' in p) {\r\n\t\tswitch (p.command) {\r\n\r\n\t\t\tcase 'Add':\r\n\t\t\t\t// adds an image to the end of the CoverflowView\r\n\t\t\t\tvar image = {\r\n\t\t\t\t\timage : p.imageFile,\r\n\t\t\t\t\theight : 150,\r\n\t\t\t\t\twidth : 240\r\n\t\t\t\t};\r\n\t\t\t\timages.push(image);\r\n\t\t\t\thover.setImages(images);\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase 'Change':\r\n\t\t\t\t// make sure there is an index\r\n\t\t\t\tif ('index' in p) {\r\n\t\t\t\t\tif (p.index < hover.images.length) {\r\n\t\t\t\t\t\thover.setImage(parseInt(p.index), images[parseInt(p.index)]);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n}\r\n{code}", "attachment": [ { "id": "37059", "filename": "app.zip", "author": { "name": "ncoverduin", "key": "ncoverduin", "displayName": "nico verduin", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-04-05T05:50:46.000+0000", "size": 5767216, "mimeType": "application/zip" }, { "id": "37060", "filename": "Sample JPGs.zip", "author": { "name": "ncoverduin", "key": "ncoverduin", "displayName": "nico verduin", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-04-05T05:52:34.000+0000", "size": 381947, "mimeType": "application/zip" } ], "flagged": false, "summary": "iOS: CoverFlowView displays half image after image modification", "creator": { "name": "nicoverduin", "key": "nicoverduin", "displayName": "nico verduin", "active": true, "timeZone": "Europe/Amsterdam" }, "subtasks": [], "reporter": { "name": "nicoverduin", "key": "nicoverduin", "displayName": "nico verduin", "active": true, "timeZone": "Europe/Amsterdam" }, "environment": "Titanium Studio 3.0.1", "comment": { "comments": [ { "id": "245834", "author": { "name": "penrique", "key": "penrique", "displayName": "Pedro Enrique", "active": false, "timeZone": "America/Los_Angeles" }, "body": "Please upload a sample project so that we can verify it.", "updateAuthor": { "name": "penrique", "key": "penrique", "displayName": "Pedro Enrique", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2013-04-04T23:32:25.000+0000", "updated": "2013-04-04T23:32:25.000+0000" }, { "id": "245887", "author": { "name": "ncoverduin", "key": "ncoverduin", "displayName": "nico verduin", "active": true, "timeZone": "America/Los_Angeles" }, "body": "This is the app folder from my standard Alloy project. index.js contains all the code. index.xml the controller xml. for the rest no adjustments", "updateAuthor": { "name": "ncoverduin", "key": "ncoverduin", "displayName": "nico verduin", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-04-05T05:50:46.000+0000", "updated": "2013-04-05T05:50:46.000+0000" }, { "id": "245888", "author": { "name": "ncoverduin", "key": "ncoverduin", "displayName": "nico verduin", "active": true, "timeZone": "America/Los_Angeles" }, "body": "These are the 3 sample jpgs i have used. I put them manually in the documents folder of the ios simulator", "updateAuthor": { "name": "ncoverduin", "key": "ncoverduin", "displayName": "nico verduin", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-04-05T05:52:34.000+0000", "updated": "2013-04-05T05:52:34.000+0000" }, { "id": "246160", "author": { "name": "dsefton", "key": "dsefton", "displayName": "Daniel Sefton", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Tested and confirmed on iOS 6 simulator with 3.0.2 GA and latest 3.1 CI. Use modified code in description.", "updateAuthor": { "name": "dsefton", "key": "dsefton", "displayName": "Daniel Sefton", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-04-06T17:38:46.000+0000", "updated": "2013-04-06T17:38:46.000+0000" }, { "id": "246195", "author": { "name": "nicoverduin", "key": "nicoverduin", "displayName": "nico verduin", "active": true, "timeZone": "Europe/Amsterdam" }, "body": "Just for my curiosity as this is my first reported bug :) on appcelerator. Confirmed means you guys have the same results as I had? And if so, what happens next?", "updateAuthor": { "name": "nicoverduin", "key": "nicoverduin", "displayName": "nico verduin", "active": true, "timeZone": "Europe/Amsterdam" }, "created": "2013-04-06T20:44:55.000+0000", "updated": "2013-04-06T20:44:55.000+0000" }, { "id": "246220", "author": { "name": "dsefton", "key": "dsefton", "displayName": "Daniel Sefton", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Confirmed means we were able to reproduce the issue on our end. The issue has been escalated to engineering who will review it and evaluate a fix or workaround.", "updateAuthor": { "name": "dsefton", "key": "dsefton", "displayName": "Daniel Sefton", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-04-07T04:36:43.000+0000", "updated": "2013-04-07T04:36:43.000+0000" }, { "id": "246910", "author": { "name": "vduggal", "key": "vduggal", "displayName": "Vishal Duggal", "active": false, "timeZone": "America/Los_Angeles" }, "body": "ok two things.\r\n\r\n1. resourcesDirectory is read only. You might want to use applicationDataDirectory to write your images\r\n2. iOS has a bug in the imageloader where we cache images from local files and do not reload them if the backing file changes. This I will file as a bug and fix in the next release. For your app you can use the blob from the toImage method directly.\r\n\r\nSo here is code that works.\r\n\r\n{code}\r\nvar win = Ti.UI.createWindow({backgroundColor:'white'});\r\n\r\nvar hover = Ti.UI.iOS.createCoverFlowView({\r\n width:320,\r\n height:200\r\n})\r\n\r\nvar images = [];\r\nvar imagefiles = [];\r\nvar dir = Titanium.Filesystem.getFile(Ti.Filesystem.resourcesDirectory);\r\n// Open the data folder\r\nvar dirItems = dir.getDirectoryListing();\r\n// get a list of all files in this folder\r\nvar filename = null;\r\n// contains the filename\r\nvar imagefile = null;\r\n// contains the full image file name\r\nvar wissel = false;\r\n \r\n// loop through the directory listing selecting all .JPG files\r\nTi.API.info(dirItems);\r\nfor (var i = 0; i < dirItems.length; i++) {\r\n // check if the file contains .JPG as extension\r\n // convert to string first\r\n filename = dirItems[i].toString();\r\n // if this is a .JPG file, then process it\r\n if (filename.indexOf('.JPG') >= 0) {\r\n // add image to coverflow view\r\n var p = {};\r\n p.imageFile = Titanium.Filesystem.resourcesDirectory + filename;\r\n p.command = 'Add';\r\n AddImageToCoverFlowView(p);\r\n // save filename for later\r\n imagefiles.push(filename);\r\n }\r\n}\r\n\r\nfunction modifyImage(e) {\r\n // just change the time in the center of the image\r\n if (e.index < images.length) {\r\n var imageFile = Titanium.Filesystem.getFile(Titanium.Filesystem.resourcesDirectory, imagefiles[e.index]);\r\n if (imageFile.exists()) {\r\n // read the image first\r\n var image = imageFile.read();\r\n imageFile = null;\r\n // release the file handle\r\n // create a view to put the image in the background\r\n var vw = Ti.UI.createView({\r\n backgroundImage : image,\r\n width : 320,\r\n height : 200,\r\n });\r\n // get the current date time\r\n var txt = new Date();\r\n // create a label to put the date in\r\n var label = Ti.UI.createLabel({\r\n text : txt,\r\n width : Ti.UI.SIZE,\r\n height : Ti.UI.SIZE,\r\n backgroundColor : \"#fff\",\r\n color : \"#000\",\r\n font : {\r\n fontSize : 20,\r\n fontFamily : 'HelveticaNeue-Bold'\r\n },\r\n minimumFontSize : 8,\r\n textAlign : 'center'\r\n });\r\n // add the label to the view\r\n vw.add(label);\r\n // get an image of the new view\r\n var newImage = vw.toImage();\r\n // overwrite the old image\r\n var newImageFile = Titanium.Filesystem.getFile(Titanium.Filesystem.applicationDataDirectory, imagefiles[e.index]);\r\n if (newImageFile.exists() == false) {\r\n newImageFile.createFile();\r\n }\r\n \r\n if (newImageFile.exists()) {\r\n newImageFile.write(newImage);\r\n } else {\r\n alert('cannot find image');\r\n return;\r\n }\r\n \r\n\r\n // now the image is ready to be resaved on the coverflow\r\n var p = {};\r\n p.imageFile = Titanium.Filesystem.applicationDataDirectory + imagefiles[e.index];\r\n images[e.index].image = newImage;\r\n p.command = 'Change';\r\n p.index = e.index;\r\n AddImageToCoverFlowView(p);\r\n }\r\n }\r\n}\r\n\r\nfunction AddImageToCoverFlowView(p) {\r\n Ti.API.info(p);\r\n // check if it is a change or add\r\n if ('command' in p) {\r\n switch (p.command) {\r\n \r\n case 'Add':\r\n // adds an image to the end of the CoverflowView\r\n var image = {\r\n image : p.imageFile,\r\n height : 150,\r\n width : 240\r\n };\r\n images.push(image);\r\n hover.setImages(images);\r\n break;\r\n \r\n case 'Change':\r\n // make sure there is an index\r\n if ('index' in p) {\r\n if (p.index < hover.images.length) {\r\n hover.setImage(parseInt(p.index), images[parseInt(p.index)]);\r\n }\r\n }\r\n break;\r\n }\r\n }\r\n}\r\n\r\n\r\nhover.addEventListener('click',modifyImage);\r\n\r\nwin.add(hover);\r\n\r\nwin.open();\r\n{code}", "updateAuthor": { "name": "vduggal", "key": "vduggal", "displayName": "Vishal Duggal", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2013-04-10T19:44:36.000+0000", "updated": "2013-04-11T18:34:56.000+0000" }, { "id": "246911", "author": { "name": "vduggal", "key": "vduggal", "displayName": "Vishal Duggal", "active": false, "timeZone": "America/Los_Angeles" }, "body": "Marking this as invalid, though I found a bug in the iOS image loader when triaging his bug. ", "updateAuthor": { "name": "vduggal", "key": "vduggal", "displayName": "Vishal Duggal", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2013-04-10T19:46:02.000+0000", "updated": "2013-04-10T19:46:02.000+0000" }, { "id": "246914", "author": { "name": "nicoverduin", "key": "nicoverduin", "displayName": "nico verduin", "active": true, "timeZone": "Europe/Amsterdam" }, "body": "Hi Vishal\r\nThanks for the info. I am actually only reading and writing in the application data directory. When the guys at Appcelerator tried to verify my issue, they changed the file. so that won't be a problem. I'll try your solution tomorrow and let you know the results. \r\n\r\nThis is then the real (temp) change right?\r\n\r\n var newImage = vw.toImage(function(){Ti.API.info('FORCE SYNC')});\r\n\r\n\r\nThanks in advance\r\nRegards\r\nNico", "updateAuthor": { "name": "nicoverduin", "key": "nicoverduin", "displayName": "nico verduin", "active": true, "timeZone": "Europe/Amsterdam" }, "created": "2013-04-10T20:02:32.000+0000", "updated": "2013-04-10T20:02:54.000+0000" }, { "id": "247105", "author": { "name": "vduggal", "key": "vduggal", "displayName": "Vishal Duggal", "active": false, "timeZone": "America/Los_Angeles" }, "body": "@nico\nYes the only change required is to change the toImage method to the sync version and to use the blob directly instead of the files you write to due to the iOS bug. And no this is not a temp change. If you intend to use the resulting blob immediately you must use the sync version of the toImage method. ", "updateAuthor": { "name": "vduggal", "key": "vduggal", "displayName": "Vishal Duggal", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2013-04-11T17:38:13.000+0000", "updated": "2013-04-11T17:38:13.000+0000" }, { "id": "247111", "author": { "name": "nicoverduin", "key": "nicoverduin", "displayName": "nico verduin", "active": true, "timeZone": "Europe/Amsterdam" }, "body": "Hi Vishal\r\nSomething went wrong today. But I just checked en noticed I hadn't changed to new image file. I'll fix that tomorrow.\r\n\r\nOne other question:\r\nThe documentation for toImage() says: \r\nParameters\r\n\r\n callback : Callback (optional)\r\n\r\n Function to be invoked upon completion. If non-null, this method will be performed asynchronously. If null, it will be performed immediately. On Tizen, this function is asynchronous only. The callback is mandatory and function always returns \"undefined\".\r\n\r\nShouldn't it be the other way around based on your comments?\r\n", "updateAuthor": { "name": "nicoverduin", "key": "nicoverduin", "displayName": "nico verduin", "active": true, "timeZone": "Europe/Amsterdam" }, "created": "2013-04-11T17:57:04.000+0000", "updated": "2013-04-11T17:57:04.000+0000" }, { "id": "247119", "author": { "name": "vduggal", "key": "vduggal", "displayName": "Vishal Duggal", "active": false, "timeZone": "America/Los_Angeles" }, "body": "@nico,\r\nYou're right. Let me see whats going on.", "updateAuthor": { "name": "vduggal", "key": "vduggal", "displayName": "Vishal Duggal", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2013-04-11T18:16:05.000+0000", "updated": "2013-04-11T18:18:36.000+0000" }, { "id": "247131", "author": { "name": "vduggal", "key": "vduggal", "displayName": "Vishal Duggal", "active": false, "timeZone": "America/Los_Angeles" }, "body": "@ncio\nI have updated the test code above, you were right that with callback=nil the method is synchronous. I am also reopening the ticket to see why this does not work when using files though it works when using the blobs directly. You should be unblocked for now. We'll update the ticket with any additional info.", "updateAuthor": { "name": "vduggal", "key": "vduggal", "displayName": "Vishal Duggal", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2013-04-11T18:36:49.000+0000", "updated": "2013-04-11T18:36:49.000+0000" }, { "id": "247137", "author": { "name": "nicoverduin", "key": "nicoverduin", "displayName": "nico verduin", "active": true, "timeZone": "Europe/Amsterdam" }, "body": "@vishal:\r\nJust an idea. As I am modifying an image but not changing the filename. Could that be a reason? Actually it would be nice to have a sort of refresh() function of sorts to have it reload from disk. Then it should be solved right?", "updateAuthor": { "name": "nicoverduin", "key": "nicoverduin", "displayName": "nico verduin", "active": true, "timeZone": "Europe/Amsterdam" }, "created": "2013-04-11T18:59:44.000+0000", "updated": "2013-04-11T18:59:44.000+0000" }, { "id": "248017", "author": { "name": "srahim", "key": "srahim", "displayName": "Sabil Rahim", "active": true, "timeZone": "America/Los_Angeles" }, "body": "PR : [4180|https://github.com/appcelerator/titanium_mobile/pull/4180]\n\nh4.TESTING INSTRUCTION\n\nUse the following [code|https://gist.github.com/srahim/5407896] in your app.js\n\nh5.Make sure to include image files with `.JPG` extension in the resources folder of your app.\n\nClick on the coverflow image to update the image with the current timestamp. Make sure the image new image does not get cropped.", "updateAuthor": { "name": "srahim", "key": "srahim", "displayName": "Sabil Rahim", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-04-17T21:31:09.000+0000", "updated": "2013-04-17T21:31:09.000+0000" }, { "id": "276482", "author": { "name": "wluu", "key": "wluu", "displayName": "Wilson Luu", "active": false, "timeZone": "America/Los_Angeles" }, "body": "Closing ticket as fixed. Using Sabil's test code, verified half images are not displayed in the CoverFlowView after selecting the images.\n\nTested on:\n\nTitanium Studio, build: 3.2.0.201310230548\nOS: Mac OS X Mountain Lion (10.8.5)\nSDK build: 3.2.0.v20131023140842\nTi CLI: 3.2.0 (72f7426b4ee6c2d2883c666d5b7e03906a16012f)\nDevices: iphone 5 (6.1.3), iphone 5c (7.0.1)", "updateAuthor": { "name": "wluu", "key": "wluu", "displayName": "Wilson Luu", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2013-10-23T22:44:52.000+0000", "updated": "2013-10-23T22:44:52.000+0000" } ], "maxResults": 19, "total": 19, "startAt": 0 } } }