700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > android 自定义照相机

android 自定义照相机

时间:2022-10-14 15:30:49

相关推荐

android 自定义照相机

做了一个dome,内容和功能都很简单,当练练手

部分代码参考了一个博客任何自己添加了一些项目的功能,具体那个博客忘记了,不好意思。

具体就是调用系统的摄相机拍照保存到手机,以后返回相片的文件地址

效果图:

照相界面的布局文件:

<SurfaceView android:id="@+id/surfaceView" android:layout_width="match_parent" android:layout_height="match_parent" /> <!-- 相对布局,放置两个按钮 --><RelativeLayoutandroid:id="@+id/buttonLayout"android:layout_width="match_parent"android:layout_height="wrap_content"android:visibility="visible" ><FrameLayoutandroid:id="@+id/fra_shade_top"android:layout_width="match_parent"android:layout_height="150dp"android:layout_alignParentTop="true"android:background="#000000" /><FrameLayoutandroid:id="@+id/fra_shade_bottom"android:layout_width="match_parent"android:layout_height="150dp"android:layout_alignParentBottom="true"android:background="#000000" /><TableLayoutandroid:id="@+id/table1"android:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:padding="4dip"android:stretchColumns="*" ><TableRow><Buttonandroid:id="@+id/bnt_enter"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="确认" /><Buttonandroid:id="@+id/bnt_takepicture"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="拍照" /><Buttonandroid:id="@+id/bnt_cancel"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="5dp"android:text="取消" /></TableRow></TableLayout></RelativeLayout>

其中SurfaceView是用于显示照相机的图像的。

RelativeLayout是相机的遮罩(设定视图的大小,我这里是1:1正方形)

下面是照相机调用和图片保存类:

/*** * 自定义相机控件* * @author Nickey* @date .11.29**/public class MainActivity extends Activity implements OnClickListener{private Button bntTakePic;private Button bntEnter;private Button bntCancel;private SurfaceView surfaceView ;private FrameLayout fraShadeTop;private FrameLayout fraShadeBottom;private Camera camera; private Camera.Parameters parameters = null; private WindowManager mWindowManager;private int windowWidth ;//获取手机屏幕宽度private int windowHight ;//获取手机屏幕高度private String savePath = "/finger/";private Bundle bundle = null;// 声明一个Bundle对象,用来存储数据 private int IS_TOOK = 0;//是否已经拍照 ,0为否@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);init();getActionBar().hide();}@SuppressWarnings("deprecation")private void init(){mWindowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);windowWidth = mWindowManager.getDefaultDisplay().getWidth();windowHight = mWindowManager.getDefaultDisplay().getHeight();fraShadeTop = (FrameLayout)findViewById(R.id.fra_shade_top);fraShadeBottom = (FrameLayout)findViewById(R.id.fra_shade_bottom);RelativeLayout.LayoutParams topParams =(RelativeLayout.LayoutParams) fraShadeTop.getLayoutParams();topParams.width = windowWidth;topParams.height =(windowHight - windowWidth) / 2;fraShadeTop.setLayoutParams(topParams);fraShadeTop.getBackground().setAlpha(200);RelativeLayout.LayoutParams bottomParams =(RelativeLayout.LayoutParams) fraShadeBottom.getLayoutParams();bottomParams.width = windowWidth;bottomParams.height =(windowHight - windowWidth) / 2;fraShadeBottom.setLayoutParams(bottomParams);fraShadeBottom.getBackground().setAlpha(200);//按钮bntTakePic = (Button)findViewById(R.id.bnt_takepicture);bntEnter = (Button)findViewById(R.id.bnt_enter);bntCancel = (Button)findViewById(R.id.bnt_cancel);bntTakePic.setVisibility(View.VISIBLE);bntEnter.setVisibility(View.INVISIBLE);bntCancel.setVisibility(View.INVISIBLE);bntTakePic.setOnClickListener(this);bntEnter.setOnClickListener(this);bntCancel.setOnClickListener(this);//照相机预览的空间surfaceView = (SurfaceView) this.findViewById(R.id.surfaceView);surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);surfaceView.getHolder().setFixedSize(150, 150); // 设置Surface分辨率surfaceView.getHolder().setKeepScreenOn(true);// 屏幕常亮surfaceView.getHolder().addCallback(new SurfaceCallback());// 为SurfaceView的句柄添加一个回调函数}/*** 三个按钮点击事件*/@Overridepublic void onClick(View v) {// TODO Auto-generated method stubswitch (v.getId()) { case R.id.bnt_takepicture: // 拍照 if (camera != null) {camera.takePicture(null, null, new MyPictureCallback()); }break; case R.id.bnt_enter:if (bundle == null) { Toast.makeText(getApplicationContext(), "bundle null", Toast.LENGTH_SHORT).show(); } else { try {if (isHaveSDCard())saveToSDCard(bundle.getByteArray("bytes"));elsesaveToRoot(bundle.getByteArray("bytes"));} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}finish();} break; case R.id.bnt_cancel:bntTakePic.setVisibility(View.VISIBLE);bntCancel.setVisibility(View.INVISIBLE);bntEnter.setVisibility(View.INVISIBLE);if (camera != null) {IS_TOOK = 0;camera.startPreview();}break;} }/*** 检验是否有SD卡* @true or false*/public static boolean isHaveSDCard() {return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState());}/*** 重构照相类* @author **/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(), "success", Toast.LENGTH_SHORT).show(); bntTakePic.setVisibility(View.INVISIBLE);bntCancel.setVisibility(View.VISIBLE);bntEnter.setVisibility(View.VISIBLE);// camera.startPreview(); // 拍完照后,重新开始预览 IS_TOOK = 1;} catch (Exception e) { e.printStackTrace(); } } } /** * 将拍下来的照片存放在SD卡中 * @param data * @throws IOException */ public void saveToSDCard(byte[] data) throws IOException { //剪切为正方形Bitmap b = byteToBitmap(data);Bitmap bitmap = Bitmap.createBitmap(b, 0, 0, windowWidth, windowWidth ); //生成文件Date date = new Date(); SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss"); // 格式化时间 String filename = format.format(date) + ".jpg"; File fileFolder = new File(Environment.getExternalStorageDirectory() + savePath); if (!fileFolder.exists()) { // 如果目录不存在,则创建一个名为"finger"的目录 fileFolder.mkdir(); } File jpgFile = new File(fileFolder, filename); FileOutputStream outputStream = new FileOutputStream(jpgFile); // 文件输出流 press(pressFormat.JPEG, 100, outputStream);outputStream.flush();// out.close();// outputStream.write(data); // 写入sd卡中 outputStream.close(); // 关闭输出流 Intent intent = new Intent();intent.putExtra("path",Environment.getExternalStorageDirectory() + savePath + filename);setResult(1, intent);} /*** */public void saveToRoot(byte[] data) throws IOException { //剪切为正方形Bitmap b = byteToBitmap(data);Bitmap bitmap = Bitmap.createBitmap(b, 0, 0, windowWidth, windowWidth ); //生成文件Date date = new Date(); SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss"); // 格式化时间 String filename = format.format(date) + ".jpg"; File fileFolder = new File(Environment.getRootDirectory() + savePath); if (!fileFolder.exists()) { // 如果目录不存在,则创建一个名为"finger"的目录 fileFolder.mkdir(); } File jpgFile = new File(fileFolder, filename); FileOutputStream outputStream = new FileOutputStream(jpgFile); // 文件输出流 press(pressFormat.JPEG, 100, outputStream);outputStream.flush();// out.close();// outputStream.write(data); // 写入sd卡中 outputStream.close(); // 关闭输出流 Intent intent = new Intent();intent.putExtra("path",Environment.getExternalStorageDirectory() + savePath + filename);setResult(1, intent);} /*** 把图片byte流编程bitmap* @param data* @return*/private Bitmap byteToBitmap(byte[] data){Options options = new BitmapFactory.Options();options.inJustDecodeBounds = true;Bitmap b = BitmapFactory.decodeByteArray(data, 0, data.length,options);int i = 0;while (true) {if ((options.outWidth >> i <= 1000)&& (options.outHeight >> i <= 1000)) {options.inSampleSize = (int) Math.pow(2.0D, i);options.inJustDecodeBounds = false;b = BitmapFactory.decodeByteArray(data, 0, data.length,options);break;}i += 1;}return b;}/*** 重构相机照相回调类* @author pc**/private final class SurfaceCallback implements Callback {@SuppressWarnings("deprecation")@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {// TODO Auto-generated method stubparameters = camera.getParameters(); // 获取各项参数 parameters.setPictureFormat(PixelFormat.JPEG); // 设置图片格式 parameters.setPreviewSize(width, height); // 设置预览大小 parameters.setPreviewFrameRate(5); //设置每秒显示4帧 parameters.setPictureSize(width, height); // 设置保存的图片尺寸 parameters.setJpegQuality(80); // 设置照片质量 // camera.setParameters(parameters);}@Overridepublic void surfaceCreated(SurfaceHolder holder) {// TODO Auto-generated method stubtry { camera = Camera.open(); // 打开摄像头 camera.setPreviewDisplay(holder); // 设置用于显示拍照影像的SurfaceHolder对象 camera.setDisplayOrientation(getPreviewDegree(MainActivity.this)); camera.startPreview(); // 开始预览 } catch (Exception e) { e.printStackTrace(); } }@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {// TODO Auto-generated method stubif (camera != null) { camera.release(); // 释放照相机 camera = null; } } }/*** 物理按键事件*/@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()); } case KeyEvent.KEYCODE_BACK:if (IS_TOOK == 0)finish();else{//camera.startPreview();bntCancel.performClick();return false;}break;} 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; } @Overridepublic 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;}/*** 通过文件地址获取文件的bitmap* @param path* @return* @throws IOException*/public static Bitmap getBitmapByPath(String path) throws IOException {BufferedInputStream in = new BufferedInputStream(new FileInputStream(new File(path)));BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = true;BitmapFactory.decodeStream(in, null, options);in.close();int i = 0;Bitmap bitmap = null;while (true) {if ((options.outWidth >> i <= 1000)&& (options.outHeight >> i <= 1000)) {in = new BufferedInputStream(new FileInputStream(new File(path)));options.inSampleSize = (int) Math.pow(2.0D, i);options.inJustDecodeBounds = false;bitmap = BitmapFactory.decodeStream(in, null, options);break;}i += 1;}return bitmap;}}

具体的使用很简单,就是普通的activity间的调用和回调(startActivityForResult);

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。