public static Camera getCameraInstance() {
Camera c = null;
try {
c = Camera.open(); // attempt to get a Camera instance
if (c != null) {
Camera.Parameters params = c.getParameters();
params.setRotation(90);
c.setParameters(params);
}
} catch (Exception e) {
Log.d("DEBUG", "Camera did not open");
// Camera is not available (in use or does not exist)
}
return c; // returns null if camera is unavailable
}
onCreate:
// Create an instance of Camera
mCamera = getCameraInstance();
mPreview = new CameraPreview(this, mCamera);
preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mPreview);
CameraPreview:
public CameraPreview(Context context, Camera camera) {
super(context);
mCamera = camera;
// 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);
}
I using MediaRecorder record video.
Result:
if i test on device android 4.0, result is ok. but in android 2.3 it is interference
Why video of camera interference in android 2.3?(Note: Capture Image , it is ok.)
This is just one potential problem. From the docs:
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
You are not implementing the Camera API correctly. Please look at the Android Guide on how to create a camera app.
Related
I am trying some preview frame processing on top of camera2basic example from android. createCaptureSession call is failing with no so useful error reporting. Can someone help me understand whats going wrong?
Following works and still image capturing works as expected
mCameraDevice.createCaptureSession(Arrays.asList(surface, mImageReader.getSurface()),
Following also works with my custom frame processing happening
mPreviewRequestBuilder.addTarget(mFrameReader.getSurface());
mCameraDevice.createCaptureSession(Arrays.asList(surface, mFrameReader.getSurface()), ....
However, its fails without proper error reporting when try both the things together
mPreviewRequestBuilder.addTarget(mFrameReader.getSurface());
mCameraDevice.createCaptureSession(Arrays.asList(surface, mImageReader.getSurface(), mFrameReader.getSurface()),
I see following error in logs and my app crashes
06-20 06:37:56.430 28839-29176/com.example.android.camera2basic
E/CameraCaptureSession: Session 0: Failed to create capture session;
configuration failed
For reference heres the whole method
/**
* Creates a new {#link CameraCaptureSession} for camera preview.
*/
private void createCameraPreviewSession() {
try {
SurfaceTexture texture = mTextureView.getSurfaceTexture();
assert texture != null;
// We configure the size of default buffer to be the size of camera preview we want.
texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
// This is the output Surface we need to start preview.
Surface surface = new Surface(texture);
// We set up a CaptureRequest.Builder with the output Surface.
mPreviewRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
mPreviewRequestBuilder.addTarget(surface);
mPreviewRequestBuilder.addTarget(mFrameReader.getSurface());
// Here, we create a CameraCaptureSession for camera preview.
mCameraDevice.createCaptureSession(Arrays.asList(surface, mImageReader.getSurface(), mFrameReader.getSurface()),
new CameraCaptureSession.StateCallback() {
#Override
public void onConfigured(#NonNull CameraCaptureSession cameraCaptureSession) {
// The camera is already closed
if (null == mCameraDevice) {
return;
}
// When the session is ready, we start displaying the preview.
mCaptureSession = cameraCaptureSession;
try {
// Auto focus should be continuous for camera preview.
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
// Flash is automatically enabled when necessary.
setAutoFlash(mPreviewRequestBuilder);
// Finally, we start displaying the camera preview.
mPreviewRequest = mPreviewRequestBuilder.build();
mCaptureSession.setRepeatingRequest(mPreviewRequest,
mCaptureCallback, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
#Override
public void onConfigureFailed(
#NonNull CameraCaptureSession cameraCaptureSession) {
showToast("Failed");
}
}, null
);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
this is my code:
#TargetApi(9)
public void surfaceCreated(SurfaceHolder holder){
Log.e(TAG, "surfaceCreated");
mCamera = Camera.open(cameraID);
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
Log.e(TAG, "surfaceChanged");
// XXX stopPreview() will crash if preview is not running
if (mPreviewRunning){
mCamera.stopPreview();
}
Camera.Parameters p = mCamera.getParameters();
p.setPreviewSize(300, 300);
mCamera.setParameters(p);
try{
mCamera.setPreviewDisplay(holder);
}catch (Exception e){
// TODO Auto-generated catch block
e.printStackTrace();
}
mCamera.startPreview();
mPreviewRunning = true;
mCamera.takePicture(null, mPictureCallback, mPictureCallback);
}
public void surfaceDestroyed(SurfaceHolder holder) {
Log.e(TAG, "surfaceDestroyed");
//mCamera.stopPreview();
//mPreviewRunning = false;
//mCamera.release();
}
private SurfaceView mSurfaceView;
private SurfaceHolder mSurfaceHolder;
it fails in: mCamera.setParameters(p);
someone can help?
Your device does not support preview 300x300 pixels, that's why Cmaera.setParameters() fails. You can only call CameraParameters.setPreviewSize() for one of the sizes listed in CameraParameters.getSupportedPreviewSizes().
Few notes:
If your device has more than one camera, each has its own list of supported sizes; some sizes may be supported by both cameras, others are not.
In some rare cases, some devices may throw RuntimeException even if you choose one of sizes that is returned by getSupportedPreviewSizes(). These are platform bugs, you can keep a blacklist of such cases per model/platform. But in any case, don't forget to wrap setParameters() in try … catch and try to resolve the issue.
In some rare cases, some devices may not throw RuntimeException but simply ignore the preview size request (or some other parameter). Be prepared.
android.hardware.Camera class is deprecated. For devices with Android Lollipop (21) and higher, use the android.hardware.camera2 API.
I'm developing an image recognition app and would like the camera to focus automatically all the time. The folks at ZXing have solved this problem by calling autofocus() every few seconds, but on some cameras this doesn't focus smoothly, but zips to one end and refocuses. On my Alcatel 995, gingerbread 2.3.3 API level 10 phone, it actually makes an alarming click every time this happens.
This phone doesn't support FOCUS_MODE_CONTINUOUS_PICTURE. I tried using FOCUS_MODE_CONTINUOUS_VIDEO, which is supported, and it didn't work. I wrote a test app that captured every preview frame of the camera normally with a callback, but it didn't focus. I added a video recorder feature to the app, and when video is being recorded, the camera does autofocus all the time. But video recording takes away the ability to get a callback on each frame, I think. It's been discussed at
https://stackoverflow.com/questions/9477042/extract-video-frames-while-recording-the-video-on-android?rq=1
and
How to show real time filtered camera preview while recording videos?
Here is some of that test code:
public void surfaceCreated(SurfaceHolder holder) {
mCamera = Camera.open();
try {
Camera.Parameters parameters = mCamera.getParameters();
mCamera.setDisplayOrientation(90); // just get it right for testing
mCamera.setParameters(parameters);
mCamera.setPreviewDisplay(holder);
mCamera.setPreviewCallback(new PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera arg1) {
Log.d(TAG, String.format("Frame %d", mFrameNumber++)); // see the frames in the logcat
}
});
} catch (IOException exception) {
mCamera.release();
mCamera = null;
Log.d(TAG, "exception setting parameters");
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// Now that the size is known, set up the camera parameters and begin
// the preview.
Camera.Parameters parameters = mCamera.getParameters();
List<Size> previewSizes = parameters.getSupportedPreviewSizes();
Size previewSize = getOptimalPreviewSize(previewSizes, w, h);
parameters.setPreviewSize(previewSize.width, previewSize.height);
parameters.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
mCamera.setParameters(parameters);
mCamera.startPreview();
if (mRecordingVideo)
startVideo(mCamera, holder);
}
// derived from http://developer.android.com/guide/topics/media/camera.html#capture-video
private void startVideo(Camera camera, SurfaceHolder holder) {
camera.stopPreview(); // not specified in documentation but seems to be needed
camera.unlock();
mMediaRecorder = new MediaRecorder();
mMediaRecorder.setCamera(camera);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); // No audio is recorded
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
mMediaRecorder.setOutputFile("/dev/null");
try {
mMediaRecorder.setPreviewDisplay(holder.getSurface());
mMediaRecorder.prepare();
} catch (IOException e) {
camera.release();
Log.d(TAG, "startVideo: Failed.");
e.printStackTrace();
}
mMediaRecorder.start();
}
If I set mRecordingVideo in the above code to start the video recorder, I gain autofocus but lose the per-preview-frame callbacks.
The Camera.Parameters class definition says that FOCUS_MODE_CONTINUOUS_VIDEO is "intended for video recording" but doesn't make plain that it doesn't work otherwise.
Is there anything else I can do to persuade continuous autofocus to work in a gingerbread phone without recording video? Have I missed something out?
Is this phone-specific? Do other phones continuous autofocus in this mode without recording video? I posted the source of a complete test app to Github if anyone would like to try it on their phone.
Someone kindly helped me out by testing this on another phone on another continent. Thanks very much, Colin!
It appears that the code above is correct and should cause the camera to focus properly.
This behaviour is phone-specific. The Alcatel 995 running 2.3.6 definitely does not focus in this mode without the video recorder running. A Samsung Galaxy Nexus (not sure which OS) running the same code does focus without the video recorder running.
try "setRecordingHint(true)" to the camera parameters
I am working on a new android application.In my app i have to add show effects on image preview [like sepia,pinch, mirror, etc] and capture and save image in that particular effect.eg: I f user select pinch effect then he can capture and store the image with pinch effect.
I had read some faq's. But they are telling about some ndk's.But i don't have any idea about ndk's. Please help me friends.
You can set all these kind of effects with camera instance itself. Walk though the below code ...
Camera camera = null;
camera = Camera.open();
if (camera != null) {
try {
Camera.Parameters parameters = camera.getParameters();
// Set all kind of stuffs here..
parameters.setSceneMode(Camera.Parameters.FLASH_MODE_AUTO);
parameters.setColorEffect(Camera.Parameters.EFFECT_SEPIA);
camera.setParameters(parameters);
camera.setPreviewDisplay(surface_holder);
camera.startPreview();
} catch (IOException exception) {
camera.release();
camera = null;
}
}
I'm developing on android, i want to do somethings with camera (process pixels's values), but just in background, is it possible to do it without surface view? just use a buffer to read pixels's values and do processing.
thanks for every one can help me
As of API-Level 11 the SurfaceTexture was added. With it a SurfaceView is no longer needed. I tested the following code with my Samsung Galaxy S3 Neo.
mCamera = Camera.open();
try {
mCamera.setPreviewTexture(new SurfaceTexture(10));
} catch (IOException e1) {
Log.e(Version.APP_ID, e1.getMessage());
}
Parameters params = mCamera.getParameters();
params.setPreviewSize(640, 480);
params.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
params.setPictureFormat(ImageFormat.JPEG);
mCamera.setParameters(params);
mCamera.startPreview();
mCamera.takePicture(null, null, null, new PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
Log.i(Version.APP_ID, "picture-taken");
}
});
I've been looking for an answer to this for a while. I found it there, copied here for convenience.
http://handycodeworks.com/?p=19
Basically, let's just create a dummy SurfaceView (it works even inside a Service), and use it for Camera functions.
SurfaceView view = new SurfaceView(this);
c.setPreviewDisplay(view.getHolder());
c.startPreview();
c.takePicture(shutterCallback, rawPictureCallback, jpegPictureCallback);