Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-17329] Android: Refactor Camera API to not use a temporary file

GitHub Issuen/a
TypeImprovement
PriorityHigh
StatusClosed
ResolutionFixed
Resolution Date2014-08-18T18:25:27.000+0000
Affected Version/sn/a
Fix Version/sRelease 3.4.0
ComponentsAndroid
Labelsmodule_media, qe-manualtest
ReporterIngo Muschenetz
AssigneePing Wang
Created2014-07-15T04:19:25.000+0000
Updated2014-08-18T18:25:27.000+0000

Description

In Titanium, we use temporary files when we are dealing with data that can not be kept in memory to avoid OOM errors. One case is in the Ti.Media module when the user takes pictures and the savetoPhotoGallery is set to false. The blob representing the response (media property for the payload to the success callback) will clearly indicate if the blob represents a file (Titanium.Blob.file will return a valid Titanium.Filesystem.File object). Users are free to delete the file once they have processed the data. We should refactor the API to not rely on the temporary file.

Comments

  1. Ping Wang 2014-07-16

  2. Vishal Duggal 2014-07-22

    Test case from TIMOB-1510
       var win1 = Titanium.UI.createWindow({
           backgroundColor : '#fff',
           exitOnClose:true
       });
          
       var saveToGallery = false;
         
       var hasCamera = Ti.Media.isCameraSupported;
         
       if(hasCamera) {
           var hasBackfacingCamera = hasCamera;
           var hasFrontfacingCamera = hasCamera;
           var front = false;
           var availableCameras = Ti.Media.availableCameras;
             
           hasBackfacingCamera = (availableCameras.indexOf(Ti.Media.CAMERA_REAR) >= 0);
           hasFrontfacingCamera = (availableCameras.indexOf(Ti.Media.CAMERA_FRONT) >= 0);
         
           var b1 = Ti.UI.createButton({
               title:'Save To Gallery',
               left:0,
               top:0,
               color:'red',
               width:'50%',
               height:'10%',
               backgroundColor:'black',
           }) ;
             
           var b2 = Ti.UI.createButton({
               title:'View Gallery',
               right:0,
               top:0,
               width:'50%',
               height:'10%',
               backgroundColor:'black',
               color:'white'
           });
             
           win1.add(b1);
           win1.add(b2);
             
           var container = Ti.UI.createView({
               top:'10%',
               height:'80%'
           });
             
           var img = Ti.UI.createImageView({
           });
             
           var saveButton = Ti.UI.createButton({
               title:'SAVE',
               backgroundColor:'black',
               color:'white',
               visible:false
           });
             
           container.add(img);
           container.add(saveButton);
           win1.add(container);
             
             
           var b3 = Ti.UI.createButton({
               title:'Native Camera',
               top:'90%',
               height:'10%',
               left:0,
               width:'50%',
               backgroundColor:'black',
               color:'white'
           });
           win1.add(b3);
             
           var b4 = Ti.UI.createButton({
               title:'Camera Overlay',
               top:'90%',
               height:'10%',
               right:0,
               width:'50%',
               backgroundColor:'black',
               color:'white'
           });
             
           win1.add(b4);
             
           var overlayObj = Ti.UI.createView({});
           var picBtn = Ti.UI.createButton({
               title:'Snap Picture',
               top:'90%',
               height:'10%',
               left:0,
               width:'50%',
               backgroundColor:'black',
               color:'white'
           });
           overlayObj.add(picBtn);
           picBtn.addEventListener('click',function(){
               Ti.Media.takePicture();
           });
           if(hasFrontfacingCamera && hasBackfacingCamera) {
               var swapBtn = Ti.UI.createButton({
                   title:'Switch Camera',
                   top:'90%',
                   height:'10%',
                   right:0,
                   width:'50%',
                   backgroundColor:'black',
                   color:'white'
               });
                 
               overlayObj.add(swapBtn);
               swapBtn.addEventListener('click',function(){
                   if(front == true) {
                       Ti.Media.switchCamera(Ti.Media.CAMERA_REAR);
                   } else {
                       Ti.Media.switchCamera(Ti.Media.CAMERA_FRONT);
                   }
                   front = !front; 
               });
           } else {
               //Adjust Button
               picBtn.width = Ti.UI.FILL;
           }
             
             
           saveButton.addEventListener('click',function(e){
               if(img.image != undefined) {
                   Ti.Media.saveToPhotoGallery(img.image,{
                       success:function(){
                           alert('Saved. Check In Gallery');
                       },
                       error:function(e){
                           var msg = 'Code: '+e.code+' Msg: '+e.error;
                           alert(msg);
                       }
                   });
                     
               } else {
                   Ti.API.info('NO IMAGE ON img to save to photo gallery');
               }
           });
             
           b1.addEventListener('click',function(){
               saveToGallery = !saveToGallery;
               if(saveToGallery == true) {
                   b1.color = 'green';
               } else {
                   b1.color = 'red';
               }
           });
             
             
           b2.addEventListener('click',function(){
               Ti.Media.openPhotoGallery({});
           });
             
             
           b3.addEventListener('click',function(){
               fireUpTheCamera(saveToGallery,false, false);
           });
             
           b4.addEventListener('click',function(){
               if(hasBackfacingCamera && hasFrontfacingCamera) {
                   //Alwways start with back camera
                   front = false;
               } else {
                   //Start with what ever camera is available
                   front = hasFrontfacingCamera;
               }
               fireUpTheCamera(saveToGallery,true, front);
           });
             
           function fireUpTheCamera(save, hasoverlay, front) {
               var options = {
                   success : function(e) {
                       Ti.API.info('GOT SUCCESS CALLBACK. File location = '+e.media.nativePath);
                       var imgWid = e.media.width;
                       var imgHeight = e.media.height;
                       var mSize = container.size;
                       var mW = mSize.width;
                       var mH = mSize.height;
                         
                       var wS = imgWid/mW;
                       var hS = imgHeight/mH;
                       var tS = (wS < hS) ? wS : hS;
                         
                       var dstWid = imgWid/tS;
                       var dstHeight = imgHeight/ tS;
                         
                       Ti.API.info(imgWid+' '+imgHeight+' '+mW+' '+mH+' '+wS+' '+hS+' '+tS+' '+dstWid+' '+dstHeight);
                       var resize = e.media.imageAsResized(dstWid,dstHeight);
                       img.image = resize;
                       saveButton.visible = true;
                   },
                   cancel : function() {
                       // create alert
                       var a = Titanium.UI.createAlertDialog({
                           title : 'Camera',
                           message: 'Action cancelled by user'
                       });
                       a.show();     
                   },
                   error : function(error) {
                       // create alert
                       var a = Titanium.UI.createAlertDialog({
                           title : 'Camera'
                       });
               
                       // set message
                       var msg = 'Unexpected error: ' + error.code;
                       if(error.error != undefined) {
                           msg = msg + ' Message: '+error.error;
                       }
                       a.setMessage(msg);
                       a.show();
                   },
                   saveToPhotoGallery : save,
                   mediaTypes : [Ti.Media.MEDIA_TYPE_PHOTO],
                   autohide: true
               };
               if(hasoverlay) {
                   options.overlay = overlayObj;
               }
               if(front) {
                   options.whichCamera = Ti.Media.CAMERA_FRONT;
               }
               Titanium.Media.showCamera(options);
           }
       }else {
           var label = Ti.UI.createLabel({
               text:'NO CAMERAS ON DEVICE',
               color:'red'
           });
           win1.add(label);
       }
         
       win1.open();
       
  3. Vishal Duggal 2014-07-22

    CR + FR ok. Merged
  4. Ping Wang 2014-07-25

    3_3_X PR: https://github.com/appcelerator/titanium_mobile/pull/5935
  5. Lokesh Choudhary 2014-08-18

    Verified the refactor. The pics does not get saved as a temp file in the sdcard when "save to gallery" is false. Closing. Environment: Appc Studio : 3.4.0.201408051600 Ti SDK : 3.4.0.v20140815142514 Mac OSX : 10.8.5 Alloy : 1.4.1 CLI - 3.3.0 Code Processor: 1.1.1 Nexus 5 - android 4.4.4

JSON Source