camera preview showing black screen - android

Hi I am developing an android app trying out custom camera and video functionality. The problem is when I try to return to the Cameraview onClick of a button in Videoview , the preview is not displayed. It shows only the black screen.
onClick in Videoview is as below
try
{
Thread.sleep(1000);
recorder.stop();
recorder.reset();
recorder.release();
}
catch (Exception e)
{
e.printStackTrace();
}
camera.release();
startActivity(new Intent(Video.this,Camera.class));
finish();
The camera is null onSurfaceChanged of the Cameraview on returning from Videoview.
#Override
public void surfaceChanged(SurfaceHolder sHolder, int format, int width, int height)
{
Log.e("surfaceChanged","camera");
if(camera != null)
{
initPreview(width, height);
camera.startPreview();
}
else if(camera == null)
{
try
{
Camera camera = Camera.open(currentCameraId);
if (holder.getSurface() == null)
{
return;
}
try
{
//camera.stopPreview();
//camera.reconnect();
//camera.lock();
//camera.unlock();
camera.setPreviewCallback(this);
camera.setPreviewDisplay(holder);
}
catch (Exception e)
{
}
initPreview(width, height);
camera.startPreview();
}
catch (Exception e)
{
releaseCamera();
}
Not sure where I am going wrong. I am not able to open camera or reconnect it. Please Help.
Thanks!

Try this:
1) Set callBack for SurfaceView.
public CameraView(Context ctx, AttributeSet attrSet) {
super(ctx, attrSet);
getHolder().addCallback(cameraPreviewCallback);
getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
Camera.PreviewCallback cameraPreviewCallback = new Camera.PreviewCallback() {
#Override
public void onPreviewFrame(byte[] data, Camera camera) {
}
};
2) Start camera
camera = Camera.open();
camera.setPreviewCallback(cameraPreviewCallback);
camera.setPreviewDisplay(getHolder());
camera.startPreview();

Related

Android camera image preview is not correct

I am trying to write a class that shows the preview of the camera surface in android. I have tried the following code. But the preview is not showing up. I tried changing the parameters but no luck. I have gone through the logcat. Nothing is shown, no error or warning. Only a black screen is shown. The app doesnot crash.
public class Preview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder holder;
private Camera camera;
public Preview(Context context, Camera camera) {
super(context);
this.camera = camera;
holder = getHolder();
holder.addCallback(this);
holder.setFixedSize(50, 50);
}
public void surfaceCreated(SurfaceHolder holder) {
try {
camera.setPreviewDisplay(holder);
camera.startPreview();
} catch (IOException e) {
Log.d("error", "Can't set camera preview: " + e.getMessage());
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
if (this.holder.getSurface() == null) {
return;
}
try {
camera.stopPreview();
} catch (Exception e) {
}
try {
camera.setPreviewDisplay(this.holder);
camera.startPreview();
} catch (Exception e) {
Log.d("DG_DEBUG", "Error starting camera preview: " + e.getMessage());
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
}
}
The problem seems here that you have not included the type of the holder. You need to set the type to SURFACE_TYPE_PUSH_BUFFERS. Use below line after adding callback
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
So your constructor should be like below
public Preview(Context context, Camera camera) {
super(context);
this.camera = camera;
holder = getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
holder.setFixedSize(50, 50);
}
I have tried the code. It works perfectly now.

Preview camera frame not capturing Android

I have the code setup (obviously not correctly but it seems ok)
My test code for capturing frame is like this:
frameCallback = new Camera.PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera camera) {
System.out.println("preview frame captured");
But this onPreviewFrame is never ran, as the print statement tests.
The weird thing is, the preview is showing up perfectly on my surface. i.e- I can see it on my screen and there is no errors. Why isn't onPreviewFrame being called then?
Here is all my code for reference:
public class HuntActivity extends AppCompatActivity implements SurfaceHolder.Callback{
Camera camera;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
Camera.PreviewCallback frameCallback;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_hunt);
surfaceView = (SurfaceView) findViewById(R.id.surfaceView);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
frameCallback = new Camera.PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera camera) {
System.out.println("preview frame captured");
}
};
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
try {camera = Camera.open();
} catch (RuntimeException e) {
System.err.println(e);
return;
}
camera.setPreviewCallback(frameCallback);
Camera.Parameters param;
param = camera.getParameters();
param.setPreviewSize(800, 480);
camera.setDisplayOrientation(90);
camera.setParameters(param);
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
} catch (Exception e) {
System.err.println(e);
return;
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
refreshCamera();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
camera.stopPreview();
camera.release();
camera = null;
}
public void refreshCamera() {
if (surfaceHolder.getSurface() == null) {return;}
try {camera.stopPreview();
} catch (Exception e){}
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
} catch (Exception e) {}
}
refreshCamera();
Do not call that function there. It will stop the preview functionality before you can use it.
Move following code to onSurfaceChanged() and use the width and heigth parameters
Camera.Parameters param;
param = camera.getParameters();
//param.setPreviewSize(800, 480);
param.setPreviewSize(width, height);
... and the rest of those lines...
Never hardcode resolutions like 800x480
try to unlock
camera.unlock();
camera.reconnect();
frameCallback.setPreviewCallback(mCallback);

Capturing Photo from SurfaceView

