Android自定义照相机实现(拍照、保存到SD卡,利用Bundle在Acitivity交换数据)

import java.io.IOException;

import java.text.SimpleDateFormat;

import java.util.Date;

import android.app.Activity;

import android.content.Intent;

import android.graphics.PixelFormat;

import android.hardware.Camera;

import android.hardware.Camera.PictureCallback;

import android.os.Bundle;

import android.os.Environment;

import android.view.KeyEvent;

import android.view.MotionEvent;

import android.view.Surface;

import android.view.SurfaceHolder;

import android.view.SurfaceHolder.Callback;

import android.view.SurfaceView;

import android.view.View;

import android.view.ViewGroup;

import android.widget.Toast;

/**

  • Android手指拍照

  • @author wwj

  • @date 2013/4/29

*/

public class MainActivity extends Activity {

private View layout;

private Camera camera;

private Camera.Parameters parameters = null;

Bundle bundle = null; // 声明一个Bundle对象,用来存储数据

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

// 显示界面

setContentView(R.layout.activity_main);

layout = this.findViewById(R.id.buttonLayout);

SurfaceView surfaceView = (SurfaceView) this

.findViewById(R.id.surfaceView);

surfaceView.getHolder()

.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

surfaceView.getHolder().setFixedSize(176, 144); //设置Surface分辨率

surfaceView.getHolder().setKeepScreenOn(true);// 屏幕常亮

surfaceView.getHolder().addCallback(new SurfaceCallback());//为SurfaceView的句柄添加一个回调函数

}

/**

  • 按钮被点击触发的事件

  • @param v

*/

public void btnOnclick(View v) {

if (camera != null) {

switch (v.getId()) {

case R.id.takepicture:

// 拍照

camera.takePicture(null, null, new MyPictureCallback());

break;

}

}

}

/**

  • 图片被点击触发的时间

  • @param v

*/

public void imageClick(View v) {

if (v.getId() == R.id.scalePic) {

if (bundle == null) {

Toast.makeText(getApplicationContext(), R.string.takephoto,

Toast.LENGTH_SHORT).show();

} else {

Intent intent = new Intent(this, ShowPicActivity.class);

intent.putExtras(bundle);

startActivity(intent);

}

}

}

private final class MyPictureCallback implements PictureCallback {

@Override

public void onPictureTaken(byte[] data, Camera camera) {

try {

bundle = new Bundle();

bundle.putByteArray(“bytes”, data); //将图片字节数据保存在bundle当中,实现数据交换

saveToSDCard(data); // 保存图片到sd卡中

Toast.makeText(getApplicationContext(), R.string.success,

Toast.LENGTH_SHORT).show();

camera.startPreview(); // 拍完照后,重新开始预览

} catch (Exception e) {

e.printStackTrace();

}

}

}

/**

  • 将拍下来的照片存放在SD卡中

  • @param data

  • @throws IOException

*/

public static void saveToSDCard(byte[] data) throws IOException {

Date date = new Date();

SimpleDateFormat format = new SimpleDateFormat(“yyyyMMddHHmmss”); // 格式化时间

String filename = format.format(date) + “.jpg”;

File fileFolder = new File(Environment.getExternalStorageDirectory()

  • “/finger/”);

if (!fileFolder.exists()) { // 如果目录不存在,则创建一个名为"finger"的目录

fileFolder.mkdir();

}

File jpgFile = new File(fileFolder, filename);

FileOutputStream outputStream = new FileOutputStream(jpgFile); // 文件输出流

outputStream.write(data); // 写入sd卡中

outputStream.close(); // 关闭输出流

}

