项目介绍——拍照笔记

…衆ロ難τιáo~ 提交于 2020-03-01 11:01:25

拍照笔记

背景

  • 这是我大二修读的智能移动平台应用开发的课程项目,老师要求我们自选题目。我和另一个小组成员发现在平时上课的时候,经常会使用手机对ppt进行拍照来记录一些重要的信息。但是如果你坐在教室两侧的位置,那么照片中的ppt就会是斜着的并且ppt也不会占满整张照片。所以我们就决定做一个拍照笔记应用,这个应用能够对照片中的矩形进行识别、截取、矫正以覆盖原来的照片,并且能够对照片做笔记。
  • 不同于普通的笔记应用,我们开发的这个笔记应用可以在照片的任意位置做笔记(也就是选中照片上的一个点之后,长按就能在标记处做笔记,为了不影响照片的显示笔记的标记点是可以显示和隐藏的),其他的笔记应用一般是在笔记中插入照片而不是在照片上做笔记。

职责

  1. 照片的拍摄、截取与保存
  2. 笔记及笔记本的编辑与保存
  3. 笔记标记所处照片位置的更新与保存
class Mark {
	private int x;
	private int y;
	private String description;
}

class Note {
	private Image image;
	private List<Mark> marks;

	// 依赖于接口而不是具体实现
	// 这样我们在实例化Note的时候就可以传入一个具体实现List接口的类的实例,比如ArrayList或者LinkedList
	public Note(List<Mark> marks){
		this.marks = marks;
	}
}

遇到的问题(Bug)

  1. 当照片的标记过多时,拖动照片会出现闪烁甚至程序崩溃的情况。原因:这是由于将标记点位置的更新放在了子线程中(标记点较多时,更新所有标记点位置的操作比较费时,所以需要放在子线程中),然后直接在子线程中跟新了UI。解决方法:使用Handler,在Handler的post()方法中更新UI
  2. 为什么Android不能在非UI线程中更新UI?首先UI线程并不是线程安全的(更新UI的方法没有加锁,任何子线程均可以调用),所以在子线程中修改UI的话数据容易出错;其次,如果支持子线程修改UI,由此带来的线程同步和线程安全的代价很高。所以Android直接规定不能在子线程中修改UI,简化了设计。

难点

  1. 照片的截取(截取照片的指定区域并矫正为矩形):最开始,我直接调用Android系统自带的裁剪功能来实现,但是发现只能裁剪矩形区域,不能是任意四边形。所以尝试自己实现图片裁剪及矫正功能,让用户自己选定照片的裁剪区域,然后对这个区域进行透视变换将图片矫正。虽然实现了裁剪和矫正的功能,但是每次都需要选定裁剪区域,操作麻烦,而且处理速度较慢。最后我们使用了一个开源的图片裁剪库——SmartCropper,该库基于opencv识别图片中的四边形区域,支持手动调节选区,然后根据所选区域裁剪出选区内的图片,并透视变换矫正成正面图片。
// 设置要裁剪的图片
public viod setImageToCrop(Bitmap bmp){
	setImageBitmap(bmp);
	// 如果开启了自动扫描,那么会调用native方法自动识别四边形区域
	setCropPoints(mAutoScanEnable ? SmartCropper.scan(bmp) : null);
}

// 裁剪图片
public Bitmap crop(Point[] points){
	if(!checkPoints(points)) return null;
	Bitmap bmp = getBitmap();
	// 调用native方法裁剪图片并透视变换矫正成正面图片
	return bmp == null ? null : SmartCropper.crop(bmp, points);
}
  1. opencv是什么?opencv是一个跨平台计算机视觉库,可以运行在Linux、Windows、Android、Mac操作系统上。
  2. 参考 OpenCV Java 实现票据、纸张的四边形边缘检测与提取、摆正
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!