Android Camera SurfaceView Orientation - android

I am building an app that uses the android camera. I use a FrameLayout that has 2 children. The first child is a SurfaceView that previews the Camera and the second child is a LinearLayout with some buttons.
I have read that in Android 2.1 and below, the only way to use the camera is on Landscape mode, so I use
android:screenOrientation="landscape" android:configChanges="keyboardHidden|orientation"
in my activity in the manifest file.
Is there a way to use the SurfaceView (camera) in landscape mode only, and use the LinearLayout (buttons) either portrait/landscape?
(For example in Google Goggles the camera doesn't change orientation but the buttons rotate when changing orientation.)

The Camera app included in Android is in AOSP. Check the source out for yourself. From the looks of it, it's fixed in landscape mode as well, but simply rotates the ImageViews when the user changes the orientation.
See this part of Camera's source.

The best way to solve is like AOSP does by using RotateImageView and special ImageView that you can set a rotation in degrees.
So in your Camera Activity you have to implement OrientationListener and onOrientationChanged you set the new Degrees to your RotateImageView. Here is the simple way but you can look for a better example at Camera implementation at
private class MyOrientationEventListener extends OrientationEventListener {
public MyOrientationEventListener(Context context) {
super(context);
}
#Override
public void onOrientationChanged(int orientation) {
mOrientation = roundOrientation(orientation);
((RotateImageView)findViewById(R.id.btnFlash)).setDegree(mOrientation);
}
}
public static int roundOrientation(int orientation) {
return ((orientation + 45) / 90 * 90) % 360;
}

Related

Camera data bytes[] always in landscape mode?

I have created a camera app and using the data to do something .But the data is always in landscape mode .
I have tried this which is making the preview in portrait mode but the byte[] I am getting still gives me a landscape photo.
public void surfaceCreated(SurfaceHolder holder) {
mCamera = Camera.open();
mCamera.setDisplayOrientation(90);
I know I can make it as a bitmap and rotate it 90 but I need only the data from onPictureTaken.
I also tried
param.setRotation(90);
Which is not working on some of the devices.
You are right, this is how camera API works (unlike iOS). There are some efficient methods that can rotate the pixels to portrait if you really need this, but they never come at 0 cost. So the best practice is to adjust your code that processes the arriving preview frames.

How can i detect orientation changes in portrait mode in android?

I need to show a camera preview in my app so that the photos can be taken by pushing a button.
So I put a pretty "standard" camera preview class. The problem is I have to put it in landscape mode so that the preview can stretch on the entire screen. If in portrait mode, it will remain only on the center of the screen, on a small part of it. If this can be solved easier, I am open to suggestions.
But my question is. If locked in landscape mode, how can i detect screen rotation so that i can rotate text of the button accordingly ?
I tried
#Override
public void onSensorChanged(SensorEvent event)
{
Log.d("onSensorChanged");
Log.d("event:" + event);
}
but I get no result.
Use OrientationEventListener:
orientationListener = new OrientationEventListener(context, SensorManager.SENSOR_DELAY_UI) {
public void onOrientationChanged(int orientation) {
//do something
}
};
use this simple method...
if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE)
{
// your code
}
OR
if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT)
{
// your code
}
First of all you should know that what happen whenever screen mode changed.
When screen mode changed its view created again it means if we can detect what screen mode is we can change our layout file or do other things in onCreate().
How how you can detect which screen mode is.
if(getResources().getConfiguration().orientation==Configuration.ORIENTATION_LANDSCAPE) {
//do something
}
Configuration class have different orientation Constant check it on developer site.

Rotate resulting Camera Images when the Activity is fixed to portrait

