当前位置: 移动技术网 > IT编程>移动开发>Android > Android开发仿扫一扫实现拍摄框内的照片功能

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

2019年07月24日  | 移动技术网IT编程  | 我要评论

白塔山,文冠果苗木价格,生物质颗粒机定制方案

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

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

先上效果图:

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

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

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

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

第二步:设置半透明边框

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

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

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

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

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

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

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开发仿扫一扫实现拍摄框内的照片功能 ,希望对大家有所帮助

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网