Android Camera——拍照
Camera定义在package android.hardware内,具体用法SDK里叙述的可清楚了。架构解析什么的网上也有很多,没什么必要讲了(你认为我不知道我会说吗)。
这篇呢,就整理了下Camera的拍照,其他还木有==
一、系统相机
1)调用方式
系统相机的入口Action:MediaStore.ACTION_IMAGE_CAPTURE。只需以startActivityForResult(…)启动该Activity即可。
-
- Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
- startActivityForResult(intent, 1);
2
)处理方式
在onActivityResult(…)中,处理返回信息。
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (1 == requestCode) {
- if (resultCode == Activity.RESULT_OK) {
- Bitmap cameraBitmap = (Bitmap) data.getExtras().get("data");
- ……
- }
- takeBtn1.setClickable(true);
- }
- super.onActivityResult(requestCode, resultCode, data);
- }
二、自定义相机
1
)照相预览
继承SufaceView写自己的预览界面,继而放到你的照相Activity的布局里。这里面有个相机拍照监听接口,用于在Activity里再处理这些操作。
- public class CameraPreview extends SurfaceView implements
- SurfaceHolder.Callback {
-
-
-
-
-
- public static final int WIDTH = 1024;
- public static final int HEIGHT = 768;
-
-
- private OnCameraStatusListener listener;
-
- private SurfaceHolder holder;
- private Camera camera;
-
-
- private PictureCallback pictureCallback = new PictureCallback() {
-
-
- @Override
- public void onPictureTaken(byte[] data, Camera camera) {
-
-
- camera.stopPreview();
- camera = null;
-
-
- if (null != listener) {
- listener.onCameraStopped(data);
- }
- }
- };
-
-
- public CameraPreview(Context context, AttributeSet attrs) {
- super(context, attrs);
-
- holder = getHolder();
-
- holder.addCallback(this);
-
- holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
- }
-
-
- public void surfaceCreated(SurfaceHolder holder) {
-
-
- camera = Camera.open();
- try {
-
- camera.setPreviewDisplay(holder);
- } catch (IOException e) {
- e.printStackTrace();
-
- camera.release();
- camera = null;
- }
- }
-
-
- public void surfaceDestroyed(SurfaceHolder holder) {
-
-
- camera.release();
- }
-
-
- public void surfaceChanged(final SurfaceHolder holder, int format, int w,
- int h) {
-
- try {
-
- Camera.Parameters parameters = camera.getParameters();
-
- parameters.setPictureFormat(PixelFormat.JPEG);
-
- parameters.setPreviewSize(WIDTH, HEIGHT);
-
- parameters.setPictureSize(WIDTH, HEIGHT);
-
- camera.setParameters(parameters);
-
- camera.startPreview();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
-
- public void takePicture() {
-
- if (camera != null) {
-
- camera.autoFocus(new AutoFocusCallback() {
- @Override
- public void onAutoFocus(boolean success, Camera camera) {
- if (null != listener) {
- listener.onAutoFocus(success);
- }
-
- if (success) {
- camera.takePicture(null, null, pictureCallback);
- }
- }
- });
- }
- }
-
-
- public void setOnCameraStatusListener(OnCameraStatusListener listener) {
- this.listener = listener;
- }
-
-
-
-
- public interface OnCameraStatusListener {
-
-
- void onCameraStopped(byte[] data);
-
-
- void onAutoFocus(boolean success);
- }
-
- }
2
)照相活动
就是我们自己做的照相Activity了。完成后调用自己的相机,也就是跳转入这个Activity。这里面,照片以自定义路径的形式存入的媒体库。
- public class CameraActivity extends Activity implements
- CameraPreview.OnCameraStatusListener {
-
- public static final Uri IMAGE_URI = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
- public static final String PATH = Environment.getExternalStorageDirectory()
- .toString() + "/AndroidMedia/";
-
- private CameraPreview mCameraPreview;
- private ImageView focusView;
- private boolean isTaking = false;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
-
- requestWindowFeature(Window.FEATURE_NO_TITLE);
- getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
- WindowManager.LayoutParams.FLAG_FULLSCREEN);
-
- setContentView(R.layout.camera);
-
- mCameraPreview = (CameraPreview) findViewById(R.id.preview);
- mCameraPreview.setOnCameraStatusListener(this);
-
- focusView = (ImageView) findViewById(R.id.focusView);
- }
-
-
-
-
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- if (event.getAction() == MotionEvent.ACTION_DOWN && !isTaking) {
- isTaking = true;
- mCameraPreview.takePicture();
- }
- return super.onTouchEvent(event);
- }
-
-
-
-
- private Uri insertImage(ContentResolver cr, String name, long dateTaken,
- String directory, String filename, Bitmap source, byte[] jpegData) {
-
- OutputStream outputStream = null;
- String filePath = directory + filename;
- try {
- File dir = new File(directory);
- if (!dir.exists()) {
- dir.mkdirs();
- }
- File file = new File(directory, filename);
- if (file.createNewFile()) {
- outputStream = new FileOutputStream(file);
- if (source != null) {
- source.compress(CompressFormat.JPEG, 75, outputStream);
- } else {
- outputStream.write(jpegData);
- }
- }
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- return null;
- } catch (IOException e) {
- e.printStackTrace();
- return null;
- } finally {
- if (outputStream != null) {
- try {
- outputStream.close();
- } catch (Throwable t) {
- }
- }
- }
- ContentValues values = new ContentValues(7);
- values.put(MediaStore.Images.Media.TITLE, name);
- values.put(MediaStore.Images.Media.DISPLAY_NAME, filename);
- values.put(MediaStore.Images.Media.DATE_TAKEN, dateTaken);
- values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
- values.put(MediaStore.Images.Media.DATA, filePath);
- return cr.insert(IMAGE_URI, values);
- }
-
-
-
-
- @Override
- public void onCameraStopped(byte[] data) {
- Log.e("onCameraStopped", "==onCameraStopped==");
-
- Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
-
- long dateTaken = System.currentTimeMillis();
-
- String filename = DateFormat.format("yyyy-MM-dd kk.mm.ss", dateTaken)
- .toString() + ".jpg";
-
- Uri uri = insertImage(getContentResolver(), filename, dateTaken, PATH,
- filename, bitmap, data);
-
- Intent intent = getIntent();
- intent.putExtra("uriStr", uri.toString());
- intent.putExtra("dateTaken", dateTaken);
-
-
- setResult(20, intent);
-
- finish();
- }
-
-
-
-
- @Override
- public void onAutoFocus(boolean success) {
-
- if (success) {
- focusView.setImageResource(R.drawable.focus2);
- } else {
- focusView.setImageResource(R.drawable.focus1);
- Toast.makeText(this, "焦距不准,请重拍!", Toast.LENGTH_SHORT).show();
- isTaking = false;
- }
- }
-
- }
3
)相机调用&
处理
-
- Intent intent = new Intent(this, CameraActivity.class);
- startActivityForResult(intent, 2);
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (2 == requestCode) {
-
- if (resultCode == 20) {
- Bundle bundle = data.getExtras();
-
- Uri uri = Uri.parse(bundle.getString("uriStr"));
-
- long dateTaken = bundle.getLong("dateTaken");
- try {
-
- Bitmap cameraBitmap = MediaStore.Images.Media.getBitmap(
- getContentResolver(), uri);
- previewBitmap(cameraBitmap);
-
- getContentResolver().delete(
- CameraActivity.IMAGE_URI,
- MediaStore.Images.Media.DATE_TAKEN + "="
- + String.valueOf(dateTaken), null);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- takeBtn2.setClickable(true);
- }
- super.onActivityResult(requestCode, resultCode, data);
- }
三、我加的相机蒙版
^^
这个最重要了,就是为了这个才把这还未完工的工程放上来的。
布局文件里面我们在加一个自定义的MaskSurfaceView,注意放在相机预览的前面,并要设置成透明(包括重刷图层的时候也要注意透明度)。
- <?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:gravity="center"
- android:orientation="horizontal" >
-
- <RelativeLayout
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:layout_weight="1" >
-
- <org.join.meida.camera.takephoto.MaskSurfaceView
- android:layout_width="fill_parent"
- android:layout_height="fill_parent" />
-
- <org.join.meida.camera.takephoto.CameraPreview
- android:id="@+id/preview"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent" />
-
- <ImageView
- android:id="@+id/focusView"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_centerInParent="true"
- android:src="@drawable/focus1" />
- </RelativeLayout>
-
- </LinearLayout>
蒙版来啦,注意到心了没有?(3d爱心是网上别人实现的)
- public class MaskSurfaceView extends SurfaceView implements
- SurfaceHolder.Callback, Runnable {
-
-
- private SurfaceHolder mSurfaceHolder;
-
- private boolean loop = true;
-
- private static final long TIME = 300;
-
- private int mCount;
-
- private int mode;
-
- public MaskSurfaceView(Context context, AttributeSet attrs) {
- super(context, attrs);
- mSurfaceHolder = getHolder();
- mSurfaceHolder.addCallback(this);
- mSurfaceHolder.setFormat(PixelFormat.TRANSLUCENT);
- }
-
-
- @Override
- public void surfaceCreated(SurfaceHolder holder) {
- mode = new Random().nextInt(2);
- new Thread(this).start();
- }
-
-
- @Override
- public void surfaceChanged(SurfaceHolder holder, int format, int width,
- int height) {
- }
-
-
- @Override
- public void surfaceDestroyed(SurfaceHolder holder) {
- loop = false;
- }
-
- @Override
- public void run() {
- while (loop) {
- try {
- Thread.sleep(TIME);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- synchronized (mSurfaceHolder) {
- drawMask();
- }
- }
- }
-
-
-
-
- private void drawMask() {
-
- Canvas mCanvas = mSurfaceHolder.lockCanvas();
-
-
- if (mSurfaceHolder == null || mCanvas == null)
- return;
-
- int w = mCanvas.getWidth();
- int h = mCanvas.getHeight();
-
-
- Paint mPaint = new Paint();
- mPaint.setAntiAlias(true);
- mPaint.setColor(0x00000000);
- mCanvas.drawRect(0, 0, w, h, mPaint);
-
- setPaintColor(mPaint);
- mPaint.setStyle(Paint.Style.STROKE);
-
- if (0 == mode) {
- drawHeart2D(mCanvas, mPaint, w / 2, h / 2, h / 2);
- } else {
- drawHeart3D(mCanvas, mPaint);
- }
-
-
- mSurfaceHolder.unlockCanvasAndPost(mCanvas);
- }
-
-
- private void drawHeart2D(Canvas mCanvas, Paint mPaint, int centerX,
- int centerY, float height) {
-
- float r = height / 4;
-
- float topX = centerX;
- float topY = centerY - r;
-
-
- RectF leftOval = new RectF(topX - 2 * r, topY - r, topX, topY + r);
- mCanvas.drawArc(leftOval, 180f, 180f, false, mPaint);
-
- RectF rightOval = new RectF(topX, topY - r, topX + 2 * r, topY + r);
- mCanvas.drawArc(rightOval, 180f, 180f, false, mPaint);
-
-
- float base = 3 * r;
- double argu = Math.PI / 2 / base;
- float y = base, value;
- while (y >= 0) {
- value = (float) (2 * r * Math.sin(argu * (base - y)));
- mCanvas.drawPoint(topX - value, topY + y, mPaint);
- mCanvas.drawPoint(topX + value, topY + y, mPaint);
- y -= 1;
- }
-
-
-
-
-
-
-
-
-
- }
-
-
- private void drawHeart3D(Canvas mCanvas, Paint mPaint) {
-
- int w = mCanvas.getWidth();
- int h = mCanvas.getHeight();
-
-
- int i, j;
- double x, y, r;
- for (i = 0; i <= 90; i++) {
- for (j = 0; j <= 90; j++) {
- r = Math.PI / 45 * i * (1 - Math.sin(Math.PI / 45 * j)) * 20;
- x = r * Math.cos(Math.PI / 45 * j) * Math.sin(Math.PI / 45 * i)
- + w / 2;
- y = -r * Math.sin(Math.PI / 45 * j) + h / 4;
- mCanvas.drawPoint((float) x, (float) y, mPaint);
- }
- }
- }
-
-
- private void setPaintColor(Paint mPaint) {
- mCount = mCount < 100 ? mCount + 1 : 0;
- switch (mCount % 6) {
- case 0:
- mPaint.setColor(Color.BLUE);
- break;
- case 1:
- mPaint.setColor(Color.GREEN);
- break;
- case 2:
- mPaint.setColor(Color.RED);
- break;
- case 3:
- mPaint.setColor(Color.YELLOW);
- break;
- case 4:
- mPaint.setColor(Color.argb(255, 255, 181, 216));
- break;
- case 5:
- mPaint.setColor(Color.argb(255, 0, 255, 255));
- break;
- default:
- mPaint.setColor(Color.WHITE);
- break;
- }
- }
-
- }
四、后记
今天是几号来着?T^T。