Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-20319] iOS: Weird behavior after crop the image captured from camera

GitHub Issuen/a
TypeBug
PriorityCritical
StatusClosed
ResolutionFixed
Resolution Date2016-09-05T03:13:32.000+0000
Affected Version/sRelease 5.1.2
Fix Version/sRelease 6.0.0
ComponentsiOS
Labelsn/a
ReporterShuo Liang
AssigneeHans Knöchel
Created2016-02-03T12:47:50.000+0000
Updated2016-09-27T21:31:05.000+0000

Description

Description

Simply run the following code in a default mobile app. Basically, the test case is 1. open a camera 2. capture a image 3. crop the image from step 2 (based on the layout of UI).

Expect Result:

The result image should be the same like inside the red rectangle area

Actual Result:

The result image is not as expected, and the orientation is wrong as well.

Code

var cameraOverLayColor = '#96000000';
var imageView;
var responseImg;
var width, height, x, y;

var win = Titanium.UI.createWindow({
	backgroundColor:'white',
	theme:'Theme.AppCompat.NoTitleBar',
	layout:'vertical'
});

win.open();

var cameraLbl = Ti.UI.createLabel({
	top:20,
	color:'blue',
	text: 'Open Camera',
	width : Ti.UI.SIZE,
	height : Ti.UI.SIZE
});
win.add(cameraLbl);

cameraLbl.addEventListener('click',doCamera);

var mainContainer = Titanium.UI.createView();

var scanner = Titanium.UI.createView({
	top : '5%',
	width : '80%',
	height : '85%',
	borderColor : 'red',
	borderWidth : 5,
	borderRadius : 1
});

var leftView = Ti.UI.createView({
	left:0,
	backgroundColor:cameraOverLayColor,
	width : '10%',
	height : '100%' 
});

var rightView = Ti.UI.createView({
	right:0,
	backgroundColor:cameraOverLayColor,
	width :  '10%',
	height : '100%' 
});

var topView = Ti.UI.createView({
	top:0,
	backgroundColor:cameraOverLayColor,
	width : '80%',
	height :'5%'
});

var bottomView = Ti.UI.createView({
	bottom:0,
	backgroundColor:cameraOverLayColor,
	width : '80%',
	height :'10%'
});

mainContainer.add(leftView);
mainContainer.add(rightView);
mainContainer.add(topView);
mainContainer.add(bottomView);
mainContainer.add(scanner);


var takeButton = Titanium.UI.createButton({
	color : '#fff',
	left: 0,
	font : {
		fontSize : 20,
		fontWeight : 'bold',
	},
	title : 'Take Picture'
});

var cancelButton = Titanium.UI.createButton({
	color : '#fff',
	right: 0,
	font : {
		fontSize : 20,
		fontWeight : 'bold',
	},
	title : 'Cancel'
});

bottomView.add(takeButton);
bottomView.add(cancelButton);

takeButton.addEventListener('click', function() {
	scanner.borderColor = 'blue';
	Ti.Media.takePicture();
});

cancelButton.addEventListener('click', function() {
	Ti.Media.hideCamera();
});


function doCamera(){	
	Titanium.Media.showCamera({
		saveToPhotoGallery : false,
		
		success : function(event) {
			if (event.media) {
				responseImg = event.media;
				
				Ti.API.info(responseImg.getWidth());
				Ti.API.info(responseImg.getheight());
				
				// get detail CroppedDict
				width = responseImg.getWidth() * 0.8;
				height = responseImg.getheight() * 0.85;
				x = responseImg.getWidth() * 0.1;
				y = responseImg.getheight() * 0.05;
				
				Ti.API.info(width);
				Ti.API.info(height);
				Ti.API.info(x);
				Ti.API.info(y);
				
				responseImg = responseImg.imageAsCropped({width: height, height: width, x: x, y: y});

				if(!imageView){
					imageView = Ti.UI.createImageView({
						image : responseImg,
						autorotate: true,
						width : Ti.UI.SiZE,
						height : Ti.UI.SIZE
				});
				win.add(imageView);
			}else{
				Ti.API.info("error");
			}

			Ti.Media.saveToPhotoGallery(responseImg,{
				success: function(e) {
					Titanium.UI.createAlertDialog({
    					buttonNames : ['OK'],
        				title:'Photo Gallery',
        				message:'Check your photo gallery for image.'
    				}).show();      
				},
				error: function(e) {
    				Titanium.UI.createAlertDialog({
    					buttonNames : ['OK'],
        				title:'Error saving',
        				message:e.error
    				}).show();
				}
			});
			}else{
				Titanium.UI.createAlertDialog({
					title : 'Camera',
					message:'Unexpected error',
					buttonNames : ["OK"]
				}).show();
			}
			scanner.borderColor = 'red';
		},

		cancel : function() {
		},
	
		error : function(error) {
			var a = Titanium.UI.createAlertDialog({
				title : 'Camera'
			});
		
			if (error.code == Titanium.Media.NO_CAMERA) {
				a.setMessage('Please run this test on device');
			} else {
				a.setMessage('Unexpected error: ' + error.code);
			}
			a.show();
		},

		overlay : mainContainer,
		showControls : false, 
		mediaTypes : Ti.Media.MEDIA_TYPE_PHOTO,
		autohide : true 
	});
}

Comments

  1. Hans Knöchel 2016-02-23

    Before I do further investigations, did you make sure it does not happen from using getheight instead of getHeight ?
  2. Shuo Liang 2016-02-23

    Any difference? Also I print out the Ti.API.info(responseImg.getheight()); And the result seems all right.
  3. Hans Knöchel 2016-02-23

    Ok. Does ist work properly on Android? Trying to troubleshoot as much as possible beforehand.
  4. Hans Knöchel 2016-02-25

    Ok, some more infos and questions: - The problems looks to happen inside the imageAsCropped method, not directly from the camera - Did it work with previous SDK versions? Can you confirm that? I will now create a simplified test case to crop a view to make the debug more easy. *Update:* Check [this demo](https://gist.github.com/hansemannn/cd11ccac9243ebe1b8ec) and [this output](http://abload.de/img/simulatorscreenshot2559rv8.png). What is very interesting: The x and y coordinated define the center inside the origin, not the offset to create the rect. So if you set the width relative to the new width and height (40% and 42,5%), it should work pretty well.
  5. Chee Kiat Ng 2016-09-05

    Issue was fixed in related ticket for 6.0.0.
  6. Lee Morris 2016-09-27

    Verified with all three attached code samples that the feature is behaving as expected. Verified with; NPM Version: 2.15.9 Node Version: 4.5.0 Mac OS: 10.11.6 Appc CLI: 5.5.0 Appc CLI NPM: 4.2.7 Titanium SDK version: 6.0.0.v20160927062927 Appcelerator Studio, build: 4.7.1.201609100950 Xcode 8.0 GM

JSON Source