I want to make an android app which can capture image along with it's camera preview. But the app crashes while taking a picture. While taking a picture it gives NullPointerException and InvocationTargetException.
I would appreciate any suggestions.
public class CameraActivity extends ActionBarActivity {
private Preview mPreview;
private static final String TAG = "CameraDemo";
RelativeLayout preview;
Camera mCamera;
private static boolean DEBUGGING = true;
private static final String LOG_TAG = "CameraPreviewSample";
private static final String CAMERA_PARAM_ORIENTATION = "orientation";
private static final String CAMERA_PARAM_LANDSCAPE = "landscape";
private static final String CAMERA_PARAM_PORTRAIT = "portrait";
protected Activity mActivity;
protected List<Camera.Size> mPreviewSizeList;
protected List<Camera.Size> mPictureSizeList;
protected Camera.Size mPreviewSize;
protected Camera.Size mPictureSize;
Camera.ShutterCallback shutterCallback = new Camera.ShutterCallback() {
@Override
public void onShutter() {
Log.d(TAG, "onShutter'd");
}
};
Camera.PictureCallback rawCallback = new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
Log.d(TAG, "onPictureTaken - raw");
}
};
Camera.PictureCallback jpegCallback = new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
Bitmap cameraBitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
Bitmap cameraScaledBitmap = Bitmap.createScaledBitmap(cameraBitmap, 1280, 720, true);
int wid = cameraScaledBitmap.getWidth();
int hgt = cameraScaledBitmap.getHeight();
Bitmap newImage = Bitmap.createBitmap(wid, hgt, Bitmap.Config.ARGB_8888);
FrameLayout view = (FrameLayout) findViewById(R.id.image);
view.setDrawingCacheEnabled(true);
Bitmap overlayBitmap = view.getDrawingCache();
Bitmap overlayScaledBitmap = Bitmap.createScaledBitmap(overlayBitmap, wid, hgt, true);
// Bitmap overlayBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.hat);
// Bitmap overlayScaledBitmap = Bitmap.createScaledBitmap(overlayBitmap, wid, hgt, true);
Canvas canvas = new Canvas(newImage);
canvas.drawBitmap(cameraScaledBitmap, 0, 0, null);
canvas.drawBitmap(overlayScaledBitmap, 0, 0, null);
File storagePath = new File(Environment.getExternalStorageDirectory() + String.format(
"/BeautyParlour/%d.png", System.currentTimeMillis()));
try {
/*FrameLayout view = (FrameLayout) findViewById(R.id.image);
view.setDrawingCacheEnabled(true);
Bitmap bitmap = view.getDrawingCache();*/
FileOutputStream outputStream = new FileOutputStream(storagePath);
newImage.compress(Bitmap.CompressFormat.PNG, 95, outputStream);
outputStream.flush();
outputStream.close();
Log.d(TAG, "onPictureTaken - wrote bytes: " + data.length);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
/*camera.startPreview();
newImage.recycle();
newImage = null;*/
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse("file://" + storagePath.getAbsolutePath()), "image/*");
startActivity(intent);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
File imageDirectory = new File(Environment.getExternalStorageDirectory() + "/BeautyParlour/");
// Check if the directory exists
if (!imageDirectory.exists()) {
// have the object build the directory structure, if needed.
imageDirectory.mkdirs();
}
}
public void snap(View view) {
/*if (mCamera == null) {
// Warn user that camera is not available via "Toast" or similar.
Log.i("CAMERA = ", "NuLL");
} else {*/
mCamera.takePicture(shutterCallback, rawCallback, jpegCallback);
//}
}
@Override
protected void onPause() {
super.onPause();
/*if (null == mCamera) {
return;
}*/
Log.i("Pause", "onpause");
if (mCamera != null){
mCamera.setPreviewCallback(null);
mPreview.getHolder().removeCallback(mPreview);
mCamera.release();
mCamera = null;
}
}
@Override
protected void onResume() {
super.onResume();
Log.i("Back", "onresume");
if (mCamera == null) {
mPreview = new Preview(this);
preview = (RelativeLayout) findViewById(R.id.preview);
preview.addView(mPreview);
}
}
class Preview extends SurfaceView implements SurfaceHolder.Callback {
SurfaceHolder mHolder;
Camera mCamera;
public Preview(Context context) {
super(context);
mActivity = (Activity) context;
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, acquire the camera and tell it where
// to draw.
//mCamera = Camera.open();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
int numberOfCameras = Camera.getNumberOfCameras();
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
for (int i = 0; i < numberOfCameras; i++) {
Camera.getCameraInfo(i, cameraInfo);
if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK)
mCamera = Camera.open(i);
}
}
/*if (mCamera == null)
mCamera = Camera.open();*/
try {
mCamera.setPreviewDisplay(holder);
mCamera.setPreviewCallback(new Camera.PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera arg1) {
Log.d(TAG, "onPreviewFrame - wrote bytes: "
+ data.length);
Preview.this.invalidate();
}
});
} catch (IOException e) {
Log.i("Exce", e.toString());
mCamera.release();
mCamera = null;
e.printStackTrace();
}
}
@Override
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<Camera.Size> sizes = parameters.getSupportedPreviewSizes();
Camera.Size optimalSize = getOptimalPreviewSize(sizes, w, h);
Display display = ((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
if(display.getRotation() == Surface.ROTATION_0)
{
parameters.setPreviewSize(optimalSize.height, optimalSize.width);
mCamera.setDisplayOrientation(90);
}
if(display.getRotation() == Surface.ROTATION_90)
{
parameters.setPreviewSize(optimalSize.width, optimalSize.height);
}
if(display.getRotation() == Surface.ROTATION_180)
{
parameters.setPreviewSize(optimalSize.width, optimalSize.height);
}
if(display.getRotation() == Surface.ROTATION_270)
{
parameters.setPreviewSize(optimalSize.width, optimalSize.height);
mCamera.setDisplayOrientation(0);
}
mCamera.setParameters(parameters);
mCamera.startPreview();*/
if (mHolder.getSurface() == null) {
// preview surface does not exist
Log.i("RETURN", "RETURN");
return;
}
// stop preview before making changes
try {
//mCamera.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.Parameters cameraParams = mCamera.getParameters();
boolean portrait = isPortrait();
configureCameraParameters(cameraParams, portrait);
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e) {
Log.d("CameraView", "Error starting camera preview: " + e.getMessage());
}
}
public boolean isPortrait() {
return (mActivity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT);
}
protected void configureCameraParameters(Camera.Parameters cameraParams, boolean portrait) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO) { // for 2.1 and before
if (portrait) {
cameraParams.set(CAMERA_PARAM_ORIENTATION, CAMERA_PARAM_PORTRAIT);
} else {
cameraParams.set(CAMERA_PARAM_ORIENTATION, CAMERA_PARAM_LANDSCAPE);
}
} else { // for 2.2 and later
int angle;
Display display = mActivity.getWindowManager().getDefaultDisplay();
switch (display.getRotation()) {
case Surface.ROTATION_0: // This is display orientation
angle = 90; // This is camera orientation
break;
case Surface.ROTATION_90:
angle = 0;
break;
case Surface.ROTATION_180:
angle = 270;
break;
case Surface.ROTATION_270:
angle = 180;
break;
default:
angle = 90;
break;
}
Log.v(LOG_TAG, "angle: " + angle);
mCamera.setDisplayOrientation(angle);
}
cameraParams = mCamera.getParameters();
mPreviewSizeList = cameraParams.getSupportedPreviewSizes();
mPictureSizeList = cameraParams.getSupportedPictureSizes();
mPreviewSize = mPreviewSizeList.get(0);
mPictureSize = mPictureSizeList.get(0);
cameraParams.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
cameraParams.setPictureSize(mPictureSize.width, mPictureSize.height);
if (DEBUGGING) {
Log.v(LOG_TAG, "Preview Actual Size - w: " + mPreviewSize.width + ", h: " + mPreviewSize.height);
Log.v(LOG_TAG, "Picture Actual Size - w: " + mPictureSize.width + ", h: " + mPictureSize.height);
}
mCamera.setParameters(cameraParams);
}
@Override
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.
Log.e("TABACT", "surfaceDestroyed()");
mCamera.stopPreview();
mCamera.setPreviewCallback(null);
mCamera.release();
mCamera = null;
}
private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int width, int height) {
final double ASPECT_TOLERANCE = 0.05;
double targetRatio = (double) width / height;
if (sizes == null) return null;
Camera.Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
int targetHeight = height;
// Try to find an size match aspect ratio and size
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);
}
}
// Cannot find the one match the aspect ratio, ignore the requirement
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;
}
}
}
0 comments:
Post a Comment