Android, camera in my app is rotated - android

i'm opening the Camera in my app and the cam display is rotated by 90deg allways even when i rotating the device in my hands.
the code:
import java.io.IOException;
import java.util.List;
import android.content.Context;
import android.hardware.Camera;
import android.view.Display;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.WindowManager;
public class CameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback
{
private SurfaceHolder holder;
private Camera camera;
private Context context;
public CameraSurfaceView(Context context)
{
super(context);
//Initiate the Surface Holder properly
this.holder = this.getHolder();
this.holder.addCallback(this);
this.holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
this.context = context;
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// Now that the size is known, set up the camera parameters and begin
// the preview.
Camera.Parameters parameters = camera.getParameters();
List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes();
Camera.Size size = previewSizes.get(0);
parameters.setPreviewSize(size.width, size.height);
Display display = ((WindowManager)context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
if(display.getOrientation() == Surface.ROTATION_0)
{
//parameters.setPreviewSize(height, width);
parameters.setRotation(90);
}
if(display.getOrientation() == Surface.ROTATION_90)
{
//parameters.setPreviewSize(width, height);
}
if(display.getOrientation() == Surface.ROTATION_180)
{
//parameters.setPreviewSize(height, width);
}
if(display.getOrientation() == Surface.ROTATION_270)
{
//parameters.setPreviewSize(width, height);
parameters.setRotation(180);
}
camera.setParameters(parameters);
camera.startPreview();
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
try
{
//Open the Camera in preview mode
this.camera = Camera.open();
this.camera.setPreviewDisplay(this.holder);
}
catch(IOException ioe)
{
ioe.printStackTrace(System.out);
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// Surface will be destroyed when replaced with a new screen
//Always make sure to release the Camera instance
camera.stopPreview();
camera.release();
camera = null;
}
}
Any ideas ? Thanks
p.s how do i know what is the correct choose for my device in the line
List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes();

I used this code, when i wanted to display the camera preview correctly
Camera.Parameters parameters = camera.getParameters();
parameters.set("jpeg-quality", 100);
parameters.set("orientation", "landscape");
parameters.set("rotation", 90);
parameters.setPictureFormat(PixelFormat.JPEG);
parameters.setPreviewSize(w, h);
camera.setParameters(parameters);

Look at the example code given in Camera.setDisplayOrientation(int degrees) method reference. Note that you should perform these actions before calling setPreviewDisplay (SurfaceHolder)

Related

Camera Preview Stretched on Front Facing Camera

Hello there I am working on an android custom camera app and facing a problem of the camera preview stretching on the following device on their front camera:
huawei Honor 4c (only on front facing camera)
HTC One M7 (only on front facing camera)
Some other devices also...as I have just the following devices to test so may be problem resides on other devices too.
The thing is that the camera preview works very well with the back camera but it only stretches when I use my app with the front facing camera!
The Code
Here is the code I am using for my Camera Preview Class:
import android.content.Context;
import android.graphics.Rect;
import android.hardware.Camera;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.FrameLayout;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
//Variables de' Preview
private SurfaceHolder mHolder;
private List<Camera.Size> mSupportedPreviewSizes;
private Camera.Size mPreviewSize;
private int FOCUS_AREA_SIZE=300;
public static Camera previewCamera;
////////////////////////
//protected LOGGER keys
protected final String EXCEPTION_KEY="xception";
//////////////////////////
public CameraPreview(Context context, Camera camera) {
super(context);
//get the camera
previewCamera = camera;
// supported preview sizes
mSupportedPreviewSizes = previewCamera.getParameters().getSupportedPreviewSizes();
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mHolder.setKeepScreenOn(true);
}
#Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
try{
//when the surface is created, we can set the camera to draw images in this surfaceholder
previewCamera.setPreviewDisplay(surfaceHolder);
previewCamera.startPreview();
} catch(Exception exp){
Log.i(EXCEPTION_KEY,"FROM surfaceCreated: "+exp.toString());
}
}
#Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i2, int i3) {
//before changing the application orientation, you need to stop the preview, rotate and then start it again
if(mHolder.getSurface() == null)//check if the surface is ready to receive camera data
return;
try{
previewCamera.stopPreview();
} catch (Exception e){
//this will happen when you are trying the camera if it's not running
}
//now, recreate the camera preview
try{
//set the camera preview on every preview change
setPreview();
previewCamera.setPreviewDisplay(mHolder);
previewCamera.startPreview();
} catch(Exception exp){
Log.i(EXCEPTION_KEY,"FROM surfaceChanged: "+exp.toString());
}
}
public void setPreview(){
try{
//set the focusable true
this.setFocusable(true);
//set the touch able true
this.setFocusableInTouchMode(true);
//set the camera display orientation lock
previewCamera.setDisplayOrientation(90);
//get the camera parameters
Camera.Parameters parameters = previewCamera.getParameters();
//set the preview size
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
//set the parameter
previewCamera.setParameters(parameters);
}catch(Exception exp){
Log.i(EXCEPTION_KEY,"FROM setPreview: "+exp.toString());
}
}
#Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
//our app has only one screen, so we'll destroy the camera in the surface
//if you are using with more screens, please move this code your activity
try{
//handle in Activity onResume and onPause
}catch(Exception exp){
Log.i(EXCEPTION_KEY,"FROM surfaceDestroyed: "+exp.toString());
}
}
//Override Methods here
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
try{
final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
setMeasuredDimension(width, height);
if (mSupportedPreviewSizes != null) {
mPreviewSize = PreviewSizeParameters.getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
}
}catch(Exception exp){
Log.i(EXCEPTION_KEY,"FROM onMeasure: "+exp.toString());
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
private void stopPreviewAndFreeCamera() {
if (previewCamera != null) {
// Call stopPreview() to stop updating the preview surface.
previewCamera.stopPreview();
// Important: Call release() to release the camera for use by other
// applications. Applications should release the camera immediately
// during onPause() and re-open() it during onResume()).
previewCamera.release();
previewCamera = null;
}
}
//end of class here
}
Can somebody please tell me what am I missing in my code because it only affects on some devices using FRONT FACING CAMERA only.
Thanks
The following code worked in my environment.
Call getOptimalPreviewSize in surfaceChanged with SurfaceView's with and height.
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
...
#Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int w, int h) {
//before changing the application orientation, you need to stop the preview, rotate and then start it again
if(mHolder.getSurface() == null)//check if the surface is ready to receive camera data
return;
try{
previewCamera.stopPreview();
} catch (Exception e){
//this will happen when you are trying the camera if it's not running
}
//now, recreate the camera preview
try{
//set the focusable true
this.setFocusable(true);
//set the touch able true
this.setFocusableInTouchMode(true);
//set the camera display orientation lock
previewCamera.setDisplayOrientation(90);
Camera.Parameters params = previewCamera.getParameters();
List<Camera.Size> sizes = params.getSupportedPreviewSizes();
Camera.Size optimalSize = getOptimalPreviewSize(sizes,w,h);
params.setPreviewSize(optimalSize.width,optimalSize.height);
previewCamera.setParameters(params);
previewCamera.setPreviewDisplay(mHolder);
previewCamera.startPreview();
} catch(Exception exp){
Log.i(EXCEPTION_KEY,"FROM surfaceChanged: "+exp.toString());
}
}
...
private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {
final double ASPECT_TOLERANCE = 0.1;
double targetRatio=(double)h / w;
if (sizes == null) return null;
Camera.Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
int targetHeight = h;
for (Camera.Size size : sizes) {
double ratio = (double) size.width / size.height;
if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
if (optimalSize == null) {
minDiff = Double.MAX_VALUE;
for (Camera.Size size : sizes) {
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
}
return optimalSize;
}
//end of class here
}

Camera preview is distorted

I have some troubles with camera. I test my code on Xiaomi Mi2a and preview was distorted.
I have this line in manifest: android:screenOrientation="portrait"
I use camera with this fragment:
import android.app.Fragment;
import android.content.res.Configuration;
import android.hardware.Camera;
import android.os.Bundle;
import android.view.*;
import android.widget.
import java.io.IOException;
import java.util.List;
public class CameraFragment extends Fragment implements SurfaceHolder.Callback, Camera.PictureCallback, Camera.PreviewCallback, Camera.AutoFocusCallback, View.OnClickListener {
private Camera mCamera;
private SurfaceHolder mSurfaceHolder;
private SurfaceView mPreview;
private ImageButton mTakePicture;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.camera_fragment, container, false);
mPreview = (SurfaceView) v.findViewById(R.id.svCameraView);
mSurfaceHolder = mPreview.getHolder();
mSurfaceHolder.addCallback(this);
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mTakePicture = (ImageButton) v.findViewById(R.id.ibTakePicture);
mTakePicture.setOnClickListener(takePictureOnClickListener);
ImageButton switchCameraButton = (ImageButton) v.findViewById(R.id.ibSwitchCamera);
switchCameraButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
return v;
}
View.OnClickListener takePictureOnClickListener = new View.OnClickListener() {
#Override
public void onClick(View view) {
}
};
#Override
public void onResume() {
super.onResume();
mCamera = Camera.open();
}
#Override
public void onPause() {
super.onPause();
if (mCamera != null) {
mCamera.setPreviewCallback(null);
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
try {
mCamera.setPreviewDisplay(holder);
mCamera.setPreviewCallback(this);
} catch (IOException e) {
e.printStackTrace();
return;
}
Camera.Parameters parameters = mCamera.getParameters();
List<String> flashModes = parameters.getSupportedFlashModes();
/*if (flashModes != null && flashModes.contains(Camera.Parameters.FLASH_MODE_OFF))
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);*/
List<String> whiteBalance = parameters.getSupportedWhiteBalance();
if (whiteBalance != null && whiteBalance.contains(Camera.Parameters.WHITE_BALANCE_AUTO))
parameters.setWhiteBalance(Camera.Parameters.WHITE_BALANCE_AUTO);
List<String> focusModes = parameters.getSupportedFocusModes();
if (focusModes != null && focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO))
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
List<Camera.Size> sizes = parameters.getSupportedPictureSizes();
/*if (sizes != null && sizes.size() > 0) {
Camera.Size size = sizes.get(0);
parameters.setPictureSize(size.width, size.height);
}*/
List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes();
/*if (previewSizes != null) {
Camera.Size previewSize = previewSizes.get(previewSizes.size() - 1);
parameters.setPreviewSize(previewSize.width, previewSize.height);
}*/
Camera.Size previewSize = mCamera.getParameters().getPreviewSize();
float aspect = (float) previewSize.width / previewSize.height;
int previewSurfaceWidth = mPreview.getWidth();
int previewSurfaceHeight = mPreview.getHeight();
ViewGroup.LayoutParams lp = mPreview.getLayoutParams();
if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
mCamera.setDisplayOrientation(90);
lp.height = previewSurfaceHeight;
lp.width = (int) (previewSurfaceHeight / aspect);
} else {
mCamera.setDisplayOrientation(0);
lp.width = previewSurfaceWidth;
lp.height = (int) (previewSurfaceWidth / aspect);
}
mPreview.setLayoutParams(lp);
mCamera.setParameters(parameters);
mCamera.startPreview();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
#Override
public void onClick(View v) {
if (v == mTakePicture) {
//mCamera.takePicture(null, null, null, this);
mCamera.autoFocus(this);
}
}
#Override
public void onPictureTaken(byte[] paramArrayOfByte, Camera paramCamera) {
paramCamera.startPreview();
}
#Override
public void onAutoFocus(boolean paramBoolean, Camera paramCamera) {
if (paramBoolean) {
paramCamera.takePicture(null, null, null, this);
}
}
#Override
public void onPreviewFrame(byte[] paramArrayOfByte, Camera paramCamera) {
}
I don't know how about resulting image, because I'm not need it at the moment. But preview is distorted. For example:
http://habrastorage.org/files/fc5/cd1/6fb/fc5cd16fb80f41f6ac7a8a800e0348b6.png
http://habrastorage.org/files/968/cd4/850/968cd48505564f93b0258a07fe48a545.png
What do I wrong? How to keep preview in normal state, without stretching? Or, maybe, is it problem with miui?
How to keep preview in normal state, without stretching?
Your SurfaceView needs to be in the same aspect ratio as is the camera preview. Otherwise, the camera preview will be stretched in one direction to fit the SurfaceView.
Take Video Size or Picture Size Available on Device
check in preview constructor-
List<Camera.Size> sizes = mCamera.getParameters()
.getSupportedVideoSizes();
if (sizes != null)
for (Camera.Size size : sizes) {
int h = size.height;
int w = size.width;
System.out.println("h=" + h + " w=" + w);
}
then decide what resolution you want for you requirment then make frame layout of same resoultion
abc.xml file
<FrameLayout
android:id="#+id/camera_preview"
android:layout_width="288dp"
android:layout_height="352dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp"
>
</FrameLayout>
preview in surface created-
if(mCamera!=null)
{
Parameters params=mCamera.getParameters();
params.setPictureSize(288, 352);
mCamera.setParameters(params);
}
please make change according to your need if you need any help then ask.
Set Camera Parameter as
Camera.Parameters params = mCamera.getParameters();
params.set("orientation", "portrait");
mCamera.setParameters(params);
this will help you..

