Android Camera preview reverse landscape Config - android

I want to set the camera preview in reverse landscape mode,When I am trying it by manifest orientation setting the preview shows as mirror view.I have an overlay over camera preview that's why I want reverse landscape mode,I am using android 4.0.
class Preview extends SurfaceView implements SurfaceHolder.Callback { // <1>
SurfaceHolder mHolder; // <2>
public Camera camera; // <3>
Preview(Context context) {
super(context);
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder(); // <4>
mHolder.addCallback(this); // <5>
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); // <6>
}
#Override
public void surfaceCreated(SurfaceHolder holder)
{
try {
if (camera != null) {
camera.setPreviewDisplay(holder);
}
} catch (IOException exception) {
Log.e("fd", "IOException caused by setPreviewDisplay()", exception);
}
} // Called when the holder is destroyed
#Override
public void surfaceDestroyed(SurfaceHolder holder) { // <14>
//camera.setParameters(Camera.Parameters.FLASH_MODE_OFF);
Parameters params = camera.getParameters();
params.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
camera.setParameters(params);
camera.stopPreview();
camera.release();
//camera = null;
}
// Called when holder has changed
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { // <15>
camera = Camera.open();
Parameters params = camera.getParameters();
List<Size> sizes = params.getSupportedPictureSizes();
Camera.Size size = sizes.get(0);
params.setFocusMode(Camera.Parameters.FOCUS_MODE_MACRO);
params.setWhiteBalance(Camera.Parameters.WHITE_BALANCE_AUTO);
params.setSceneMode(Camera.Parameters.SCENE_MODE_LANDSCAPE);
params.setFlashMode(Camera.Parameters.FLASH_MODE_ON);
params.setJpegThumbnailQuality(100);
params.setExposureCompensation(0);
params.setJpegQuality(100);
// params.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
/*
*
* Camera.Parameters parameters = camera.getParameters();
List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes();
// You need to choose the most appropriate previewSize for your app
Camera.Size previewSize = // .... select one of previewSizes here
parameters.setPreviewSize(previewSize.width, previewSize.height);
camera.setParameters(parameters);
camera.startPreview();
*/
//int w=0,h=0;
for(int i=0;i<sizes.size();i++)
{
if(sizes.get(i).width > size.width)
size = sizes.get(i);
}
params.setPictureSize(size.width, size.height);
//Toast.makeText(getContext(), size.width+"and"+size.height,Toast.LENGTH_SHORT).show();
camera.setParameters(params);
/* if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE)
{
params.set("orientation", "portrait");
camera.setDisplayOrientation(90);
}*/
camera.startPreview();
try
{
camera.setPreviewDisplay(holder);
}
catch (IOException exception)
{
camera.release();
camera = null;
}
}
}

All credits for this answer go to Jason Robinson.
Instead of using setCameraDisplayOrientation(), you can simply call camera.setDisplayOrientation(270);

Related

java.lang.RuntimeException: setParameters failed, while setting the camera parameters

