Android扫描名片的动画以及剪裁扫描框的图片

2024-09-07 12:48

本文主要是介绍Android扫描名片的动画以及剪裁扫描框的图片,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

参考代码:https://github.com/smartown/CertificateCamera

本文章在上述参考代码的基础上进行修改,用到的SurfaceView是链接代码里的CameraPreview,不过本人比较懒,直接加入相机连续对焦模式代替点击屏幕对焦   ,在CameraPreview中添加

parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);// 连续对焦模式

即可。

布局文件:

主要是用半透明的view将中间的扫描框包围其起来

代码如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:background="#000"><com.view.CameraPreviewandroid:id="@+id/camera_surface"android:layout_width="match_parent"android:layout_height="match_parent" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"android:orientation="vertical"><Viewandroid:id="@+id/viewtop"android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"android:background="@color/preview_mock" /><!--android:background="#5e9" />--><!--android:background="@color/preview_mock" />--><LinearLayoutandroid:id="@+id/camera_crop_container"android:layout_width="0dp"android:layout_height="0dp"android:orientation="horizontal"><Viewandroid:id="@+id/viewleft"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"android:background="@color/preview_mock" /><RelativeLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"><ImageViewandroid:id="@+id/camera_crop"android:layout_width="0dp"android:layout_height="0dp"android:scaleType="fitXY" /><ImageViewandroid:id="@+id/iv_scan_line"android:layout_width="200dp"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:layout_centerHorizontal="true"android:maxHeight="250dp"android:src="@mipmap/face_scan_line"android:visibility="gone"/></RelativeLayout><RelativeLayoutandroid:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"android:background="@color/preview_mock"><Viewandroid:id="@+id/viewright"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"/></RelativeLayout></LinearLayout></LinearLayout><TextViewandroid:id="@+id/tv_picture"android:layout_width="match_parent"android:layout_height="136dp"android:layout_gravity="right"android:gravity="center"android:text="拍照"android:textColor="@color/c_white"android:background="@color/preview_mock"/></LinearLayout><!-- 顶部 --><include layout="@layout/toolbar_right"/><com.view.RotateTextViewandroid:id="@+id/rtv_scaning"android:layout_width="wrap_content"android:layout_height="match_parent"android:textSize="@dimen/sp_14"android:textColor="@color/c_B5B5B5"android:layout_alignParentRight="true"android:gravity="center_vertical"android:layout_centerVertical="true"android:visibility="gone"android:text="识别中"/></RelativeLayout>

在activity中我的改动比较大,由于我只扫描名片不涉及到横屏竖屏切换,所以页面强制竖屏,初始化代码如下,关于权限申请本文章不进行展示了,

