java扫一扫加拍照_Android开发仿扫一扫实现拍摄框内的照片功能

本文介绍了如何在Android应用中实现类似扫一扫的拍摄功能,通过SurfaceView预览并拍照,然后裁剪拍摄框内的图像。主要步骤包括设置相机预览、添加半透明边框、裁剪图片和实现点击对焦。通过简洁的代码实现相机操作和图片处理,降低了实现复杂度。
摘要由CSDN通过智能技术生成

就是仿照现在扫一扫的形式,周围是半透明的遮挡,然后中间是全透明的,拍摄后只截取框内的内容

查了很多博客,实现起来真的太复杂了,本人比较怕麻烦所以在很多地方偷懒了

先上效果图:

70f9293c23e0145fd76456073b3ed583.png

b5498f3c70fac680b13fbcccfa01dc98.png

ecf4b561f6fa4b4a1f22b4601f2f5485.png

第一步:设置照相机预览以及拍照

这是所有步骤的前提,没有预览,用户怎么知道自己拍的什么呢。预览用的是SurfaceView

这篇博文写得已经十分详细了,打开照相机,然后拍照,而且十分简洁!不想别的博客一下就几百行代码不知所云。这篇代码可以复制下去当相机模版使用。

这里遇到一个问题,就是预览的效果是左转90度的,拍出来也是左转90度的,查了很多资料,大家统一的做法就是。在相机预览那里设置右旋90度,拍下的照片再右旋90度,具体的做法我会贴代码

第二步:设置半透明边框

很多博客的做法是绘图呀什么的,太过负责。

其实如果考虑简单点的话,只要在surfaceView上面叠加一层图片就好了,用Framelayout布局

就是背景半透明,中间扣掉

7387406c09146f1fa690bfcda288a0e0.png

第三步:怎么只拍摄框内的图片

这个问题,很多博客都是长篇大论,什么矩阵运算都用上了,虽然很强,但是不想看下去。

拍摄框内的图片,就直接拍完整张照片之后,在照片里面抠图就好了啊。

Bitmap.createBitmap(bitmap,50,250,650,500);

自己算一下透明框大概在什么位置,左上角的坐标是什么,宽和高是什么。用上述函数就可以在原照片抠图了。

第四步:完善一点,加入点击对焦

其实就是在点击事件里面调用对焦函数就行

总的代码:

public class MainActivity extends AppCompatActivity {

private SurfaceView surfaceview;

private Camera camera;

private Button take;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

requestWindowFeature(Window.FEATURE_NO_TITLE); // 没有标题 必须在设置布局之前找到调用

setContentView(R.layout.activity_main);

/*

getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, // 设置全屏显示

WindowManager.LayoutParams.FLAG_FULLSCREEN);

*/

take = (Button)findViewById(R.id.take);

surfaceview = (SurfaceView) findViewById(R.id.surfaceview);

SurfaceHolder holder = surfaceview.getHolder();

holder.setFixedSize(176, 155);// 设置分辨率

holder.setKeepScreenOn(true);

holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

// SurfaceView只有当activity显示到了前台,该控件才会被创建 因此需要监听surfaceview的创建

holder.addCallback(new MySurfaceCallback());

//拍照按钮

take.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View view) {

takepicture();

}

});

}

//点击事件

@Override

public boolean onTouchEvent(MotionEvent event) {

//对焦

camera.autoFocus(new Camera.AutoFocusCallback() {

@Override

public void onAutoFocus(boolean b, Camera camera) {

camera.cancelAutoFocus();

}

});

return super.onTouchEvent(event);

}

/**

* 监听surfaceview的创建

* @author Administrator

* Surfaceview只有当activity显示到前台,该空间才会被创建

*/

private final class MySurfaceCallback implements SurfaceHolder.Callback {

@Override

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

int height) {

// TODO Auto-generated method stub

}

@Override

public void surfaceCreated(SurfaceHolder holder) {

// TODO Auto-generated method stub

try {

// 当surfaceview创建就去打开相机

camera = Camera.open();

Camera.Parameters params = camera.getParameters();

// Log.i("i", params.flatten());

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

params.setPictureSize(1024, 768);

params.setPreviewFrameRate(5); // 预览帧率

camera.setParameters(params); // 将参数设置给相机

//右旋90度,将预览调正

camera.setDisplayOrientation(90);

// 设置预览显示

camera.setPreviewDisplay(surfaceview.getHolder());

// 开启预览

camera.startPreview();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

@Override

public void surfaceDestroyed(SurfaceHolder holder) {

// TODO Auto-generated method stub

if(camera != null){

camera.release();

camera = null;

}

}

}

//拍照的函数

public void takepicture(){

/*

* shutter:快门被按下

* raw:相机所捕获的原始数据

* jpeg:相机处理的数据

*/

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

}

//byte转Bitmap

public Bitmap Bytes2Bimap(byte[] b) {

if (b.length != 0) {

return BitmapFactory.decodeByteArray(b, 0, b.length);

} else {

return null;

}

}

//bitmap转byte

public byte[] Bitmap2Bytes(Bitmap bm) {

ByteArrayOutputStream baos = new ByteArrayOutputStream();

bm.compress(Bitmap.CompressFormat.PNG, 100, baos);

return baos.toByteArray();

}

//照片回调函数,其实是处理照片的

private final class MyPictureCallback implements Camera.PictureCallback {

@Override

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

// TODO Auto-generated method stub

try {

Bitmap bitmap = Bytes2Bimap(data);

Matrix m = new Matrix(); int width = bitmap.getWidth(); int height = bitmap.getHeight(); m.setRotate(90);

//将照片右旋90度

bitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, m,

true);

Log.d("TAG","width "+width);

Log.d("TAG","height "+height);

//截取透明框内照片

bitmap = Bitmap.createBitmap(bitmap,50,250,650,500);

data = Bitmap2Bytes(bitmap);

File file = new File(Environment.getExternalStorageDirectory(),System.currentTimeMillis()+".jpg");

FileOutputStream fos = new FileOutputStream(file);

fos.write(data);

// 在拍照的时候相机是被占用的,拍照之后需要重新预览

camera.startPreview();

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

}

以上所述是小编给大家介绍的Android开发仿扫一扫实现拍摄框内的照片功能 ,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值