[TIMOB-13436] iOS: CoverFlowView displays half image after image modification
GitHub Issue | n/a |
---|---|
Type | Bug |
Priority | High |
Status | Closed |
Resolution | Fixed |
Resolution Date | 2013-04-18T21:48:34.000+0000 |
Affected Version/s | n/a |
Fix Version/s | 2013 Sprint 08 API, 2013 Sprint 08, Release 3.2.0 |
Components | iOS |
Labels | triage |
Reporter | nico verduin |
Assignee | Sabil Rahim |
Created | 2013-04-04T16:57:08.000+0000 |
Updated | 2013-10-23T22:45:12.000+0000 |
Description
*Steps to Reproduce*
- create a project with Alloy with a single CoverFlowView
- add a couple of images
- when a user clicks one of the images, modify the actual image as follows
a) create a view with the actual image as background
b) add a label text wit some text (i.e. Date())
c) save the view as image back to the original image file
d) do a setImage () reloading the image with correct index
*Actual Result*
When the images are loaded the first time, they show up perfect
When an image is peformed, only the top half of that image shows in the coverflowview
When the app is killed and restarted, the correct images appear.
The click even works perfect as the images are correctly changed
*Expected Result*
When 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.
Appc Support Team Notes
The 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. *index.xml*
<Alloy>
<Window title="Test CoverFlowView" id="win" class="container">
<CoverFlowView id="COVERFLOW" onClick="modifyImage" platform="ios" width= "320" height="150">
</CoverFlowView>
</Window>
</Alloy>
*index.js*
var hover = $.getView('COVERFLOW');
// pointer to CoverFlowView on screen
var images = [];
var imagefiles = [];
var dir = Titanium.Filesystem.getFile(Ti.Filesystem.resourcesDirectory);
// Open the data folder
var dirItems = dir.getDirectoryListing();
// get a list of all files in this folder
var filename = null;
// contains the filename
var imagefile = null;
// contains the full image file name
var wissel = false;
// loop through the directory listing selecting all .JPG files
Ti.API.info(dirItems);
for (var i = 0; i < dirItems.length; i++) {
// check if the file contains .JPG as extension
// convert to string first
filename = dirItems[i].toString();
// if this is a .JPG file, then process it
if (filename.indexOf('.JPG') >= 0) {
// add image to coverflow view
var p = {};
p.imageFile = Titanium.Filesystem.resourcesDirectory + filename;
p.command = 'Add';
AddImageToCoverFlowView(p);
// save filename for later
imagefiles.push(filename);
}
}
function modifyImage(e) {
// just change the time in the center of the image
if (e.index < images.length) {
var imageFile = Titanium.Filesystem.getFile(Titanium.Filesystem.resourcesDirectory, imagefiles[e.index]);
if (imageFile.exists()) {
// read the image first
var image = imageFile.read();
imageFile = null;
// release the file handle
// create a view to put the image in the background
var vw = Ti.UI.createView({
backgroundImage : image,
width : 320,
height : 200,
});
// get the current date time
var txt = new Date();
// create a label to put the date in
var label = Ti.UI.createLabel({
text : txt,
width : Ti.UI.SIZE,
height : Ti.UI.SIZE,
backgroundColor : "#fff",
color : "#000",
font : {
fontSize : 20,
fontFamily : 'HelveticaNeue-Bold'
},
minimumFontSize : 8,
textAlign : 'center'
});
// add the label to the view
vw.add(label);
// get an image of the new view
var newImage = vw.toImage();
// overwrite the old image
var imageFile = Titanium.Filesystem.getFile(Titanium.Filesystem.resourcesDirectory, imagefiles[e.index]);
if (imageFile.exists()) {
imageFile.write(newImage);
} else {
alert('cannot find image');
}
// cleanup view and label
vw.remove(label);
vw = null;
label = null;
newImage = null;
txt = null;
// now the image is ready to be resaved on the coverflow
var p = {};
p.imageFile = Titanium.Filesystem.applicationDataDirectory + imagefiles[e.index];
p.command = 'Change';
p.index = e.index;
AddImageToCoverFlowView(p);
}
}
}
win1 = $.getView('win');
win1.open();
function AddImageToCoverFlowView(p) {
Ti.API.info(p);
// check if it is a change or add
if ('command' in p) {
switch (p.command) {
case 'Add':
// adds an image to the end of the CoverflowView
var image = {
image : p.imageFile,
height : 150,
width : 240
};
images.push(image);
hover.setImages(images);
break;
case 'Change':
// make sure there is an index
if ('index' in p) {
if (p.index < hover.images.length) {
hover.setImage(parseInt(p.index), images[parseInt(p.index)]);
}
}
break;
}
}
}
Attachments
File | Date | Size |
---|---|---|
app.zip | 2013-04-05T05:50:46.000+0000 | 5767216 |
Sample JPGs.zip | 2013-04-05T05:52:34.000+0000 | 381947 |
Please upload a sample project so that we can verify it.
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
These are the 3 sample jpgs i have used. I put them manually in the documents folder of the ios simulator
Tested and confirmed on iOS 6 simulator with 3.0.2 GA and latest 3.1 CI. Use modified code in description.
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?
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.
ok two things. 1. resourcesDirectory is read only. You might want to use applicationDataDirectory to write your images 2. 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. So here is code that works.
Marking this as invalid, though I found a bug in the iOS image loader when triaging his bug.
Hi Vishal Thanks 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. This is then the real (temp) change right? var newImage = vw.toImage(function(){Ti.API.info('FORCE SYNC')}); Thanks in advance Regards Nico
@nico Yes 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.
Hi Vishal Something went wrong today. But I just checked en noticed I hadn't changed to new image file. I'll fix that tomorrow. One other question: The documentation for toImage() says: Parameters callback : Callback
@nico, You're right. Let me see whats going on.
@ncio I 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.
@vishal: Just 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?
PR : [4180](https://github.com/appcelerator/titanium_mobile/pull/4180)
TESTING INSTRUCTION
Use the following [code](https://gist.github.com/srahim/5407896) in your app.jsMake sure to include image files with
Click on the coverflow image to update the image with the current timestamp. Make sure the image new image does not get cropped..JPG
extension in the resources folder of your app.Closing ticket as fixed. Using Sabil's test code, verified half images are not displayed in the CoverFlowView after selecting the images. Tested on: Titanium Studio, build: 3.2.0.201310230548 OS: Mac OS X Mountain Lion (10.8.5) SDK build: 3.2.0.v20131023140842 Ti CLI: 3.2.0 (72f7426b4ee6c2d2883c666d5b7e03906a16012f) Devices: iphone 5 (6.1.3), iphone 5c (7.0.1)