user3137766
user3137766

Reputation:

Titanium Unable to load bitmap. Not enough memory: Failed to allocate

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

Answers (1)

developer82
developer82

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

Related Questions