private void init() {//获取屏幕最小边,设置为cameraSurface较窄的一边float screenMinSize = Math.min(getResources().getDisplayMetrics().widthPixels, getResources().getDisplayMetrics().heightPixels);//根据screenMinSize,计算出cameraSurface的较宽的一边,长宽比为标准的16:9float maxSize = screenMinSize / 9.0f * 16.0f;RelativeLayout.LayoutParams layoutParams;layoutParams = new RelativeLayout.LayoutParams((int) screenMinSize, (int) maxSize);layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT);cameraSurface.setLayoutParams(layoutParams);float width = (int) (screenMinSize * 0.65);float height = (int) (width * 43.0f / 30.0f);LinearLayout.LayoutParams containerParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, (int) height);RelativeLayout.LayoutParams cropParams = new RelativeLayout.LayoutParams((int) width, (int) height);containerView.setLayoutParams(containerParams);cropView.setLayoutParams(cropParams);cropView.setImageResource(R.mipmap.face_scan_rect_blue);ivScanLine.setMaxHeight(cropView.getHeight());Display defaultDisplay = getWindowManager().getDefaultDisplay();Point point = new Point();defaultDisplay.getSize(point);int x = point.x;int y = point.y;Log.i(TAG, "x = " + x + ",y = " + y);}

点击拍照后的处理,主要是剪裁与扫描框相同大小的区域:

 cameraSurface.takePhoto(new Camera.PictureCallback() {@Overridepublic void onPictureTaken(final byte[] data, Camera camera) {camera.stopPreview();ivScanLine.setVisibility(View.VISIBLE);rtvScaning.setVisibility(View.VISIBLE);//子线程处理图片,防止ANRnew Thread(new Runnable() {@Overridepublic void run() {try {File originalFile = getOriginalFile();FileOutputStream originalFileOutputStream = new FileOutputStream(originalFile);originalFileOutputStream.write(data);originalFileOutputStream.close();Bitmap bitmap = BitmapFactory.decodeFile(originalFile.getPath());//计算裁剪位置float left, top, right, bottom;left = ((float) containerView.getLeft() - (float) cameraSurface.getLeft()) / (float) cameraSurface.getWidth();top = (float) cropView.getTop() / (float) cameraSurface.getHeight();right = (float) containerView.getRight() / (float) cameraSurface.getWidth();bottom = (float) cropView.getBottom() / (float) cameraSurface.getHeight();//裁剪及保存到文件int w = cropView.getMeasuredWidth();int h = cropView.getMeasuredHeight();cropView.getLocationOnScreen(location);// 获取状态栏高度Rect frame = new Rect();ScanCardActivity.this.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);int statusBarHeight = frame.top;System.out.println(statusBarHeight);Bitmap cropBitmap;//判断照片是横屏还是竖屏if ( bitmap.getWidth()> bitmap.getHeight()){int  lx;if (Utils.checkDeviceHasNavigationBar2(ScanCardActivity.this)){lx =viewtop.getHeight()-statusBarHeight+NavUtils.getNavigationBarHeight(ScanCardActivity.this);}else{lx=viewtop.getHeight()-statusBarHeight;}int   ly=bitmap.getHeight()- cropView.getWidth()-viewleft.getWidth();//判断剪裁范围是否超出照片范围if ((lx+cropView.getHeight())>bitmap.getWidth()||(ly+cropView.getWidth())>bitmap.getHeight()){cropBitmap=bitmap;}else{cropBitmap = Bitmap.createBitmap(bitmap,(int) lx,(int) ly,(int) cropView.getHeight(),(int) cropView.getWidth());}}else{int lx2;if (Utils.checkDeviceHasNavigationBar2(ScanCardActivity.this)){lx2=viewtop.getHeight()-statusBarHeight+NavUtils.getNavigationBarHeight(ScanCardActivity.this);}else{lx2=viewtop.getHeight()-statusBarHeight;}//判断剪裁范围是否超出照片范围if ((viewleft.getWidth()+w)>bitmap.getWidth()||(lx2+h)>bitmap.getHeight()){cropBitmap=bitmap;}else{cropBitmap = Bitmap.createBitmap(bitmap,(int) viewleft.getWidth(),(int)lx2,(int)  w,(int)h);}}final File cropFile = getCropFile();BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(cropFile));cropBitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);bos.flush();bos.close();Handler mainHandler = new Handler(Looper.getMainLooper());mainHandler.post(new Runnable() {@Overridepublic void run() {//已在主线程中,可以更新UIpostImageCard(cropFile);}});runOnUiThread(new Runnable() {@Overridepublic void run() {
//                                        resultView.setVisibility(View.VISIBLE);}});return;} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}runOnUiThread(new Runnable() {@Overridepublic void run() {
//                                optionView.setVisibility(View.VISIBLE);cameraSurface.setEnabled(true);}});}}).start();Loger.debug("Bitmap  containerView.getWidth()  :  " + containerView.getWidth());Loger.debug("Bitmap  containerView.getHeight()  :  " + containerView.getHeight());TranslateAnimation translateAni = new TranslateAnimation(//X轴初始位置Animation.ABSOLUTE, 0.0f,//X轴移动的结束位置Animation.ABSOLUTE, 0.0f,//y轴开始位置Animation.ABSOLUTE, 0.0f,//y轴移动后的结束位置Animation.ABSOLUTE, containerView.getHeight());//                Animation.RELATIVE_TO_PARENT,  containerView.getX(), Animation.RELATIVE_TO_PARENT,
//                        containerView.getX()+containerView.getWidth(), Animation.RELATIVE_TO_PARENT, containerView.getY(),
//                        Animation.RELATIVE_TO_PARENT, containerView.getY()//                );//设置动画执行的时间,单位是毫秒translateAni.setDuration(3000);// 设置动画重复次数// -1或者Animation.INFINITE表示无限重复,正数表示重复次数,0表示不重复只播放一次translateAni.setRepeatCount(10);// 设置动画模式(Animation.REVERSE设置循环反转播放动画,Animation.RESTART每次都从头开始)translateAni.setRepeatMode(Animation.REVERSE);translateAni.setAnimationListener(new Animation.AnimationListener() {@Overridepublic void onAnimationStart(Animation animation) {}@Overridepublic void onAnimationEnd(Animation animation) {ivScanLine.setVisibility(View.GONE);}@Overridepublic void onAnimationRepeat(Animation animation) {}});// 启动动画ivScanLine.startAnimation(translateAni);}});

主要修改就是剪裁图片的时候,要区别拍照后是横向图片还是竖向照片,然后为了防止有没有测试到的情况直接检测裁剪的范围是否超过了原图,加入了长宽与原图的判断,在最后运行扫描条来回移动的动画。

基本的修改就这些了,最后在handler中放入获取剪裁图片后的下一步处理。

本文暂时用于自己日后参考,可能会有些代码不全的地方

 

 

 

这篇关于Android扫描名片的动画以及剪裁扫描框的图片的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1145105

相关文章

Android使用ImageView.ScaleType实现图片的缩放与裁剪功能

《Android使用ImageView.ScaleType实现图片的缩放与裁剪功能》ImageView是最常用的控件之一,它用于展示各种类型的图片,为了能够根据需求调整图片的显示效果,Android提... 目录什么是 ImageView.ScaleType?FIT_XYFIT_STARTFIT_CENTE

关于MongoDB图片URL存储异常问题以及解决

《关于MongoDB图片URL存储异常问题以及解决》:本文主要介绍关于MongoDB图片URL存储异常问题以及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录MongoDB图片URL存储异常问题项目场景问题描述原因分析解决方案预防措施js总结MongoDB图

python实现svg图片转换为png和gif

《python实现svg图片转换为png和gif》这篇文章主要为大家详细介绍了python如何实现将svg图片格式转换为png和gif,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录python实现svg图片转换为png和gifpython实现图片格式之间的相互转换延展:基于Py

使用Python从PPT文档中提取图片和图片信息(如坐标、宽度和高度等)

《使用Python从PPT文档中提取图片和图片信息(如坐标、宽度和高度等)》PPT是一种高效的信息展示工具,广泛应用于教育、商务和设计等多个领域,PPT文档中常常包含丰富的图片内容,这些图片不仅提升了... 目录一、引言二、环境与工具三、python 提取PPT背景图片3.1 提取幻灯片背景图片3.2 提取

Python实现图片分割的多种方法总结

《Python实现图片分割的多种方法总结》图片分割是图像处理中的一个重要任务,它的目标是将图像划分为多个区域或者对象,本文为大家整理了一些常用的分割方法,大家可以根据需求自行选择... 目录1. 基于传统图像处理的分割方法(1) 使用固定阈值分割图片(2) 自适应阈值分割(3) 使用图像边缘检测分割(4)

Android实现在线预览office文档的示例详解

《Android实现在线预览office文档的示例详解》在移动端展示在线Office文档(如Word、Excel、PPT)是一项常见需求,这篇文章为大家重点介绍了两种方案的实现方法,希望对大家有一定的... 目录一、项目概述二、相关技术知识三、实现思路3.1 方案一:WebView + Office Onl

Android实现两台手机屏幕共享和远程控制功能

《Android实现两台手机屏幕共享和远程控制功能》在远程协助、在线教学、技术支持等多种场景下,实时获得另一部移动设备的屏幕画面,并对其进行操作,具有极高的应用价值,本项目旨在实现两台Android手... 目录一、项目概述二、相关知识2.1 MediaProjection API2.2 Socket 网络

Android实现悬浮按钮功能

《Android实现悬浮按钮功能》在很多场景中,我们希望在应用或系统任意界面上都能看到一个小的“悬浮按钮”(FloatingButton),用来快速启动工具、展示未读信息或快捷操作,所以本文给大家介绍... 目录一、项目概述二、相关技术知识三、实现思路四、整合代码4.1 Java 代码(MainActivi

C#实现将Excel表格转换为图片(JPG/ PNG)

《C#实现将Excel表格转换为图片(JPG/PNG)》Excel表格可能会因为不同设备或字体缺失等问题,导致格式错乱或数据显示异常,转换为图片后,能确保数据的排版等保持一致,下面我们看看如何使用C... 目录通过C# 转换Excel工作表到图片通过C# 转换指定单元格区域到图片知识扩展C# 将 Excel

Android Mainline基础简介

《AndroidMainline基础简介》AndroidMainline是通过模块化更新Android核心组件的框架,可能提高安全性,本文给大家介绍AndroidMainline基础简介,感兴趣的朋... 目录关键要点什么是 android Mainline?Android Mainline 的工作原理关键