I'm currently working on an application which uses camera input from iOS devices on the iPhone 3GS and up. Using the native Camera and Video classes, I am able to render the camera input from these devices to the screen. In the case of this current applicaiton, the input renders into a frame sized 640x640, and then is upscaled based on the device's camera and screen resolutions (as well as the device's application memory allocation) and drawn to BitmapData in order to be saved.
In order to set the resolution of the camera input initially, I am using the setMode() function, in which I pass in the default resolution for that device's camera based on the conditions mentioned above. This works well across the board, save for the newer devices equipped with the higher resolution cameras. On the iPad 3 and iPhone 4s, I seem to be losing a portion of the images - about 200px - on each of the edges. The resulting input looks like a slightly zoomed-in camera.
I've experimented with many varying resolutions and aspect ratios on this device - all with the same results. I've also ensured that the favorArea parameter in setMode is set to true (though I've tried setting it to false just for kicks). It seems the only way I can avert this problem is if I don't call the setMode() function at all. This won't work though, as the default resolution for the Camera is set to 160x120, which is far too low-res for my needs.
Are there any caveats with the Camera class that might cause this?
Thanks!
EDIT: This project is using Air 3.3 release.
EDIT 2: Another interesting detail: The FaceTime (front facing) camera doesn't have this problem. Not surprisingly, it is a significantly lower resolution camera than the rear one.
Sure thing. For NDA reasons I can't divulge the exact source for this, but I took the time to extract the relevant parts. Please keep in mind that this code is part of a larger class, and thus logic inconsistencies are likely due to redacted code. The important parts here are in the setCameraResolution function. When an iPad 3 or iPhone 4S are run through this function, the resolution gets set correctly, but you lose the edges of the image. Strangely enough, if you do switchCamera, the front-facing camera renders input correctly.
public class StateCamera extends StateBaseView
{
private var videoWrapper:flash.display.Sprite;
private var vid:Video;
private var camInput:Camera = new Camera();
private var cameraNames:Array = Camera.names;
private var currentCameraIndex:int = 0;
private var DEVICE_CAMERA_RESOLUTIONS:Object = new Object();
public function StateCamera()
{
camInput = Camera.getCamera(currentCameraIndex.toString());
DEVICE_CAMERA_RESOLUTIONS[Constants.DEVICE_TYPE_IPAD3.toStr ing()] = 2448;
DEVICE_CAMERA_RESOLUTIONS[Constants.DEVICE_TYPE_IPAD2.toStr ing()] = 720;
DEVICE_CAMERA_RESOLUTIONS[Constants.DEVICE_TYPE_IPOD.toStri ng()] = 512;
DEVICE_CAMERA_RESOLUTIONS[Constants.DEVICE_TYPE_IPHONE4.toS tring()] = 2448;
DEVICE_CAMERA_RESOLUTIONS[Constants.DEVICE_TYPE_IPHONE3.toS tring()] = 1536;
DEVICE_CAMERA_RESOLUTIONS[Constants.UNKNOWN_DEVICE.toString ()] = 640;
vid = new Video(640, 640);
init()
}
public function init():void
{
Button(mLayoutSpriteTop.getChildByName("btnFlipCamera")).ca llback = switchCamera;
if(cameraNames.length <= 1)
{
mLayoutSpriteTop.getChildByName("btnFlipCamera").visib le = false;
}
setCameraResolution();
videoWrapper = new flash.display.Sprite();
vid.attachCamera(camInput);
videoWrapper.addChild(vid);
addChild(videoWrapper);
}
public function setCameraResolution():void
{
if(DEVICE_CAMERA_RESOLUTIONS.hasOwnProperty(Constants.CURRE NT_DEVICE_TYPE.toString()))
{
var res:int = DEVICE_CAMERA_RESOLUTIONS[Constants.CURRENT_DEVICE_TYPE.toString()];
camInput.setMode(res, res, 25, true);
}
else
{
camInput.setMode(CAM_RES_DEFAULT, CAM_RES_DEFAULT, 25, true);
}
}
public function switchCamera(e:Event = null):void
{
currentCameraIndex++;
if(currentCameraIndex >= cameraNames.length)
{
currentCameraIndex = 0;
}
camInput = Camera.getCamera(currentCameraIndex.toString());
setCameraResolution();
vid.attachCamera(camInput);
}
}
May be I am missing something, but I am unable to reproduce the issue. The camera preview looks just fine on iPad3 with the following simple code (reduced form of your code) -
package
{
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.media.Camera;
import flash.media.Video;
public class cam extends Sprite
{
private var camera:Camera = null;
private var vid:Video = null;
public function cam()
{
super();
// support autoOrients
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
vid = new Video(640, 640);
vid.x = vid.y =0;
camera = Camera.getCamera();
camera.setMode(2448, 2448, 25,true);
addChild(vid);
vid.attachCamera(camera);
}
}
}
To my knowledge, this has yet to be fixed. We ended up releasing as-is on iOS. On Android devices, you're better off just using the native camera, as Starling on Android requires you to set the prevent_lost_context flag to true anyways. Be warned though, that due to the varying hardware configurations on Android, you might randomly lose the ability to access the camera due to insufficient memory allocation. In this case, you should make sure to have logic which can redirect to the CameraRoll.
North America
Europe, Middle East and Africa
Asia Pacific