Android图形图像处理:添加涂鸦文字
时间:2019-02-21
本文章向大家介绍Android图形图像处理:添加涂鸦文字,主要包括Android图形图像处理:添加涂鸦文字使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
先看运行效果:
关键的PaintView:
package com.zhangphil;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import java.util.ArrayList;
import java.util.List;
public class PaintView extends View {
public class DrawPath {
Path path;
Paint paint;
}
private Paint paint;
private Path path;
private float downX, downY;
private float tempX, tempY;
private int paintWidth = 10;
private List<DrawPath> drawPathList;
private List<DrawPath> savePathList;
public PaintView(Context context) {
this(context, null);
}
public PaintView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public PaintView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
drawPathList = new ArrayList<>();
savePathList = new ArrayList<>();
initPaint();
}
private void initPaint() {
paint = new Paint();
paint.setAntiAlias(true);
paint.setStrokeWidth(paintWidth);
paint.setStyle(Paint.Style.STROKE);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (drawPathList != null && !drawPathList.isEmpty()) {
for (DrawPath drawPath : drawPathList) {
if (drawPath.path != null) {
canvas.drawPath(drawPath.path, drawPath.paint);
}
}
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
downX = event.getX();
downY = event.getY();
path = new Path();//每次手指下去都是一条新的路径
path.moveTo(downX, downY);
DrawPath drawPath = new DrawPath();
drawPath.paint = paint;
drawPath.path = path;
drawPathList.add(drawPath);
invalidate();
tempX = downX;
tempY = downY;
break;
case MotionEvent.ACTION_MOVE:
float moveX = event.getX();
float moveY = event.getY();
path.quadTo(tempX, tempY, moveX, moveY);
invalidate();
tempX = moveX;
tempY = moveY;
break;
case MotionEvent.ACTION_UP:
initPaint();//每次手指抬起都要重置下画笔,不然画笔会保存了之前的设置什么画笔的属性会引起bug
break;
}
return true;
}
/**
* 撤销功能。
*/
public void undo() {
if (drawPathList != null && drawPathList.size() >= 1) {
savePathList.add(drawPathList.get(drawPathList.size() - 1));
drawPathList.remove(drawPathList.size() - 1);
invalidate();
}
}
/**
* 反撤销功能。重新生效。
*/
public void reundo() {
if (savePathList != null && !savePathList.isEmpty()) {
drawPathList.add(savePathList.get(savePathList.size() - 1));
savePathList.remove(savePathList.size() - 1);
invalidate();
}
}
/**
* 改变画笔颜色。
*
* @param color
*/
public void resetPaintColor(int color) {
paint.setColor(color);
}
/**
* 放大就是改变画笔的宽度。线条变粗。
*/
public void resetPaintWidth() {
paintWidth += 2;
paint.setStrokeWidth(paintWidth);
}
/**
* 橡皮擦功能。
* 原理是把画笔的颜色和view的背景颜色一样就,然后把画笔的宽度变大了,擦除的时候显得擦除范围大点。
*/
public void eraser() {
paint.setColor(Color.WHITE);//这是view背景的颜色
paint.setStrokeWidth(paintWidth + 6);
}
}
剩下的就是使用。写一个xml布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff">
<RelativeLayout
android:id="@+id/rl_left"
android:layout_width="100dp"
android:layout_height="match_parent">
<Button
android:id="@+id/btn_undo"
android:layout_width="match_parent"
android:layout_height="60dp"
android:text="撤销" />
<Button
android:id="@+id/btn_do"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_below="@id/btn_undo"
android:text="反撤销" />
<Button
android:id="@+id/btn_red"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_below="@id/btn_do"
android:text="红色" />
<Button
android:id="@+id/btn_blue"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_below="@id/btn_red"
android:text="蓝色" />
<Button
android:id="@+id/btn_green"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_below="@id/btn_blue"
android:text="绿色" />
<Button
android:id="@+id/btn_scral"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_below="@id/btn_green"
android:text="放大" />
<Button
android:id="@+id/btn_eraser"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_below="@id/btn_scral"
android:text="橡皮擦" />
</RelativeLayout>
<com.zhangphil.PaintView
android:id="@+id/paint_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toRightOf="@id/rl_left" />
</RelativeLayout>
测试的Activity:
package zhangphil.test;
import android.graphics.Color;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import com.zhangphil.PaintView;
public class DrawActivity extends AppCompatActivity implements View.OnClickListener {
private Button btnUndo;
private Button btnDo;
private Button btnRed;
private Button btnBlue;
private Button btnGreen;
private Button btnScral; //放大。
private Button btnEraser; //橡皮擦。
private PaintView paintView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initListener();
}
private void initListener() {
btnUndo.setOnClickListener(this);
btnDo.setOnClickListener(this);
btnRed.setOnClickListener(this);
btnBlue.setOnClickListener(this);
btnGreen.setOnClickListener(this);
btnScral.setOnClickListener(this);
btnEraser.setOnClickListener(this);
}
private void initView() {
paintView = (findViewById(R.id.paint_view));
btnUndo = findViewById(R.id.btn_undo);
btnDo = findViewById(R.id.btn_do);
btnRed = findViewById(R.id.btn_red);
btnBlue = findViewById(R.id.btn_blue);
btnGreen = findViewById(R.id.btn_green);
btnScral = findViewById(R.id.btn_scral);
btnEraser = findViewById(R.id.btn_eraser);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_undo:
paintView.undo();
return;
case R.id.btn_do:
paintView.reundo();
return;
case R.id.btn_red:
paintView.resetPaintColor(Color.RED);
return;
case R.id.btn_green:
paintView.resetPaintColor(Color.GREEN);
return;
case R.id.btn_blue:
paintView.resetPaintColor(Color.BLUE);
return;
case R.id.btn_scral:
paintView.resetPaintWidth();
break;
case R.id.btn_eraser:
paintView.eraser();
break;
}
}
}
- Spring 必知概念(一)
- 如何在EHAB(EntLib)中定义”细粒度”异常策略?
- MVC、MVP以及Model2[下篇]
- Dora.Interception: 一个为.NET Core度身定制的AOP框架
- 为了支持AOP的编程模式,我为.NET Core写了一个轻量级的Interception框架[开源]
- 关于Expression Tree和IL Emit的所谓的"性能差别"
- 采用一个自创的"验证框架"实现对数据实体的验证[扩展篇]
- 采用一个自创的"验证框架"实现对数据实体的验证[改进篇]
- Flash XSS检测脚本的简单实现
- 采用一个自创的"验证框架"实现对数据实体的验证[设计篇]
- 采用一个自创的"验证框架"实现对数据实体的验证[编程篇]
- 谈谈你最熟悉的System.DateTime[上篇]
- 12步轻松搞定Python装饰器
- 实用小工具,教你轻松转化Python通用数据格式
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- Hive小知识之分桶抽样
- CountDownLatch类在性能测试中应用
- 算法集锦(20) | 自动驾驶 | 交通标志识别算法
- 敏捷回归测试
- 算法集锦(21) | 自动驾驶 |汽车转向角控制算法
- Java压缩/解压缩字符串
- 凉经算法题反思 | 单调栈与DP二分法
- 终于有人把Docker讲清楚了!
- 飞天茅台超卖事故:Redis分布式锁请慎用!
- 算法集锦(24) | 自动驾驶 |高速公路行驶路径规划算法
- 【自动驾驶专题】|小白都会玩的自动驾驶算法
- 算法基础(6)| 语音识别DTW算法小讲
- Selenium设置浏览器为手机模式自定义大小
- 如何在Jetson nano上同时编译TensorRT与Paddle Lite框架
- 一文概览无监督聚类算法有多少 | 算法基础(10)