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开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!