I have tried all the existing methods out there.. but everytime the application force closes. Here is the code. Please help me debugging it.
MainActivity.java
package com.example.camera1;
import android.os.Bundle;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.Toast;
public class MainActivity extends Activity {
private Camera cameraObject;
private ShowCamera showCamera;
private ImageView pic;
public static Camera isCameraAvailiable(){
Camera object = null;
try { object = Camera.open();
} catch (Exception e){
} return object;
}
private PictureCallback capturedIt = new PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
Bitmap bitmap = BitmapFactory.decodeByteArray(data , 0, data .length);
if(bitmap==null){
Toast.makeText(getApplicationContext(), "not taken", Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(getApplicationContext(), "taken", Toast.LENGTH_SHORT).show();
}
cameraObject.release();
}
};
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pic = (ImageView)findViewById(R.id.imageView1);
cameraObject = isCameraAvailiable();
showCamera = new ShowCamera(this, cameraObject);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(showCamera);
}
public void snapIt(View view){
cameraObject.takePicture(null, null, capturedIt);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
ShowCamera.java
package com.example.camera1;
import java.io.IOException;
import android.content.Context;
import android.hardware.Camera;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class ShowCamera extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder holdMe;
private Camera theCamera;
public ShowCamera(Context context,Camera camera) {
super(context);
theCamera = camera;
holdMe = getHolder();
holdMe.addCallback(this);
// TODO Auto-generated constructor stub
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
try {
theCamera.setPreviewDisplay(holder);
theCamera.startPreview();
} catch (IOException e)
{
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<FrameLayout
android:id="#+id/camera_preview"
android:layout_width="fill_parent"
android:layout_height="199dp" >
</FrameLayout>
<Button
android:id="#+id/button_capture"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick = "snapIt"
android:text="#string/Capture"/>
<ImageView
android:id="#+id/imageView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="fitXY"
android:src="#drawable/ic_launcher"/>
</LinearLayout>
I am making this for android gingerbread and above versions. where my target sdk is Android Kitkat.
While testing the app on gingerbread it opens the application but simply shows a white screen that is it doesnt load the layout and force closes.. please help..!!
To open the camera,use the following code appropriately:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
Camera.CameraInfo info=new Camera.CameraInfo();
for (int i=0; i < Camera.getNumberOfCameras(); i++) {
Camera.getCameraInfo(i, info);
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
camera=Camera.open(i);
}
}
}
if (camera == null) {
camera=Camera.open();
}
Add the SurfaceView to a FrameLayout in order to display it.
Instead of returning the Camera,you could instead use the global Camera instance variable.The camera is released in onPause like this:
mCamera.release();
mCamera=null;
//remove SurfaceView from the FrameLayout you added it to
You can retain the Camera.Parameters object and use it to set the parameters to the value by placing a check in your surfaceChanged.
You could also consider starting your Camera in a seperate Thread in onCreate as it has been done here:
//This code is from AOSP ICS:
Thread mCameraOpenThread = new Thread(new Runnable() {
public void run() {
try {
mCameraDevice = Util.openCamera(Camera.this, mCameraId);
} catch (CameraHardwareException e) {
mOpenCameraFail = true;
} catch (CameraDisabledException e) {
mCameraDisabled = true;
}
}
});
This is the onCreate method:
super.onCreate(icicle);
mCameraOpenThread.start();
SurfaceView preview = (SurfaceView) findViewById(R.id.camera_preview);
SurfaceHolder holder = preview.getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
// Make sure camera device is opened.
try {
mCameraOpenThread.join();
mCameraOpenThread = null;
}
catch(InterruptedException e)
{
//ignore
}
The link to the code is here http://android.googlesource.com/platform/packages/apps/Camera/+/ics-factoryrom-2-release/src/com/android/camera/Camera.java
Related
I'm new to android and I'm trying to make an app that accesses the camera with zoom and an overlay. To implement zoom I used this:
add Zoom controls of Camera in Camera
I've tried to initialize "params" using this:
Zoom In & Out Custom Camera - Null Pointer Exception
After initialising params in the constructor I still get the error "params cannot be resolved to a variable"
Have I missed something?
Any help would be greatly appreciated.
MainActivity.java
package com.reidbailey.droidscope;
import java.io.IOException;
import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.ZoomControls;
public class MainActivity extends Activity implements SurfaceHolder.Callback{
Camera camera;
int currentZoomLevel = 0, maxZoomLevel = 0;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
boolean cameraview = false;
LayoutInflater inflater = null;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
getWindow().setFormat(PixelFormat.UNKNOWN);
surfaceView = (SurfaceView)findViewById(R.id.cameraview);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
inflater = LayoutInflater.from(getBaseContext());
View view = inflater.inflate(R.layout.overlay, null);
LayoutParams layoutParamsControl= new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
this.addContentView(view, layoutParamsControl);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
if(cameraview){
camera.stopPreview();
cameraview = false;
}
if (camera != null){
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
cameraview = true;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
ZoomControls zoomControls = (ZoomControls) findViewById(R.id.CAMERA_ZOOM_CONTROLS);
params = camera.getParameters();
if(params.isZoomSupported()){
maxZoomLevel = params.getMaxZoom();
zoomControls.setIsZoomInEnabled(true);
zoomControls.setIsZoomOutEnabled(true);
zoomControls.setOnZoomInClickListener(new OnClickListener(){
public void onClick(View v){
if(currentZoomLevel < maxZoomLevel){
currentZoomLevel++;
camera.startSmoothZoom(currentZoomLevel);
}
}
});
zoomControls.setOnZoomOutClickListener(new OnClickListener(){
public void onClick(View v){
if(currentZoomLevel > 0){
currentZoomLevel--;
camera.startSmoothZoom(currentZoomLevel);
}
}
});
}
else
zoomControls.setVisibility(View.GONE);
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera = Camera.open();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera.stopPreview();
camera.release();
camera = null;
cameraview = false;
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<SurfaceView
android:id="#+id/cameraview"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<ZoomControls
android:id="#+id/CAMERA_ZOOM_CONTROLS"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
It's because params is nowhere defined in your code, hence the compiler is complaining. You can declare your variable in place where you're using it, so just add Camera.Parameters in front of your variable name:
Camera.Parameters params = camera.getParameters();
or - if you want to have it accessible in the whole MainActivity, place it below Camera declaration in MainActivity:
Camera camera;
//add params
Camera.Parameters params;
While accepted answer is correct.
As, me, if you too, where here for "cannot resolve Camera.Parameters"
You need to import proper library.
import android.hardware.Camera;
in copy paste i had imported incorrectly
import android.graphics.Camera;
My Application gives error "Unfortunately PhotoComment has stopped" when I am pressing back or home button. But when I am reopening app from task manager it works.
this is my mainactivity.java
package com.cameratag;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.Date;
import java.text.SimpleDateFormat;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.hardware.Camera;
import android.os.Bundle;
import android.os.Environment;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
public class MainActivity extends Activity{
private CameraSurfaceView cameraView;
private ImageView imageResult;
private ImageView imageResult2;
private FrameLayout framenew;
private TextView snapPhoto;
private boolean takePicture = true;
private Bitmap image = null;
private String lastPreviewImgPath = "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setupcamera();
}
public void setupcamera(){
cameraView = new CameraSurfaceView(getApplicationContext());
imageResult = new ImageView(getApplicationContext());
imageResult.setBackgroundColor(Color.GRAY);
framenew = (FrameLayout) findViewById(R.id.frame);
snapPhoto = (TextView) findViewById(R.id.textView1);
framenew.addView(imageResult);
framenew.addView(cameraView);
}
public void captureHandler(View view){
if(takePicture){
cameraView.capture(jpegHandler);
}
else{
takePicture = true;
cameraView.preview();
framenew.bringChildToFront(cameraView);
imageResult.setImageBitmap(null);
snapPhoto.setText("Capture");
}
}
public void zoomMinusHandler(View view){
cameraView.zoomMinus();
}
public void zoomPilusHandler(View view){
cameraView.zoomPilus();
}
public Camera.PictureCallback jpegHandler = new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
// TODO Auto-generated method stub
image = BitmapFactory.decodeByteArray(data, 0, data.length);
imageResult.setImageBitmap(image);
imageResult2 = imageResult;
LayoutParams params = imageResult.getLayoutParams();
params.width = framenew.getWidth();
params.height = framenew.getHeight();
imageResult2.setLayoutParams(params);
//framenew.bringChildToFront(imageResult);
//snapPhoto.setText("Take Picture");
//takePicture = false;
File directory = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), "NNCam");
if (!directory.exists()) {
if (!directory.mkdirs()) {
//Log.e(TAG, "Failed to create storage directory.");
}
}
String timeStamp = new SimpleDateFormat("yyyMMdd_HHmmss").format(new Date(System.currentTimeMillis()));
String filename = "/IMG_" + timeStamp + ".jpg";
if(image!=null){
saveImage(directory.getPath(),filename,image);
cameraView.preview();
}
}
};
public void saveImage(String path, String imgname, Bitmap image){
try{
FileOutputStream fos = new FileOutputStream(path+imgname);
BufferedOutputStream stream = new BufferedOutputStream(fos);
image.compress(CompressFormat.JPEG, 100, stream);
stream.flush();
stream.close();
}
catch(FileNotFoundException e){
}
catch(IOException e){
}
lastPreviewImgPath = path+imgname;
Bitmap bitmap = BitmapFactory.decodeFile(lastPreviewImgPath);
ImageView myImageView = (ImageView)findViewById(R.id.lastPreview);
myImageView.setImageBitmap(bitmap);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
cameraView.release();
}
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
cameraView.reconnect();
}
#Override
public void onPause() {
super.onPause();
cameraView.release();
}
}
and this is surfaceview class
package com.cameratag;
import java.io.IOException;
import java.util.List;
import android.content.Context;
import android.content.res.Configuration;
import android.hardware.Camera;
import android.view.Display;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.WindowManager;
public class CameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback{
private Context context;
private SurfaceHolder mHolder;
public Camera camera = null;
public int zoomValue = 0;
public CameraSurfaceView(Context context) {
super(context);
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
// TODO Auto-generated constructor stub
}
#Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
Camera.Parameters parameters = camera.getParameters();
List<Camera.Size> sizes = parameters.getSupportedPictureSizes();
Camera.Size cs = sizes.get(0);
List<Camera.Size> sizes2 = parameters.getSupportedPreviewSizes();
Camera.Size cs2 = sizes2.get(0);
parameters.setPreviewSize(cs2.width, cs2.height);
parameters.setPictureSize(cs.width, cs.height);
camera.setParameters(parameters);
camera.startPreview();
}
#Override
public void surfaceCreated(SurfaceHolder arg0) {
// TODO Auto-generated method stub
camera = Camera.open();
try {
camera.setPreviewDisplay(mHolder);
} catch (IOException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
}
int rrr = 0;
Display display = ((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
int rotation = display.getRotation();
if(rotation==0)rrr=90;
else if(rotation==1)rrr=0;
else if(rotation==3)rrr=180;
else rrr=270;
camera.setDisplayOrientation(rrr);
}
#Override
public void surfaceDestroyed(SurfaceHolder arg0) {
// TODO Auto-generated method stub
camera.stopPreview();
camera = null;
}
public void capture(Camera.PictureCallback jpegHandler){
camera.takePicture(null, null, jpegHandler);
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
int rrr = 0;
Display display = ((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
int rotation = display.getRotation();
if(rotation==0)rrr=90;
else if(rotation==1)rrr=0;
else if(rotation==3)rrr=180;
else rrr=270;
//camera.stopPreview();
camera.setDisplayOrientation(rrr);
//camera.startPreview();
}
public void preview(){
camera.startPreview();
}
public void reconnect(){
try {
camera.reconnect();
} catch (IOException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
}
}
public void zoomMinus() {
Camera.Parameters parameters = camera.getParameters();
// TODO Auto-generated method stub
if(parameters.isZoomSupported()){
if(zoomValue>0){
zoomValue-=2;
parameters.setZoom(zoomValue);
if(parameters.isSmoothZoomSupported()){
camera.startSmoothZoom(zoomValue);
}
else{
camera.setParameters(parameters);
}
}
}
}
public void zoomPilus() {
Camera.Parameters parameters = camera.getParameters();
// TODO Auto-generated method stub
if(parameters.isZoomSupported()){
if(zoomValue<parameters.getMaxZoom()){
zoomValue+=2;
parameters.setZoom(zoomValue);
if(parameters.isSmoothZoomSupported()){
camera.startSmoothZoom(zoomValue);
}
else{
camera.setParameters(parameters);
}
}
}
}
public void release() {
// TODO Auto-generated method stub
camera.setPreviewCallback(null);
camera.stopPreview();
camera.release();
}
}
Please help.
#Override
protected void onPause() {
super.onPause();
// if (inPreview) {
// mCamera.stopPreview();
// }
// mCamera.release();
// mCamera = null;
// inPreview = false;
mCamera.setPreviewCallback(null);
super.onPause();
// mCamera.stopPreview();
}
I was having a similar issue, the trick is to also setup the camera inside of onResume().
The issue was that the app does not call onCreate() every time you go to an activity with the back button, sometimes it simply pauses the activity. onResume() is called whenever the activity returns to the foreground and is a more reliable place to set up the camera.
#Override
protected void onResume()
{
super.onResume();
if( camera == null )
{
camera = Camera.open();
}
}
try to put your release code in try catch block
try{
if (camera != null){
camera.setPreviewCallback(null);
camera.stopPreview();
camera.release();
}
}
I have found the solution for my own. You only need to change surfaceDestroyed method to this.
#Override
public void surfaceDestroyed(SurfaceHolder arg0) {
// TODO Auto-generated method stub
try{
camera.stopPreview();
camera.release();
camera = null;
}
catch(NullPointerException e){
//e.printStackTrace();
}
}
and on onRestoreInstanceState to this.
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
cameraView = null;
setupcamera();
//cameraView.reconnect();
}
in my app requirement for custom camera so developing one, upto that ok everything working fine getting the picture also but when i take picture with my Samsung galaxy ace android phone(2.3) on landscape mode its ok but while going to portrait mode the view of the picture move to left side with 90 degree angle.As you can see in my code i had tried to change the surface position also but nothing happen.
Here is the code for Myactivity class
package com.goutam.test_camera;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.util.Log;
import android.view.Display;
import android.view.Menu;
import android.view.View;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.widget.FrameLayout;
import android.widget.HorizontalScrollView;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.Toast;
public class CameraclassActivity extends Activity implements OnClickListener,
PictureCallback {
ImageButton take_picture, retake_button, save_picture, setting_button;
FrameLayout camerapreviewsurface;
Previewclass cameradisplayclass;
ImageView capture_image;
HorizontalScrollView myscrollview;
private Camera myowncamera;
byte[] finalimage;
Bitmap pic_cap_bitmap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_portrait);
take_picture = (ImageButton) findViewById(R.id.imageButton1);
//
retake_button = (ImageButton) findViewById(R.id.imageButton3);
//
save_picture = (ImageButton) findViewById(R.id.imageButton4);
//
setting_button = (ImageButton) findViewById(R.id.imageButton2);
//
capture_image = (ImageView) findViewById(R.id.imageView1);
//
myscrollview = (HorizontalScrollView) findViewById(R.id.horizontalScrollView1);
//
take_picture.setOnClickListener(this);
retake_button.setOnClickListener(this);
save_picture.setOnClickListener(this);
//
retake_button.setVisibility(View.INVISIBLE);
save_picture.setVisibility(View.INVISIBLE);
setting_button.setVisibility(View.INVISIBLE);
capture_image.setVisibility(View.INVISIBLE);
myscrollview.setVisibility(View.INVISIBLE);
//
myowncamera = Camera.open();
camerapreviewsurface = (FrameLayout) findViewById(R.id.framelayout1);
cameradisplayclass = new Previewclass(this, myowncamera);
camerapreviewsurface.addView(cameradisplayclass);
Log.i("ACTIVITY", "ON CREATE");
}
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.imageButton1:
takePicture();
break;
}
}
private void takePicture() {
// TODO Auto-generated method stub
take_picture.setVisibility(View.INVISIBLE);
cameradisplayclass.takepicture(this);
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
// TODO Auto-generated method stub
// setContentView(R.layout.layout_portrait);
super.onConfigurationChanged(newConfig);
}
#Override
public void onPictureTaken(byte[] data, Camera camera) {
// TODO Auto-generated method stub
finalimage = data;
// camera.stopPreview();
this.myowncamera = camera;
retake_button.setVisibility(View.INVISIBLE);
camerapreviewsurface.setVisibility(View.INVISIBLE);
setting_button.setVisibility(View.VISIBLE);
capture_image.setVisibility(View.VISIBLE);
Toast.makeText(getApplicationContext(), "PICTURE TAKEN", 0).show();
new DisplayImageTask().execute(finalimage);
}
private class DisplayImageTask extends AsyncTask<byte[], Void, Bitmap> {
#Override
protected Bitmap doInBackground(byte[]... parameter) {
pic_cap_bitmap = BitmapFactory.decodeByteArray(finalimage, 0,
finalimage.length);
return pic_cap_bitmap;
}
#Override
protected void onPostExecute(Bitmap result) {
capture_image.setImageBitmap(pic_cap_bitmap);
super.onPostExecute(result);
}
#Override
protected void onProgressUpdate(Void... values) {
Toast.makeText(getApplicationContext(), "DISPLAYING IMAGE", 0)
.show();
super.onProgressUpdate(values);
}
}
// #Override
// public boolean onCreateOptionsMenu(Menu menu) {
// // Inflate the menu; this adds items to the action bar if it is present.
// getMenuInflater().inflate(R.menu.layout_portrait, menu);
// return true;
#Override
protected void onPause() {
Log.i("ACTIVITY", "ON PAUSE");
System.gc();
this.finish();
super.onPause();
}
#Override
protected void onResume() {
super.onResume();
}
#Override
public void onBackPressed() {
System.gc();
this.finish();
myowncamera.release();
super.onBackPressed();
}
#Override
protected void onDestroy() {
this.finish();
System.gc();
super.onDestroy();
}
}
and here is the code for the preview class for my surfaceholder to hold the surface view
package com.goutam.test_camera;
import java.io.IOException;
import android.app.Activity;
import android.content.Context;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.PictureCallback;
import android.util.Log;
import android.view.Display;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.Surface;
import android.view.SurfaceView;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Toast;
public class Previewclass extends SurfaceView implements Callback {
private Camera mcamera;
boolean ispreviewing = false;
// WindowManager manager;
SurfaceHolder holder;
public Previewclass(Context context, Camera mycamera) {
super(context);
this.mcamera = mycamera;
// manager=(WindowManager)
// context.getSystemService(Context.WINDOW_SERVICE);
holder = this.getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
// mcamera=null;
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
Log.i("CAMERA", "ON SURFACE CHANGE");
try {
mcamera.setPreviewDisplay(this.holder);
mcamera.startPreview();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// if(ispreviewing==true)
// {
// mcamera.stopPreview();
// }
// Parameters mparameters=mcamera.getParameters();
// Display display=manager.getDefaultDisplay();
// if(display.getRotation()==Surface.ROTATION_0)
// {
// mparameters.setPreviewSize(height, width);
// mcamera.setDisplayOrientation(90);
// }
// if(display.getRotation()==Surface.ROTATION_90)
// {
// mparameters.setPreviewSize(width, height);
// }
// if(display.getRotation() == Surface.ROTATION_180)
// {
// mparameters.setPreviewSize(height, width);
// }
// if(display.getRotation() == Surface.ROTATION_270)
// {
// mparameters.setPreviewSize(width, height);
// mcamera.setDisplayOrientation(180);
// }
// mcamera.setParameters(mparameters);
// previewCamera();
}
// private void previewCamera()
// {
// try {
// mcamera.setPreviewDisplay(this.holder);
// mcamera.startPreview();
// ispreviewing = true;
// } catch (IOException e) {
// Log.e("CAMERA DISPLAY", "ERROR");
// e.printStackTrace();
// }
//
// }
#Override
public void surfaceCreated(SurfaceHolder holder) {
Log.i("CAMERA", "ON SURFACE CREATED");
try {
mcamera.setPreviewDisplay(holder);
ispreviewing = true;
mcamera.startPreview();
} catch (IOException e) {
Log.e("CAMERA OPENING", "ERROR");
e.printStackTrace();
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
Log.i("CAMERA", "ON SURFACE DESTROY");
this.mcamera = null;
// this.manager=null;
this.holder = null;
// mcamera.stopPreview();
// this.mcamera.release();
}
public void takepicture(PictureCallback imageCallback) {
mcamera.takePicture(null, null, imageCallback);
}
}
here is my androidmanifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.goutam.test_camera"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="16" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature
android:name="android.hardware.camera.autofocus"
android:required="false" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.goutam.test_camera.CameraclassActivity"
android:configChanges="orientation|keyboardHidden"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
i am stuck with this thing for very long time but didn't found any
solution
as i am new to android not able identify the behaviour on android device.
but one thing is there the same code is work very well with the htc made android phone.So,can i assume that this is the hardware
default which is providing by the manufacturer.If anyone want the .apk
file for test i can send to them.
email id:gkundu07#gmail.com
Sorry for my language and thanks for listening me.
Any kind of help will be appreciate.
Actually this happens because , by default the camera of Samsung Galaxy Ace is Landscape . So if you change it to portrait , it automatically rotates the image captured as if the image is captured in the landscape mode .
Find the orientation of the screen ( using the following code )
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState)
{
super.onRestoreInstanceState(savedInstanceState);
if (savedInstanceState != null)
{
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT)
{
// your code
}
else if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE)
{
// your code
}
savedInstanceState.getInt("param");
Log.e("on restore saved state",""+savedInstanceState.getInt("param"));
}
}
and if it is Portrait
Either rotate the image and save in the SDCard or if you are just displaying it in the imageView , rotate and set to its BackgroundResource
the Following is the code to rotate it to 90 degree ,
public static Bitmap rotate(Bitmap b, int degrees)
{
if (degrees != 0 && b != null)
{
Matrix m = new Matrix();
m.setRotate(degrees, (float) b.getWidth() / 2, (float) b.getHeight() / 2);
try {
Bitmap b2 = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), m, true);
if (b != b2)
{
b.recycle();
b = b2;
}
} catch (OutOfMemoryError ex)
{
throw ex;
}
}
return b;
}
i want to switch between the front and back cameras on a button click .
when any one of the camera's is open , i need to release it and open the other one .
could anyone tell me the block of code to switch ?
Thank you in advance . . . .
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<Button
android:id="#+id/Button01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:background="#drawable/camera_btn"/>
<Button
android:id="#+id/Button02"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:background="#drawable/front_back_btn"/>
<ImageView
android:id="#+id/ImageView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/Button01"
android:contentDescription="#string/app_name">
</ImageView>
<com.example.surfacecamera.CameraView
android:id="#+id/CameraView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true" />
</RelativeLayout>
THIS IS MY ACTIVITY
and main java class is
package com.example.surfacecamera;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Bitmap.CompressFormat;
import android.hardware.Camera;
public class MainActivity extends Activity implements OnClickListener, Camera.PictureCallback {
CameraView cameraView;
ImageView imv;
Button b2 ;
int cameraCount = 0;
int camIdx = 0;
Camera cam;
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
setContentView(R.layout.activity_main);
Button pictureButton = (Button) this.findViewById(R.id.Button01);
Button b2 = (Button) this.findViewById(R.id.Button02);
imv = (ImageView) this.findViewById(R.id.ImageView01);
cameraView = (CameraView) this.findViewById(R.id.CameraView01);
cameraCount = Camera.getNumberOfCameras();
b2.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
}
});
pictureButton.setOnClickListener(this);
}
// From the OnClickListener
public void onClick(View v)
{
cameraView.takePicture(null, null, this);
}
// From the Camera.PictureCallback
public void onPictureTaken(byte[] data, Camera camera)
{
Bitmap bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
imv.setImageBitmap(bmp);
String filename = "apicture.jpg";
File pictureFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + filename);
try
{
FileOutputStream pfos = new FileOutputStream(pictureFile);
bmp.compress(CompressFormat.JPEG, 75, pfos);
pfos.flush();
pfos.close();
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
and another class
package com.example.surfacecamera;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import android.content.Context;
import android.content.res.Configuration;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class CameraView extends SurfaceView implements SurfaceHolder.Callback
{
SurfaceHolder mHolder;
int width;
int height;
Camera mCamera;
public CameraView(Context context, AttributeSet attrs)
{
super(context,attrs);
holderCreation();
}
public CameraView(Context context)
{
super(context);
holderCreation();
}
public void takePicture(Camera.ShutterCallback shutter, Camera.PictureCallback raw, Camera.PictureCallback jpeg)
{
mCamera.takePicture(shutter, raw, jpeg);
}
#SuppressWarnings("deprecation")
public void holderCreation()
{
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder)
{
// The Surface has been created, acquire the camera and tell it where to draw.
mCamera = Camera.open();
Parameters params = mCamera.getParameters();
// If we aren't landscape (the default), tell the camera we want portrait mode
if (this.getResources().getConfiguration().orientation !=
Configuration.ORIENTATION_LANDSCAPE)
{
params.set("orientation", "portrait"); // "landscape"
// And Rotate the final picture if possible
// This works on 2.0 and higher only
//params.setRotation(90);
// Use reflection to see if it exists and to call it so you can support older versions
try {
Method rotateSet = Camera.Parameters.class.getMethod(
"setRotation", new Class[] { Integer.TYPE } );
Object arguments[] = new Object[] { new Integer(90) };
rotateSet.invoke(params, arguments);
} catch (NoSuchMethodException nsme) {
// Older Device
Log.v("CameraView","No Set Rotation");
} catch (IllegalArgumentException e) {
Log.v("CameraView","Exception IllegalArgument");
} catch (IllegalAccessException e) {
Log.v("CameraView","Illegal Access Exception");
} catch (InvocationTargetException e) {
Log.v("CameraView","Invocation Target Exception");
}
}
mCamera.setParameters(params);
try
{
mCamera.setPreviewDisplay(holder);
}
catch (IOException exception)
{
mCamera.release();
mCamera = null;
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// Surface will be destroyed when we return, so stop the preview.
// Because the CameraDevice object is not a shared resource, it's very
// important to release it when the activity is paused.
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h)
{
width = w;
height = h;
// Now that the size is known, set up the camera parameters and begin the preview.
Camera.Parameters parameters = mCamera.getParameters();
//parameters.setPreviewSize(w, h);
mCamera.setParameters(parameters);
mCamera.startPreview();
}
}
I've developed a very simple app on android to get the webcam screen on a surfaceView and now I want to capture the surfaceView as an image onto SDCard but I only end up with a black screen after saving the picture below is my full app for get webcam screen on surface and also capture the image out of surfaceView:
imported packages
import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.*;
import android.widget.Button;
import android.widget.Toast;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
methods for getting webcam screen on a surfaceview
Camera camera;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
boolean previewing = false;
private String mScreenshotPath = Environment.getExternalStorageDirectory() + "/myimages";
//private ArrayList<Element> mElements = new ArrayList<Element>();
private Button takePicture;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
getWindow().setFormat(PixelFormat.UNKNOWN);
surfaceView = (SurfaceView)findViewById(R.id.camerapreview);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
surfaceView.setDrawingCacheEnabled(true);
LayoutInflater controlInflater = LayoutInflater.from(getBaseContext());
View viewControl = controlInflater.inflate(R.layout.control, null);
ViewGroup.LayoutParams layoutParamsControl = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT
,ViewGroup.LayoutParams.FILL_PARENT);
this.addContentView(viewControl,layoutParamsControl);
takePicture = (Button) findViewById(R.id.takepicture);
takePicture.setOnClickListener(this);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
if(previewing){
camera.stopPreview();
previewing = false;
}
if (camera != null){
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
previewing = true;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera = Camera.open();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera.stopPreview();
camera.release();
camera = null;
previewing = false;
}
on the same class my approach for capturing a surfaceView as image
#Override
public void onClick(View view) {
//To change body of implemented methods use File | Settings | File Templates.
Toast.makeText(getApplicationContext() , "pucture saved" , Toast.LENGTH_SHORT).show();
saveScreenshot();
//takePicture.setVisibility(View.GONE);
}
private boolean ensureSDCardAccess() {
File file = new File(mScreenshotPath);
if (file.exists()) {
return true;
} else if (file.mkdirs()) {
return true;
}
return false;
}
public void saveScreenshot() {
if (ensureSDCardAccess()) {
//Bitmap bitmap = Bitmap.createBitmap(surfaceView.getWidth(), surfaceView.getHeight(), Bitmap.Config.ARGB_8888);
surfaceHolder.getSurface().freeze();
Bitmap bitmap = surfaceView.getDrawingCache();
Canvas canvas = new Canvas(bitmap);
//surfaceView.draw(canvas);
File file = new File(mScreenshotPath + "/" + System.currentTimeMillis() + ".jpg");
FileOutputStream fos;
try {
fos = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.close();
} catch (FileNotFoundException e) {
Log.e("Panel", "FileNotFoundException", e);
} catch (IOException e) {
Log.e("Panel", "IOEception", e);
}
}
}
layouts :
//main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<SurfaceView
android:id="#+id/camerapreview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
/>
</LinearLayout>
//control.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:layout_gravity="bottom"
>
<Button android:id="#+id/takepicture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Take picture"
android:layout_gravity="right"
android:layout_margin="10dp"
/>
</LinearLayout>
As you can see I'm able to capture surfaceView in a bitmap object but my problem is, there isn't any clue of webcam screen on surfaceView during saving it in a bitmap object.
How can I have a persistence surfaceView so I'm not gonna miss the webcam screen?
I had a similar thing where I needed to save my image with an overlay. I achieved this by first saving the captured image, then putting it back into my view, and then saving that as the bitmap. It worked well enough for what i needed.