I am making an application with a built in camera. The Activity is fixed to portrait orientation but I want to have the images saved properly right-side up, like so:
Camera camera = getCameraInstance(); //method found on http://developer.android.com/guide/topics/media/camera.html
Camera.Parameters params = camera.getParameters();
params.setRotation(someInteger); //I want to get the proper value for this method
camera.setParameters(params);
Has anyone been able to achieve this?
If you're just trying to rotate the JPEG images you receive from calling takePicture, then setRotation is the right method to use.
Is the question about what value to pass into setRotation? Assuming you want real-world 'up' to be 'up' in the saved JPEG image, setRotate needs to be set based on the current orientation of the camera sensor relative to the world.
You can find out what the relative orientation of the whole device to the world is, and you can find out what the orientation of the camera sensor is relative to the device's 'natural' orientation, and combine the two rotations into the final answer. The math is easy to get wrong, which is why we have it explicitly spelled out in the API documentation for setRotation, reproduced here:
public void onOrientationChanged(int orientation) {
if (orientation == ORIENTATION_UNKNOWNsetRotation) return;
android.hardware.Camera.CameraInfo info =
new android.hardware.Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(cameraId, info);
orientation = (orientation + 45) / 90 * 90;
int rotation = 0;
if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
rotation = (info.orientation - orientation + 360) % 360;
} else { // back-facing camera
rotation = (info.orientation + orientation) % 360;
}
mParameters.setRotation(rotation);
}
You'll need to inherit from OrientationEventListener and implement the above for the callback method. Of course, you should check that your camera is open, and that mParameters, etc, is valid before updating the parameters.
Please note that this only rotates the JPEGs that are sent out by the camera. If you see that your preview is not correctly oriented in your UI, you need to call setDisplayOrientation for that. The camera sensor is normally lined up with the landscape orientation of the device, so landscape camera apps can often get away without calling this function, even though they should in case they're on an unusual Android device. However, if you're writing a portrait app, it's likely mandatory you adjust the display orientation to align with your UI. As with setRotation, you need to take a few factors into account, and sample code for doing the math right is included in the documentation.

Camera on surfaceview android rotation

I'm developing an application with camera and I use surfaceview to preview the camera, so when I start the preview the camera is rotated 90 degree or something like that it is in landscape but I hold my phone in portrait.
How can I make it start in regular position. The photos that I take are in landscape.
parameters.set("orientation", "landscape");
parameters.set("rotation", 90);
well you can pass your activity reference to surfaceview and check for orientation on surfaceCreated method by this code
if(yourActivity.getRequestedOrientation()==ActivityInfo.LANDSCAPE)
{
//perform you setting here
}
else if(yourActivity.getRequestedOrientation()==ActivityInfo.PORTRAIT)
{
//perform accordingly
}

Using Camera in Portrait Orientation

I'm trying to develop an app which uses the Camera. So far it's been working well, except that I'm unable to force the orientation to be "portrait". It seems to work well if I force all activities to "landscape", because the camera preview seems to fit in landscape.
Is there anyway to use the Camera in portrait mode?
Android devices v2.2 and above contain and API to rotate the display to portrait. Devices below 2.2 are landscape only. Your best bet is to detect if the device is 2.2 and rotate 90 degrees. Fall back on landscape for devices under 2.2. The good news is most Android devices are on 2.2 and above.
Check out my answer here for more info:
Camera is wrong unless keyboard is open
public void surfaceCreated(SurfaceHolder holder)
{
// The Surface has been created, acquire the camera and tell it where to draw.
mCamera = Camera.open();
Parameters params = mCamera.getParameters();
if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE)
{
params.set("orientation", "portrait");
mCamera.setDisplayOrientation(90);
}
try
{
mCamera.setPreviewDisplay(holder);
}
catch (IOException exception)
{
mCamera.release();
mCamera = null;
}
}
edit: I was in the midst of Adobe AIR for Android development when I answered this question, and looking back at it, I realize this question didn't pertain to Adobe AIR.
Adobe says:
On devices that can change the screen orientation, such as mobile phones, a Video object attached to the camera will only show upright video in a landscape-aspect orientation. Thus, mobile apps should use a landscape orientation when displaying video and should not auto-rotate.
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/media/Camera.html
If you do really want to use the camera in portrait mode, my suggestion is to rotate the video object.
Here's some sample code that rotates the video object (_video) by an angle in degrees (source was pulled from elsewhere on stackoverflow):
var matrix:Matrix = _video.transform.matrix;
var rect:Rectangle = _video.getBounds(this);
matrix.translate(- (rect.left + (rect.width/2)), - (rect.top + (rect.height/2)));
matrix.rotate((angle/180)*Math.PI);
matrix.translate(rect.left + (rect.width/2), rect.top + (rect.height/2));
_video.transform.matrix = matrix;

Categories

Resources