canvas 对图片进行涂抹,涂抹区域保存图片存入本地
来源:互联网 发布:分水岭分割算法流程图 编辑:程序博客网 时间:2024/04/29 13:30
今晚写了一个比较有意思的控件 ,也是项目需要,项目做一个OCR的图片识别 ,上午老板提出一个需求 ,增加触摸翻译的功能 。我觉得比较有趣,就画了2个多小时吧这个控件写出来并分享出来,网上搜了一下,目前还没有类似的控件的功能
代码目前考虑的范围不够全面,等我软件优化完了,这里修复一下,给大家看看思路
后来写了一个升级版的,解决屏幕不适配的问题 :
http://blog.csdn.net/fkgjdkblxckvbxbgb/article/details/77801086
先介绍下百度翻译的OCR功能 :
1:拍照,拿到照片,识别里面的文字 ,根据识别的文字进行翻译 。
2:截图翻译,就是根据截取的屏幕内容对内容进行翻译,准确率更高
3:涂抹翻译,比截图翻译更精确,正对性更强
今天要写的就是第三种 涂抹翻译,原理不难 ,
有点类似刮刮卡的功能 ,然后涂抹区域的bitmap进行重绘制保存
先看效果图 ,虚拟机没看不出来效果,需要用真机,因为有用到SD卡读写权限 ,最后返回的是图片的存储路径
我
我的代码都比较容易看懂 ,没有那么多的嵌套封装,注释的很清楚,
package com.reeman.view;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Path;import android.graphics.PorterDuff;import android.graphics.PorterDuffXfermode;import android.graphics.RectF;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.view.View;import com.reeman.view.entity.TouchPoint;import java.io.File;import java.io.FileOutputStream;import java.util.ArrayList;import java.util.Collections;import java.util.List;public class XfermodeView extends View { private Bitmap mBgBitmap; Bitmap mFgBitmap; private Paint mPaint; private Canvas mCanvas; private Path mPath; int FINGER_WIDTH = 40; public XfermodeView(Context context) { this(context, null); } public XfermodeView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public XfermodeView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } @Override protected void onDraw(Canvas canvas) { canvas.drawBitmap(mBgBitmap, 0, 0, null); canvas.drawBitmap(mFgBitmap, 0, 0, null); } private void init() { mPaint = new Paint(); mPaint.setAlpha(0); mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN)); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeJoin(Paint.Join.ROUND); mPaint.setStrokeWidth(80); mPaint.setStrokeCap(Paint.Cap.ROUND); mPath = new Path();// mBgBitmap = BitmapFactory.decodeResource(getResources(), imageId);// mFgBitmap = Bitmap.createBitmap(mBgBitmap.getWidth(), mBgBitmap.getHeight(), Bitmap.Config.ARGB_8888);// mCanvas = new Canvas(mFgBitmap);// mCanvas.drawColor(BLACK_HALF_COLOR); } int BLACK_HALF_COLOR = 0x89000000; float startX, startY, endX, endY; @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: startX = event.getX(); startY = event.getY(); listPoint.clear(); listPoint.add(new TouchPoint(event.getX(), event.getY())); Log.i("point", "====添加的点==" + startX + "/" + startY); mPath.reset(); mPath.moveTo(startX, startY); break; case MotionEvent.ACTION_MOVE: listPoint.add(new TouchPoint(event.getX(), event.getY())); mPath.lineTo(event.getX(), event.getY()); break; case MotionEvent.ACTION_UP: endX = event.getX(); endY = event.getY(); listPoint.add(new TouchPoint(event.getX(), event.getY())); changePoints(); Log.i("point", "====添加的点==" + endX + "/" + endY); break; } mCanvas.drawPath(mPath, mPaint); invalidate(); return true; } List<TouchPoint> listPoint = new ArrayList<>(); List<Float> pointX = new ArrayList<>(); List<Float> pointY = new ArrayList<>(); /*** * 计算手指滑动的区域 */ private void changePoints() { pointX.clear(); pointY.clear(); for (int i = 0; i < listPoint.size(); i++) { pointX.add(listPoint.get(i).getPointX()); pointY.add(listPoint.get(i).getPointY()); } /*** * 这里因为用户会反复的涂抹,所以吧所有的移动点添加到集合中,然后对所有的点取值 * 取出手指的最大范围和最小范围, */ float minX = Collections.min(pointX); float minY = Collections.min(pointY); float maxX = Collections.max(pointX); float maxY = Collections.max(pointY); /*** * 这里加上笔触的宽度 */ minX = minX - FINGER_WIDTH; minY = minY - FINGER_WIDTH; maxX = maxX + FINGER_WIDTH; maxY = maxY + FINGER_WIDTH; if (minX < 0) { minX = 0; } if (minY < 0) { minY = 0; } if (maxX > MainActivity.width) { maxX = MainActivity.width; } if (maxY > MainActivity.height) { maxY = MainActivity.height; } //这是手指绘制的区域 RectF rect = new RectF(minX, minY, maxX, maxY); saveBitmap(rect); } /*** * 保存图片到本地 * @param rect */ private void saveBitmap(RectF rect) { try { Log.i("point", "====保存的尺寸==" + rect.left + "/" + rect.top + " ///" + rect.right + "/" + rect.bottom); Bitmap bmp = Bitmap.createBitmap((int) rect.width(), (int) rect.height(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bmp); canvas.translate(-(rect.left), -(rect.top)); canvas.drawColor(Color.WHITE); canvas.drawBitmap(mBgBitmap, 0, 0, null); canvas.save(Canvas.ALL_SAVE_FLAG); canvas.restore(); File file = new File("/sdcard//test.png"); if (!file.exists()) { file.createNewFile(); } FileOutputStream fos = new FileOutputStream(file.getPath()); bmp.compress(Bitmap.CompressFormat.PNG, 100, fos); fos.close(); listener.touchBackUrl(file.getPath()); } catch (Exception e) { listener.touchCutError(e.toString()); e.printStackTrace(); } } public void translateImage(int imageId) { mBgBitmap = BitmapFactory.decodeResource(getResources(), imageId); mFgBitmap = Bitmap.createBitmap(mBgBitmap.getWidth(), mBgBitmap.getHeight(), Bitmap.Config.ARGB_8888); mCanvas = new Canvas(mFgBitmap); mCanvas.drawColor(BLACK_HALF_COLOR); } TouchCutListener listener; public void setOnTouchCutListener(TouchCutListener listener) { this.listener = listener; } public interface TouchCutListener { // void touchPoint(float left, float top, float right, float bottom); void touchBackUrl(String filePath); void touchCutError(String error); }}
布局代码,切记,用真机看效果,虚拟机看不到效果
<?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" tools:context="com.reeman.view.MainActivity"> <RelativeLayout android:layout_width="match_parent" android:layout_height="150dp" android:background="@color/colorAccent"> <ImageView android:id="@+id/iv_bitma" android:layout_width="300dp" android:layout_height="150dp" /> </RelativeLayout> <com.reeman.view.XfermodeView android:id="@+id/modeview" android:layout_width="300dp" android:layout_height="300dp" android:layout_alignParentBottom="true" android:layout_centerInParent="true" /></RelativeLayout>
主界面代码,为什么要使用真机测试,主界面代码一目了然
package com.reeman.view;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.view.WindowManager;import android.widget.ImageView;public class MainActivity extends AppCompatActivity implements XfermodeView.TouchCutListener { static int width; static int height; XfermodeView modeview; private ImageView iv_bitma; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); WindowManager wm = this.getWindowManager(); width = wm.getDefaultDisplay().getWidth(); height = wm.getDefaultDisplay().getHeight(); setContentView(R.layout.activity_main); iv_bitma = (ImageView) findViewById(R.id.iv_bitma); modeview = (XfermodeView) findViewById(R.id.modeview); modeview.translateImage(R.mipmap.test5); modeview.setOnTouchCutListener(this); } @Override public void touchBackUrl(String filePath) { Bitmap map = BitmapFactory.decodeFile(filePath); iv_bitma.setImageBitmap(map); } @Override public void touchCutError(String error) { }}
阅读全文
0 0
- canvas 对图片进行涂抹,涂抹区域保存图片存入本地
- android 裁剪涂抹区域并保存成图片
- 保存涂抹区域的图片_升级版
- iOS图片处理之涂抹马赛克解析
- 涂抹CANVAS,判断清除完毕执行操作
- H5中实现图片的涂抹擦除--利用jquery.eraser.js插件
- Canvas实现保存图片到本地
- 如何将canvas保存为本地图片
- 使用ueditor进行图片上传、保存、存入数据库
- 利用HTML5d的Canvas绘制签名区域,保存为图片
- 感光蓝油涂抹
- 三思笔记,涂抹ORACLE~~
- 《涂抹MySQL》目录
- 学习PS涂抹工具
- 保存图片感兴趣区域
- 用html5的canvas生成图片并保存到本地
- 将html canvas里的图片保存到本地
- 利用Python3对网易的某个话题进行爬取并保存图片到本地
- 面向接口编程
- 杭电acm—1009 FatMouse' Trade
- Android列表滑动加载实现
- 论文阅读:CopyNet
- UVA 12034:Race (动态规划)
- canvas 对图片进行涂抹,涂抹区域保存图片存入本地
- js的Date和Math的对象
- 第四天总结
- 解题报告:HDU_5909:Tree Cutting 树上FWT
- 日志中不打印异常堆栈
- js 冒泡排序
- React Native移动开发实战-1-React Native的JSX解决方案
- 用模板实现顺序表和带头结点的双向循环链表
- 粘贴版