I'm trying to capture an image from a SurfaceView custom camera. I have set up the initial code but I don't know how to call the 'take photo' method so that I can see the preview on the surface.
Currently this code displays the preview in realtime. I need to take the picture and access the byte[] array
Please help me complete the code:
private SurfaceView mSurfaceView;
private SurfaceHolder mSurfaceHolder;
private Camera mCamera;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
captureImage = (ImageButton) findViewById(R.id.captureImage);
mSurfaceView = (SurfaceView) findViewById(R.id.surfaceView);
captureImage.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
//this button press should take the picture
}
});
mSurfaceView.getHolder().addCallback(this);
mSurfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mCamera = Camera.open();
}
#Override
public void onPause() {
super.onPause();
mCamera.stopPreview();
}
#Override
public void onDestroy() {
super.onDestroy();
mCamera.release();
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
try {
mCamera.setPreviewDisplay(mSurfaceView.getHolder());
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Camera.Parameters params = mCamera.getParameters();
List<Camera.Size> sizes = params.getSupportedPreviewSizes();
Camera.Size selected = sizes.get(0);
params.setPreviewSize(selected.width,selected.height);
mCamera.setParameters(params);
mCamera.setDisplayOrientation(90);
mCamera.startPreview();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
I need to get the bytes [] data so that I can convert the image to a base64 string. How do I call the necessary methods to take the picture using the code above?
Check "jpegCallback" in my example:
public class CameraActivity extends ActionBarActivity implements SurfaceHolder.Callback {
Camera camera;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
PictureCallback jpegCallback;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
surfaceView = (SurfaceView) findViewById(R.id.surfaceView);
surfaceHolder = surfaceView.getHolder();
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
surfaceHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
jpegCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
FileOutputStream outStream = null;
try {
outStream = new FileOutputStream(String.format("/sdcard/%d.jpg", System.currentTimeMillis()));
outStream.write(data);
outStream.close();
Log.d("Log", "onPictureTaken - wrote bytes: " + data.length);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
Toast.makeText(getApplicationContext(), "Picture Saved", 2000).show();
refreshCamera();
}
};
}
public void captureImage(View v) throws IOException {
//take the picture
camera.takePicture(null, null, jpegCallback);
}
#Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
try {
// open the camera
camera = Camera.open();
} catch (RuntimeException e) {
// check for exceptions
System.err.println(e);
return;
}
Camera.Parameters param;
param = camera.getParameters();
// modify parameter
List<Camera.Size> sizes = param.getSupportedPreviewSizes();
Camera.Size selected = sizes.get(0);
param.setPreviewSize(selected.width,selected.height);
camera.setParameters(param);
try {
// The Surface has been created, now tell the camera where to draw
// the preview.
camera.setDisplayOrientation(90);
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
} catch (Exception e) {
// check for exceptions
System.err.println(e);
return;
}
}
#Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
// Now that the size is known, set up the camera parameters and begin
// the preview.
refreshCamera();
}
#Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
// stop preview and release camera
camera.stopPreview();
camera.release();
camera = null;
}
public void refreshCamera() {
if (surfaceHolder.getSurface() == null) {
// preview surface does not exist
return;
}
// stop preview before making changes
try {
camera.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
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
} catch (Exception e) {
}
}
}

Take picture in android

Is it possible to take a picture with out opening camera ? I tried with intents but its opening camera, but i don't want to open camera.I tried following
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(takePictureIntent, 1);
and after that receiving the activity.But how to do with out opening the camera?
Yes it is possible for that use SurfaceHolder.Callback Interface .
And
#TargetApi(9)
public void surfaceCreated(SurfaceHolder holder){
Log.e(TAG, "surfaceCreated");
mCamera = Camera.open(CaptureCameraImage.cameraID);
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
Log.e(TAG, "surfaceChanged");
if (mPreviewRunning){
mCamera.stopPreview();
}
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();
}
For that use dummy surfaceview so you can take picture from background.
like
SurfaceView dummy=new SurfaceView(context);
dummy.addCallback(this);
And do some reasearch work on this dummy Surfaceview.

android startVideo stretched and in landscape mode

I have some problem in my code. I must start camera and capture it , so here is my code, and my problem is that camera starting with some strange view, like landscape mode and stretched.
mVideoCaptureView = (SurfaceView) findViewById(R.id.cameraView);
SurfaceHolder videoCaptureViewHolder = mVideoCaptureView.getHolder();
videoCaptureViewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
videoCaptureViewHolder.addCallback(new Callback() {
public void surfaceDestroyed(SurfaceHolder holder) {
}
public void surfaceCreated(SurfaceHolder holder) {
startVideo();
}
public void surfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
}
});
and the startVideo() function
private void startVideo() {
if(mCamera != null) return;
SurfaceHolder videoCaptureViewHolder = null;
try {
mCamera = Camera.open();
} catch (RuntimeException e) {
Log.e("CameraTest", "Camera Open filed");
return;
}
mCamera.setErrorCallback(new ErrorCallback() {
public void onError(int error, Camera camera) {
}
});
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPreviewFrameRate(30);
mCamera.setParameters(parameters);
if (null != mVideoCaptureView)
videoCaptureViewHolder = mVideoCaptureView.getHolder();
try {
mCamera.setPreviewDisplay(videoCaptureViewHolder);
} catch (Throwable t) {
}
try {
mCamera.startPreview();
} catch (Throwable e) {
mCamera.release();
mCamera = null;
return;
}
}
Also I must add my own buttons , ImageButtons in camera view
Thanks
Regards
sorry for English
There was some function for Camera `camera.setDisplayOrientation(90); I got it from here

Categories

Resources