private final class SurfaceCallback implements Callback {

// 拍照状态变化时调用该方法

@Override

public void surfaceChanged(SurfaceHolder holder, int format, int width,

int height) {

parameters = camera.getParameters(); // 获取各项参数

parameters.setPictureFormat(PixelFormat.JPEG); // 设置图片格式

parameters.setPreviewSize(width, height); // 设置预览大小

parameters.setPreviewFrameRate(5); //设置每秒显示4帧

parameters.setPictureSize(width, height); // 设置保存的图片尺寸

parameters.setJpegQuality(80); // 设置照片质量

}

// 开始拍照时调用该方法

@Override

public void surfaceCreated(SurfaceHolder holder) {

try {

camera = Camera.open(); // 打开摄像头

camera.setPreviewDisplay(holder); // 设置用于显示拍照影像的SurfaceHolder对象

camera.setDisplayOrientation(getPreviewDegree(MainActivity.this));

camera.startPreview(); // 开始预览

} catch (Exception e) {

e.printStackTrace();

}

}

// 停止拍照时调用该方法

@Override

public void surfaceDestroyed(SurfaceHolder holder) {

if (camera != null) {

camera.release(); // 释放照相机

camera = null;

}

}

}

/**

  • 点击手机屏幕是,显示两个按钮

*/

@Override

public boolean onTouchEvent(MotionEvent event) {

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:

layout.setVisibility(ViewGroup.VISIBLE); // 设置视图可见

break;

}

return true;

}

@Override

public boolean onKeyDown(int keyCode, KeyEvent event) {

switch (keyCode) {

case KeyEvent.KEYCODE_CAMERA: // 按下拍照按钮

if (camera != null && event.getRepeatCount() == 0) {

// 拍照

//注:调用takePicture()方法进行拍照是传入了一个PictureCallback对象——当程序获取了拍照所得的图片数据之后

//,PictureCallback对象将会被回调,该对象可以负责对相片进行保存或传入网络

camera.takePicture(null, null, new MyPictureCallback());

}

}

return super.onKeyDown(keyCode, event);

}

// 提供一个静态方法,用于根据手机方向获得相机预览画面旋转的角度

public static int getPreviewDegree(Activity activity) {

// 获得手机的方向

int rotation = activity.getWindowManager().getDefaultDisplay()

.getRotation();

int degree = 0;

// 根据手机的方向计算相机预览画面应该选择的角度

switch (rotation) {

case Surface.ROTATION_0:

degree = 90;

break;

case Surface.ROTATION_90:

degree = 0;

break;

case Surface.ROTATION_180:

degree = 270;

break;

case Surface.ROTATION_270:

degree = 180;

break;

}

return degree;

}

}

用来显示图片的Activity:

package com.wwj.finger;

import android.app.Activity;

import android.content.Intent;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.graphics.Matrix;

import android.os.Bundle;

import android.widget.ImageView;

public class ShowPicActivity extends Activity {

private ImageView ivPic = null; // 显示图片控件

/**

  • Activity在创建的时候回调的函数 主要用来初始化一些变量

*/

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.showpic);

ivPic = (ImageView) findViewById(R.id.ivPic);

setImageBitmap(getImageFormBundle());

}

/**

  • 将MainActivity传过来的图片显示在界面当中

  • @param bytes

*/

public void setImageBitmap(byte[] bytes) {

Bitmap cameraBitmap = byte2Bitmap();

// 根据拍摄的方向旋转图像(纵向拍摄时要需要将图像选择90度)

Matrix matrix = new Matrix();

matrix.setRotate(MainActivity.getPreviewDegree(this));

cameraBitmap = Bitmap

.createBitmap(cameraBitmap, 0, 0, cameraBitmap.getWidth(),

cameraBitmap.getHeight(), matrix, true);

ivPic.setImageBitmap(cameraBitmap);

}

/**

  • 从Bundle对象中获取数据

  • @return

*/

public byte[] getImageFormBundle() {

Intent intent = getIntent();

Bundle data = intent.getExtras();

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助

因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
索成长,自己不成体系的自学效果低效漫长且无助**。

因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

[外链图片转存中…(img-lV9nK21j-1715488092476)]

[外链图片转存中…(img-2l4rkI0V-1715488092478)]

[外链图片转存中…(img-19h0vMmf-1715488092479)]

[外链图片转存中…(img-iIp6qflf-1715488092480)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

  • 16
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值