Reputation:
I am about to create a simple app that capture photo from camera and append it to imageView :
The view
<Alloy>
<Window id="wCustomEvent" class="container">
<View layout="vertical" top="100dp">
<Label onClick='readF' id="lien" text='Image path' />
<View id="imageContainer" />
</View>
</Window>
The controller :
function writeToFile(data) {
app = {};
app.writeToFile = function(filedata) {
file = Titanium.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, 'avatar.txt');
if (!file.exists) {
file.createFile();
}
file.write(filedata, false);
Ti.App.fireEvent('datachanged', {
newdata : filedata
});
};
Ti.App.addEventListener('datachanged', function(evt) {
Ti.API.info('datachanged event' + JSON.stringify(evt));
});
//source = evt.source;
//data = source.dataText;
app.writeToFile(data);
}
function readF() {
file = Titanium.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, 'avatar.txt');
if (file.exists) {
var content = file.read();
return content.text;
}
//Ti.App.fireEvent('datachanged', {newdata:'tet'});
}
/* Android Camera */
var win = Titanium.UI.currentWindow;
$.imageContainer.addEventListener("click", function(_event) {
Titanium.Media.showCamera({
success : function(event) {
var image = event.media;
// I TRY TO RESIZE IMAGE HERE
var img = image.imageAsResized(80,80);
Ti.API.debug('Our type was: ' + event.mediaType);
Ti.Media.hideCamera();
if (event.mediaType == Ti.Media.MEDIA_TYPE_PHOTO) {
// THE IMAGE PATH
imagePath = img.nativePath;
/* Write image path to file */
writeToFile(imagePath);
/* Get image path from file */
fichier = readF();
if( $.wCustomEvent.avatarPlaceholder ){
$.wCustomEvent.remove(avatarPlaceholder);
}
var avatar = Ti.UI.createImageView({
id:'avatarPlaceholder',
width: 80,
height:80,
borderRadius:40,
backgroundColor:'red',
image : fichier
});
$.imageContainer.add(avatar);
$.imageContainer.backgroundImage = fichier;
} else {
alert("got the wrong type back =" + event.mediaType);
}
},
cancel : function() {
alert('You canceled the action.');
},
error : function(error) {
// create alert
var a = Titanium.UI.createAlertDialog({
title : 'Camera'
});
// set message
if (error.code == Titanium.Media.NO_CAMERA) {
a.setMessage('Please run this test on device');
} else {
a.setMessage('Unexpected error: ' + error.code);
}
// show alert
a.show();
},
saveToPhotoGallery : false,
showControls : true, // don't show system controls
mediaTypes : Ti.Media.MEDIA_TYPE_PHOTO,
autohide : false
});
});
When i run it, i can capture photo, append to the view but i receive this message :
art: Throwing OutOfMemoryError "Failed to allocate a 38340876 byte allocation with 7738667 free bytes and 7MB until OOM"
[ERROR] : TiUIHelper: (main) [65,159991] Unable to load bitmap. Not enough memory: Failed to allocate a 38340876 byte allocation with 7738667 free bytes and 7MB until OOM
And when i try to capture second image, it's not working.
Any titanium gourou here ? thank you for help.
Upvotes: 0
Views: 545
Reputation: 13713
What you are facing is not a Titanium problem, It's an Android problem (for example: Android:java.lang.OutOfMemoryError: Failed to allocate a 23970828 byte allocation with 2097152 free bytes and 2MB until OOM).
What happens is that Android loads the image as bitmaps and needs to allocate memory according to the image resolution (size of the image) - and for really big images - it can't - and really doesn't need to in order to show them on screen. So what needs to be done in order to display images is to make them smaller before showing them - and an ImageView control will do that for you.
What you are doing is try to show the image as a backgroundImage
for a View
control. Instead, use an ImageView
and set it's image
property.
Upvotes: 1