I am making a Camera application. The preview picture was 90 degree rotated. So I changed my code and added the code to set the correct display orientation of the camera. Now when I run the app, it crashes and the error message is
java.lang.RuntimeException: setParameters failed
My surfaceChanged(SurfaceHolder holder,int format,int w,int h) and surfaceCreated(SurfaceHolder holder) methods are as shown.
public void surfaceChanged(SurfaceHolder holder,int format,int w,int h){
Camera.Parameters mparameters;
mholder = holder;
mparameters = mcamera.getParameters();
mparameters.setPreviewSize(mpreviewsizewidth,mpreviewsizeheight);
mparameters.setPictureSize(mpreviewsizewidth,mpreviewsizeheight);
String mCameraFlashMode = mparameters.getFlashMode();
if(mCameraFlashMode != null){
mparameters.setFlashMode(mparameters.FLASH_MODE_ON);
}
if(mparameters.getFocusMode() != null) {
mparameters.setFocusMode(mparameters.FOCUS_MODE_AUTO);
}
Display display = ((WindowManager)mcontext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
if(display.getRotation() == Surface.ROTATION_0)
{
mparameters.setPreviewSize(mpreviewsizeheight, mpreviewsizewidth);
mcamera.setDisplayOrientation(90);
}
if(display.getRotation() == Surface.ROTATION_90)
{
mparameters.setPreviewSize(mpreviewsizewidth, mpreviewsizeheight);
}
if(display.getRotation() == Surface.ROTATION_180)
{
mparameters.setPreviewSize(mpreviewsizeheight, mpreviewsizewidth);
}
if(display.getRotation() == Surface.ROTATION_270)
{
mparameters.setPreviewSize(mpreviewsizewidth, mpreviewsizeheight);
mcamera.setDisplayOrientation(180);
}
mcamera.setParameters(mparameters);
try {
mcamera.setPreviewDisplay(mholder);
}catch(IOException e){
e.printStackTrace();
}
mcamera.startPreview();
}
public void surfaceCreated(SurfaceHolder holder){
mcamera = Camera.open();
try{
mcamera.setPreviewDisplay(holder);
mcamera.setPreviewCallback(this);
}catch(IOException e){
mcamera.release();
mcamera = null;
}
}
Please help me how I can correct my code so that app does not crash while setting the camera parameters, and the preview can be displayed with correct orientation.
I guess you are trying to set a preview size which is not supported by Camera object.
You should get the list of supported previewSizes first to check what values you can actually set.
List<Camera.Size> sizes = cam.getParameters().getSupportedPreviewSizes();

Camera Preview is stretched and skewed

How to solve the streching of image in my camera preview?
Camera Preview Class
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
public class CameraPreview extends SurfaceView implements
SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
public CameraPreview(Context context, Camera camera) {
super(context);
mCamera = camera;
mHolder = getHolder();
mHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
try {
// create the surface and start camera preview
if (mCamera == null) {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
}
} catch (IOException e) {
Log.d(VIEW_LOG_TAG,
"Error setting camera preview: " + e.getMessage());
}
}
public void refreshCamera(Camera camera) {
if (mHolder.getSurface() == null) {
// preview surface does not exist
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e) {
// ignore: tried to stop a non-existent preview
}
// set preview size and make any resize, rotate or
// reformatting changes here
// start preview with new settings
setCamera(camera);
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e) {
Log.d(VIEW_LOG_TAG,
"Error starting camera preview: " + e.getMessage());
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// If your preview can change or rotate, take care of those events here.
// Make sure to stop the preview before resizing or reformatting it.
refreshCamera(mCamera);
}
public void setCamera(Camera camera) {
// method to set a camera instance
mCamera = camera;
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
// mCamera.release();
}
}
Maybe your CameraView's aspect ratio is not match with the aspect ratio of camera preview size.
You should caculate your CameraView's aspect ratio and use this aspect ratio to find best size for Camera.Parameters.setPreviewSize() method.
Try this
private Camera.Size getBestPreviewSize(Camera.Parameters parameters, int width, int height) {
Camera.Size result = null;
double ratio = width / height;
double w = 0, h = 0;
for (Camera.Size size : parameters.getSupportedPreviewSizes()) {
w = size.width;
h = size.height;
if (w / h == ratio) {
if (result != null) {
if (w > result.width) {
result = size;
}
} else {
result = size;
}
}
}
return (result);
}

Using Camera in Landscape Mode getting Preview in Portrait

Whenever i use my Camera in Landscape Mode getting View in Portrait, I prepared two different layout for Portrait and Landscape Modes.
like still i am getting Preview in Portrait Mode not matter i am using Camera in Landscape or in Portrait Mode, but once i remove this line: mCamera.setDisplayOrientation(90); i am getting Preview in Landscape mode, either i use Camera in Landscape or in Portrait Mode
PreviewSurface.java:-
public class PreviewSurface extends SurfaceView implements
SurfaceHolder.Callback {
public static final String LOG_TAG = "CameraPreview";
private SurfaceHolder mSurfaceHolder;
private Camera mCamera;
// Constructor that obtains context and camera
#SuppressWarnings("deprecation")
public PreviewSurface(Context context, Camera camera) {
super(context);
this.mCamera = camera;
this.mSurfaceHolder = this.getHolder();
this.mSurfaceHolder.addCallback(this);
this.mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
this.mSurfaceHolder.setFixedSize(100, 100);
}
#Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
try {
mCamera.setPreviewDisplay(surfaceHolder);
mCamera.startPreview();
} catch (IOException e) {
// left blank for now
}
}
#Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
mCamera.stopPreview();
mCamera.release();
}
#Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int format,
int width, int height) {
// start preview with new settings
try {
mCamera.setDisplayOrientation(90);
mCamera.setPreviewDisplay(surfaceHolder);
mCamera.startPreview();
} catch (Exception e) {
// intentionally left blank for a test
}
}
I suggest you to use : Configuration.ORIENTATION_LANDSCAPE to support Landscape Preview
Edit Answer:
#Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
try {
Camera.Parameters parameters = mCamera.getParameters();
if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
parameters.set("orientation", "portrait");
mCamera.setDisplayOrientation(90);
parameters.setRotation(90);
}
else {
// This is an undocumented although widely known feature
parameters.set("orientation", "landscape");
// For Android 2.2 and above
mCamera.setDisplayOrientation(0);
// Uncomment for Android 2.0 and above
parameters.setRotation(0);
}
mCamera.setPreviewDisplay(surfaceHolder);
mCamera.startPreview();
} catch (IOException e) {
// left blank for now
}
}
#Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
mCamera.stopPreview();
mCamera.release();
}
#Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int format,
int width, int height) {
try {
Camera.Parameters parameters = mCamera.getParameters();
if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
parameters.set("orientation", "portrait");
mCamera.setDisplayOrientation(90);
parameters.setRotation(90);
mCamera.setPreviewDisplay(surfaceHolder);
mCamera.startPreview();
}
else {
// This is an undocumented although widely known feature
parameters.set("orientation", "landscape");
// For Android 2.2 and above
mCamera.setDisplayOrientation(0);
// Uncomment for Android 2.0 and above
parameters.setRotation(0);
}
mCamera.setPreviewDisplay(surfaceHolder);
mCamera.startPreview();
} catch (IOException e) {
// left blank for now
}
}