Android Camera Preview not showing properly on google glass?

I am developing a camera app and the problem is that the camera i am making shows a distorted preview.
The picture it takes is clear but the preview is messed up.
Complete camera preview code is below just in case:
import java.io.IOException;
import java.util.List;
import com.glass.cuxtomcam.constants.CuxtomIntent.CAMERA_MODE;
import android.content.Context;
import android.content.res.Configuration;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.OnZoomChangeListener;
import android.hardware.Camera.Parameters;
import android.util.Log;
import android.view.OrientationEventListener;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.Toast;
public class CameraPreview extends SurfaceView implements
SurfaceHolder.Callback, OnZoomChangeListener {
private SurfaceHolder mHolder;
private Camera mCamera;
private Context mContext;
private static String TAG = "CAMERA PREVIEW";
private int zoomOffset;
private CameraListener mCallback;
private int cameraMode;
public CameraPreview(Context context, Camera camera, int cameraMode) {
super(context);
mContext = context;
mCamera = camera;
mHolder = getHolder();
this.cameraMode = cameraMode;
mHolder.addCallback(this);
mHolder.setKeepScreenOn(true);
}
public void setCameraListener(CameraListener listener) {
mCallback = listener;
}
#Override
public synchronized void surfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
// If your preview can change or rotate, take care of those events here.
// Make sure to stop the preview before resizing or reformatting it.
if (mHolder.getSurface() == null) {
// preview surface does not exist
return;
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
if (mCamera != null) {
try {
mCamera.stopPreview();
if (mCamera.getParameters().isZoomSupported()) {
mCamera.setZoomChangeListener(this);
zoomOffset = mCamera.getParameters().getMaxZoom() / 5;
}
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
mCamera.lock();
} catch (IOException e) {
Log.e("Error starting preview", e.getMessage());
}
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (mCamera != null) {
mCamera.stopPreview();
// release the camera
mCamera.release();
// unbind the camera from this object
mCamera = null;
}
}
public synchronized void zoomIn() {
if (mCamera != null && mCamera.getParameters().isZoomSupported()
&& mCamera.getParameters().isSmoothZoomSupported()) {
int zoomvalue = mCamera.getParameters().getZoom() + zoomOffset;
if (zoomvalue <= mCamera.getParameters().getMaxZoom()) {
mCamera.startSmoothZoom(zoomvalue);
}
} else {
Toast.makeText(mContext, "Zoom In is not supported",
Toast.LENGTH_LONG).show();
}
}
public synchronized void zoomOut() {
if (mCamera != null && mCamera.getParameters().isZoomSupported()
&& mCamera.getParameters().isSmoothZoomSupported()) {
int zoomvalue = mCamera.getParameters().getZoom() - zoomOffset;
if (zoomvalue >= 0) {
mCamera.startSmoothZoom(zoomvalue);
}
} else {
Toast.makeText(mContext, "Zoom Out is not supported",
Toast.LENGTH_LONG).show();
}
}
#Override
public void onZoomChange(int zoomValue, boolean stopped, Camera camera) {
// Log.i("Camera Zoom Value", zoomValue + "");
}
}
Can anyone guide me on why is this happening?
Not sure if it is still relevant (after 2 months without an answer). But this is a solution I used when my camera was like you showed.
Camera.Parameters parameters = camera.getParameters();
parameters.setPreviewFpsRange(30000, 30000);
parameters.setPreviewSize(640,360);
camera.setParameters(parameters);
It sets the frames per second to 30fps, the problem you are experiencing is a too high framerate (most likely)

Simultaneous TextureView and SurfaceView Android Camera

I can display a preview of the camera video properly with a TextureView:
package com.example.camerasurfacetexture;
import java.io.IOException;
import android.app.Activity;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.TextureView;
import android.view.TextureView.SurfaceTextureListener;
import android.widget.FrameLayout;
public class MainActivity extends Activity implements SurfaceTextureListener
{
private Camera mCamera = null;
private TextureView mTextureView = null;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
mTextureView = new TextureView(this);
mTextureView.setSurfaceTextureListener(this);
setContentView(mTextureView);
}
#Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width,
int height)
{
Log.i("onSurfaceTextureAvailable", "onSurfaceTextureAvailable");
mCamera = Camera.open();
Camera.Size previewSize = mCamera.getParameters().getPreviewSize();
mTextureView.setLayoutParams(new FrameLayout.LayoutParams(
previewSize.width, previewSize.height, Gravity.CENTER));
try
{
mCamera.setPreviewTexture(surface);
}
catch (IOException t)
{
}
mCamera.startPreview();
}
#Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width,
int height)
{
// Ignored, the Camera does all the work for us
}
#Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface)
{
Log.i("onSurfaceTextureDestroyed", "onSurfaceTextureDestroyed");
mCamera.stopPreview();
mCamera.release();
return true;
}
#Override
public void onSurfaceTextureUpdated(SurfaceTexture surface)
{
// Update your view here!
}
}
and with a SurfaceView:
package com.example.cameratest;
import android.app.Activity;
import android.hardware.Camera;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.Toast;
public class MainActivity extends Activity
{
private SurfaceView preview = null;
private SurfaceHolder previewHolder = null;
private Camera camera = null;
private boolean inPreview = false;
private boolean cameraConfigured = false;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
preview = (SurfaceView) findViewById(R.id.cpPreview);
previewHolder = preview.getHolder();
previewHolder.addCallback(surfaceCallback);
previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
#Override
public void onResume()
{
super.onResume();
camera = Camera.open();
startPreview();
}
#Override
public void onPause()
{
if (inPreview)
{
camera.stopPreview();
}
camera.release();
camera = null;
inPreview = false;
super.onPause();
}
private Camera.Size getBestPreviewSize(int width, int height,
Camera.Parameters parameters)
{
Camera.Size result = null;
for (Camera.Size size : parameters.getSupportedPreviewSizes())
{
if (size.width <= width && size.height <= height)
{
if (result == null)
{
result = size;
}
else
{
int resultArea = result.width * result.height;
int newArea = size.width * size.height;
if (newArea > resultArea)
{
result = size;
}
}
}
}
return (result);
}
private void initPreview(int width, int height)
{
if (camera != null && previewHolder.getSurface() != null)
{
try
{
camera.setPreviewDisplay(previewHolder);
}
catch (Throwable t)
{
Log.e("PreviewDemo-surfaceCallback",
"Exception in setPreviewDisplay()", t);
Toast.makeText(MainActivity.this, t.getMessage(),
Toast.LENGTH_LONG).show();
}
if (!cameraConfigured)
{
Camera.Parameters parameters = camera.getParameters();
Camera.Size size = getBestPreviewSize(width, height, parameters);
if (size != null)
{
parameters.setPreviewSize(size.width, size.height);
camera.setParameters(parameters);
cameraConfigured = true;
}
}
}
}
private void startPreview()
{
if (cameraConfigured && camera != null)
{
camera.startPreview();
inPreview = true;
}
}
SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback()
{
public void surfaceCreated(SurfaceHolder holder)
{
// no-op -- wait until surfaceChanged()
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height)
{
initPreview(width, height);
startPreview();
}
public void surfaceDestroyed(SurfaceHolder holder)
{
// no-op
}
};
}
but if I try to do both at the same time:
package com.example.multiplecamerapreviewtest;
import java.io.IOException;
import android.app.Activity;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.TextureView;
import android.view.TextureView.SurfaceTextureListener;
import android.widget.FrameLayout;
import android.widget.Toast;
public class MainActivity extends Activity implements SurfaceTextureListener
{
private SurfaceView svPreview = null;
private SurfaceHolder previewHolder = null;
private Camera mCamera = null;
private boolean inPreview = false;
private boolean cameraConfigured = false;
private TextureView tvPreview = null;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
svPreview = (SurfaceView) findViewById(R.id.svPreview);
previewHolder = svPreview.getHolder();
previewHolder.addCallback(surfaceCallback);
previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
// mTextureView = new TextureView(this);
tvPreview = (TextureView) findViewById(R.id.tvPreview);
tvPreview.setSurfaceTextureListener(this);
// setContentView(mTextureView);
}
#Override
public void onResume()
{
super.onResume();
mCamera = Camera.open();
startPreview();
}
#Override
public void onPause()
{
if (inPreview)
{
mCamera.stopPreview();
}
mCamera.release();
mCamera = null;
inPreview = false;
super.onPause();
}
private Camera.Size getBestPreviewSize(int width, int height,
Camera.Parameters parameters)
{
Camera.Size result = null;
for (Camera.Size size : parameters.getSupportedPreviewSizes())
{
if (size.width <= width && size.height <= height)
{
if (result == null)
{
result = size;
}
else
{
int resultArea = result.width * result.height;
int newArea = size.width * size.height;
if (newArea > resultArea)
{
result = size;
}
}
}
}
return (result);
}
private void initPreview(int width, int height)
{
if (mCamera != null && previewHolder.getSurface() != null)
{
try
{
mCamera.setPreviewDisplay(previewHolder);
}
catch (Throwable t)
{
Log.e("PreviewDemo-surfaceCallback",
"Exception in setPreviewDisplay()", t);
Toast.makeText(MainActivity.this, t.getMessage(),
Toast.LENGTH_LONG).show();
}
if (!cameraConfigured)
{
Camera.Parameters parameters = mCamera.getParameters();
Camera.Size size = getBestPreviewSize(width, height, parameters);
if (size != null)
{
parameters.setPreviewSize(size.width, size.height);
mCamera.setParameters(parameters);
cameraConfigured = true;
}
}
}
}
private void startPreview()
{
if (cameraConfigured && mCamera != null)
{
mCamera.startPreview();
inPreview = true;
}
}
SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback()
{
public void surfaceCreated(SurfaceHolder holder)
{
// no-op -- wait until surfaceChanged()
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height)
{
initPreview(width, height);
startPreview();
}
public void surfaceDestroyed(SurfaceHolder holder)
{
// no-op
}
};
#Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width,
int height)
{
Log.i("onSurfaceTextureAvailable", "onSurfaceTextureAvailable");
mCamera = Camera.open();
Camera.Size previewSize = mCamera.getParameters().getPreviewSize();
tvPreview.setLayoutParams(new FrameLayout.LayoutParams(
previewSize.width, previewSize.height, Gravity.CENTER));
try
{
mCamera.setPreviewTexture(surface);
}
catch (IOException t)
{
}
mCamera.startPreview();
}
#Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width,
int height)
{
// Ignored, the Camera does all the work for us
}
#Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface)
{
Log.i("onSurfaceTextureDestroyed", "onSurfaceTextureDestroyed");
mCamera.stopPreview();
mCamera.release();
return true;
}
#Override
public void onSurfaceTextureUpdated(SurfaceTexture surface)
{
// Update your view here!
}
}
I get a "Fail to connect to camera service" exception when calling mCamera.setPreviewTexture().
According to the documentation (http://developer.android.com/reference/android/hardware/Camera.html#setPreviewDisplay%28android.view.SurfaceHolder%29), this is the expected behavior:
setPreviewDisplay()
Setting a preview surface will un-set any preview surface texture that was set via setPreviewTexture(SurfaceTexture).
(and vice-versa). Is there anything I can do to get these both displaying at the same time?
Send the Camera output to a SurfaceTexture, then render the texture wherever you like using GLES.
See e.g. the "texture from camera" activity in Grafika.
This requires some EGL management and a basic familiarity with GLES, though you can get pretty far just using the code in Grafika. This approach will get you much better performance than manipulating pixels with the NDK, because the GPU does all the work.
Camera is a shared hardware resource. I don't think you can access it (Camera.open()) more than once even within the same application i.e even within the same process with same user id. How about accessing the buffers for camera preview natively and then reading bytes from those buffers to render them on as many TextureViews or SurfaceViews or VideoViews as you wish?
Edited:
NDK Resource:
How do I get the raw Android camera buffer in C using JNI?

Android Camera Orientation

I'm trying to learn an Augmented Reality basic from this article :
http://www.devx.com/wireless/Article/42482/0/page/2
when it run, the camera took an opposite orientation.
My question is how to get a fixed and normal view with the camera. This is the CustomCameraView Class:
package com.syariati.camera;
import android.content.Context;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class CustomCameraView extends SurfaceView {
Camera camera;
SurfaceHolder surfaceHolder;
public CustomCameraView(Context context){
super(context);
surfaceHolder = this.getHolder();
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
surfaceHolder.addCallback(surfaceHolderListener);
}
SurfaceHolder.Callback surfaceHolderListener = new SurfaceHolder.Callback() {
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera.stopPreview();
camera.release();
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera = Camera.open();
try{
camera.setPreviewDisplay(surfaceHolder);
}
catch(Exception e){
e.printStackTrace();
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
Parameters params = camera.getParameters();
params.setPictureFormat(PixelFormat.JPEG);
camera.setParameters(params);
camera.startPreview();
}
};
}
Should I add another method on params ??
Sorry for my bad English. Thank you.
This is how the problem is solved.
add :
camera.setDisplayOrientation(90);
Android - Camera preview is sideways
Set orientation Degree as per your requirment because I had user 90 for
front camera and 270 degree for back camera:
Camera.Parameters params = camera.getParameters();
params.set("rotation", 90);
camera.setParameters(params);
Goto your application AndroidManifest.xml file and then follow
Application tab -> select CustomCameraView activity ->
attributes for CustomCameraView activity -> screen orientation -> select portrait.
And run it-
Njoy...

Categories

Resources