I am using the Surface View and Surface Holder for opening the USB camera. Camera opening but after some time, I am getting "Error 100, Camera server died". I search lots of tutorials but error is not resolving. If anyone knows about this error please help me.
I am using below code for opening the camera.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
start = (Button)findViewById(R.id.start);
start.setOnClickListener(new Button.OnClickListener()
{
public void onClick(View arg0) {
start_camera();
}
});
surfaceView = (SurfaceView)findViewById(R.id.surfaceView);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
rawCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
Log.d("Log", "onPictureTaken - raw");
}
};
}
private void start_camera()
{
try{
camera = Camera.open(0);
}catch(RuntimeException e){
Log.e(tag, "init_camera: 2=" + e);
return;
}
Camera.Parameters param;
param = camera.getParameters();
//modify parameter
param.setPreviewFrameRate(20);
param.setPreviewSize(640, 480);
camera.setParameters(param);
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
} catch (Exception e) {
return;
}
}
mCamera = Camera.open(mCameraId);
mCamera.setErrorCallback(new Camera.ErrorCallback() {
#Override
public void onError(int error, Camera camera) {
KLog.e("相机服务出错,错误代码:" + error);
switch (error) {
case Camera.CAMERA_ERROR_SERVER_DIED:
case Camera.CAMERA_ERROR_UNKNOWN:
try {
mCamera.setPreviewCallback(null);
mCamera.setPreviewDisplay(null);
mCamera.stopPreview();
mCamera.release();
mCamera = null;
start();
} catch (IOException e) {
e.printStackTrace();
}
break;
}
}
});
Related
My application freezes when I call switchCam method in my code.something must be wrong there, but i cant understand what is the problem.Can someone help me out there what is the actual problem in my code.
public class MainActivity extends AppCompatActivity {
private Camera mCamera = null;
SurfaceHolder surfaceHolder=null;
private CameraView mCameraView = null;
int currentCameraId = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);//int flag, int mask
openCam();
//setCameraDisplayOrientation(MainActivity.this, currentCameraId, mCamera);
}
public void openCam() {
try {
mCamera = Camera.open();//you can use open(int) to use different cameras
} catch (Exception e) {
Log.d("ERROR", "Failed to get camera: " + e.getMessage());
mCamera = Camera.open();//you can use open(int) to use different cameras
}
if (mCamera != null) {
mCameraView = new CameraView(this, mCamera);//create a SurfaceView to show camera data
FrameLayout camera_view = (FrameLayout) findViewById(R.id.camera_preview);
camera_view.addView(mCameraView);//add the SurfaceView to the layout
}
}
public void switchCam(View view){
int camNum = 0;
camNum = Camera.getNumberOfCameras();
int camBackId = Camera.CameraInfo.CAMERA_FACING_BACK;
int camFrontId = Camera.CameraInfo.CAMERA_FACING_FRONT;
Toast.makeText(getApplicationContext(),"Hi Cam"+camNum,Toast.LENGTH_SHORT).show();
Camera.CameraInfo currentCamInfo = new Camera.CameraInfo();
//if camera is running
if (mCamera != null){
//and there is more than one camera
mCamera.stopPreview();
mCamera.release();
//swap the id of the camera to be used
if(currentCameraId == Camera.CameraInfo.CAMERA_FACING_BACK){
currentCameraId = Camera.CameraInfo.CAMERA_FACING_FRONT;
}
else {
currentCameraId = Camera.CameraInfo.CAMERA_FACING_BACK;
}
mCamera = Camera.open(currentCameraId);
//setCameraDisplayOrientation(MainActivity.this, currentCameraId, mCamera);
try {
mCamera.setPreviewDisplay(surfaceHolder);
} catch (IOException e) {
e.printStackTrace();
}
mCamera.startPreview();
}
}
CameraView class is here
public class CameraView extends SurfaceView implements SurfaceHolder.Callback{
private SurfaceHolder mHolder;
private Camera mCamera;
int currentCameraId=0;
public CameraView(Context context, Camera camera) {
super(context);
mCamera = camera;
//get the holder and set this class as the callback, so we can get camera data here
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_NORMAL);
}
#Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
try {
mCamera.setPreviewDisplay(surfaceHolder);
mCamera.startPreview();
}catch (IOException e) {
Log.d("ERROR", "Camera error on surfaceCreated " + e.getMessage());
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
mCamera.startPreview();
if(mHolder.getSurface() == null)//check if the surface is ready to receive camera data
return;
try{
mCamera.stopPreview();
} catch (Exception e){
//this will happen when you are trying the camera if it's not running
}
try{
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (IOException e) {
Log.d("ERROR", "Camera error on surfaceChanged " + e.getMessage());
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
mCamera.stopPreview();
mCamera.release();
}
}
It will be my very pleasure if you share any link with me that can help me out for taking picture too .Thanks in advance :)
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) {
}
}
}
Here is my code, this thing work fine. Right now the pictures were saved in the same folder as the mobile camera but I want to change the save location to another folder. Any suggestion?
SurfaceView cameraView;
SurfaceHolder surfaceHolder;
Camera camera;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
setContentView(R.layout.main);
cameraView = (SurfaceView)this.findViewById(R.id.CameraView);
surfaceHolder = cameraView.getHolder();
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
surfaceHolder.addCallback(this);
cameraView.setFocusable(true);
cameraView.setFocusableInTouchMode(true);
cameraView.setClickable(true);
cameraView.setOnClickListener(this);
}
public void onClick(View v){
camera.takePicture(null, null, this);
}
#Override
public void onPictureTaken(byte[] data, Camera camera) {
Uri imageFileUri = getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, new ContentValues());
try{
OutputStream imageFileOS = getContentResolver().openOutputStream(imageFileUri);
imageFileOS.write(data);
imageFileOS.flush();
imageFileOS.close();
} catch(FileNotFoundException e){
Toast t = Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT);
t.show();
} catch (IOException e) {
Toast t = Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT);
t.show();
}
camera.startPreview();
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {
camera.startPreview();
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
camera = Camera.open();
try{
camera.setPreviewDisplay(holder);
Camera.Parameters parameters = camera.getParameters();
parameters.setPictureSize(640, 480);
camera.setParameters(parameters);
} catch(IOException e){
camera.release();
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
camera.stopPreview();
camera.release();
}
Right, you need to change Uri imageFileUri (or OutputStream imageFileOS).
Where do you want to store image file?
After taken a few photo, my camera just went black. Any suggestion of this?
SurfaceView cameraView;
SurfaceHolder surfaceHolder;
Camera camera;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.camera);
cameraView = (SurfaceView)this.findViewById(R.id.CameraView);
surfaceHolder = cameraView.getHolder();
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
surfaceHolder.addCallback(this);
cameraView.setFocusable(true);
cameraView.setFocusableInTouchMode(true);
cameraView.setClickable(true);
cameraView.setOnClickListener(this);
}
public void onClick(View v){
camera.takePicture(null, null, this);
}
#Override
public void onPictureTaken(byte[] data, Camera camera) {
try{
OutputStream imageFileOS = new FileOutputStream(String.format("/sdcard/Galmix/%d.jpg",System.currentTimeMillis()));
imageFileOS.write(data);
imageFileOS.flush();
imageFileOS.close();
} catch(FileNotFoundException e){
Toast t = Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT);
t.show();
} catch (IOException e) {
Toast t = Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT);
t.show();
}
camera.startPreview();
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {
camera.startPreview();
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
camera = Camera.open();
try{
camera.setPreviewDisplay(holder);
Camera.Parameters parameters = camera.getParameters();
parameters.setPictureSize(640, 480);
if(this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE){
parameters.set("orientation", "portrait");
camera.setDisplayOrientation(90);
}
camera.setParameters(parameters);
} catch(IOException e){
camera.release();
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
camera.stopPreview();
camera.release();
}
Check to make sure the images you're saving are being saved properly. I had a similar issue where due to a bug in my saving code I was getting a NullPointerException and killing my camera activity. For more specifics you'll have to post code though.
Are there any way to constantly set the resolution of the photo (like 256x256) that were taken by my own camera application. Here is bits of code, Thanks.
SurfaceView cameraView;
SurfaceHolder surfaceHolder;
Camera camera;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
File mFile=new File("/sdcard/Galmix");
mFile.mkdir();
cameraView = (SurfaceView)this.findViewById(R.id.CameraView);
surfaceHolder = cameraView.getHolder();
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
surfaceHolder.addCallback(this);
cameraView.setFocusable(true);
cameraView.setFocusableInTouchMode(true);
cameraView.setClickable(true);
cameraView.setOnClickListener(this);
}
public void onClick(View v){
camera.takePicture(null, null, this);
}
#Override
public void onPictureTaken(byte[] data, Camera camera) {
try{
OutputStream imageFileOS = new FileOutputStream(String.format("/sdcard/Galmix/%d.jpg",System.currentTimeMillis()));
imageFileOS.write(data);
imageFileOS.flush();
imageFileOS.close();
} catch(FileNotFoundException e){
Toast t = Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT);
t.show();
} catch (IOException e) {
Toast t = Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT);
t.show();
}
camera.startPreview();
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {
camera.startPreview();
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
camera = Camera.open();
try{
camera.setPreviewDisplay(holder);
Camera.Parameters parameters = camera.getParameters();
if(this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE){
parameters.set("orientation", "portrait");
camera.setDisplayOrientation(90);
}
List<String> colorEffects = parameters.getSupportedColorEffects();
Iterator<String> cei = colorEffects.iterator();
while(cei.hasNext()){
String currentEffect = cei.next();
if(currentEffect.equals(Camera.Parameters.EFFECT_SOLARIZE)){
parameters.setColorEffect(Camera.Parameters.EFFECT_SOLARIZE); break;
}
}
camera.setParameters(parameters);
} catch(IOException e){
camera.release();
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
camera.stopPreview();
camera.release();
}
See Camera Parameters for information.
to resolve your problem, you have to check your camera supported sizes by using this code:
Camera camera = Camera.open();
Parameters params = camera.getParameters();
List<Camera.Size> sizes = params.getSupportedPictureSizes();
Once you will se the supported Sizes, you can define them with the method :
setPictureSize(int width, int height);