Android flash mode as torch doesnt works

I am using the camera API and flash mode as torch but after taking one picture the flash is turning off.How can i turn on the flash again.?I am using android 2.3,How can I use flash mode as torch
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { // <15>
camera = Camera.open();
params = camera.getParameters();
List<Size> sizes = params.getSupportedPictureSizes();
Camera.Size size = sizes.get(0);
params.setFocusMode(Camera.Parameters.FOCUS_MODE_MACRO);
params.setWhiteBalance(Camera.Parameters.WHITE_BALANCE_AUTO);
params.setSceneMode(Camera.Parameters.SCENE_MODE_LANDSCAPE);
params.setFlashMode("torch");
params.setJpegThumbnailQuality(100);
params.setExposureCompensation(0);
params.setJpegQuality(100);
// params.setPreviewSize(PreviewSizeWidth,PreviewSizeHeight);
//now that you have the list of supported sizes, pick one and set it back to the parameters...
//int w=0,h=0;
for(int i=0;i<sizes.size();i++)
{
if(sizes.get(i).width > size.width)
size = sizes.get(i);
}
params.setPictureSize(size.width, size.height);
Toast.makeText(getContext(), size.width+"and"+size.height,Toast.LENGTH_SHORT).show();
camera.setParameters(params);
if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE)
{
params.set("orientation", "portrait");
camera.setDisplayOrientation(90);
}
camera.startPreview();
try
{
camera.setPreviewDisplay(holder);
}
catch (IOException exception)
{
camera.release();
camera = null;
}
}
}
Check this
private Camera camera;
if (camera == null) {
} else {
// Set the torch flash mode
Parameters param = camera.getParameters();
param.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
try {
camera.setParameters(param);
camera.startPreview();
} catch (Exception e) {
}
}
What do you do with the photo after you take it? Do you move to a different activity/fragment and then come back into the take photo fragment? Do you simply store the photo without ever leaving the current activity/fragment?
If you don't leave the activity/fragment, I'd suggest trying to restart the torch at the end of your last Camera.PictureCallback. Remember, the camera preview stops after taking a photo so you have to restart the preview. Perhaps something like:
mPictureCallback = new Camera.PictureCallback(){
#Override
public void onPictureTaken(byte[] data, Camera camera) {
// ... process your byte data ...
if(mCamera != null){
Camera.Parameters params = mCamera.getParameters();
params.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
mCamera.setParameters(params);
try{
mCamera.startPreview();
}catch(Exception e){
e.printStackTrace();
}
}
}
};
you need to call mCamera.stopPreview() before calling mCamera.setParameters(params); like below.
mCamera.stopPreview();
mCamera.setParameters(cameraParameters);
mCamera.startPreview();

Images from Custom Camera are blurry on Galaxy Nexus

I have a custom camera in the app and the images that are taken on most of the devices look good but on galaxy nexus the story is different. Images are blurry in Galaxy nexus. I see grainy lines on Motorola Atrix as well. But Droid X, Droid Razr, HTC Evo, HTC incredible are showing good results. Any idea why it would happpen? This is what I have so far.
P.S.: I am using Auto focus in the activity.
public class CameraPreview extends SurfaceView implements
SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
public CameraPreview(Context context, Camera camera) {
super(context);
mCamera = camera;
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, now tell the camera where to draw the
// preview.
try {
mCamera.setPreviewDisplay(holder);
Camera.Parameters parameters = mCamera.getParameters();
List<String> focusModes = parameters.getSupportedFocusModes();
if (focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
}
parameters.set("orientation", "portrait");
mCamera.setDisplayOrientation(90);
mCamera.setParameters(parameters);
mCamera.startPreview();
} catch (IOException e) {
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
if (mHolder.getSurface() == null) {
// preview surface does not exist
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e) {
// ignore: tried to stop a non-existent preview
}
try {
mCamera.startPreview();
} catch (Exception e) {
}
}
Its been a while I solved this problem. If I remember it correctly, I solved by adding the below lines while getting the camera instance.
Camera.Parameters parameters = camera.getParameters();
List<Camera.Size> sizes = parameters.getSupportedPictureSizes();
int w = 0, h = 0;
for (Size size : sizes) {
if (size.width > w || size.height > h) {
w = size.width;
h = size.height;
}
}
parameters.setPictureSize(w, h);
Have you tried this one ?
if (cameraParameters.getSupportedSceneModes().contains(Camera.Parameters.SCENE_MODE_STEADYPHOTO)) {
cameraParameters.setSceneMode(Camera.Parameters.SCENE_MODE_STEADYPHOTO);
}

Categories

Resources