Android手绘手写图DrawableView
Android上的第三方开源DrawableView支持手写,类似于写字板。DrawableView支持改变画笔颜色,画笔线条粗细,画布的手势缩放和拖曳显示部分区域。并最终支持将手绘的图保存到本地。
在github上的项目主页:https://github.com/PaNaVTEC/DrawableView
先把布局文件中写一个DrawableView:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<Button
android:id="@+id/strokeWidthPlusButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="画笔宽度+" />
<Button
android:id="@+id/strokeWidthMinusButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="画笔宽度-" />
<Button
android:id="@+id/changeColorButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="画笔颜色" />
<Button
android:id="@+id/undoButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="撤销上一步" />
<Button
android:id="@+id/saveButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="保存成图片" />
</LinearLayout>
<me.panavtec.drawableview.DrawableView
android:id="@+id/paintView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Java代码:
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Random;
import me.panavtec.drawableview.DrawableView;
import me.panavtec.drawableview.DrawableViewConfig;
public class MainActivity extends Activity {
private DrawableView drawableView;
private DrawableViewConfig config = new DrawableViewConfig();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
drawableView = (DrawableView) findViewById(R.id.paintView);
// 画笔宽度-
Button strokeWidthMinusButton = (Button) findViewById(R.id.strokeWidthMinusButton);
// 画笔宽度+
Button strokeWidthPlusButton = (Button) findViewById(R.id.strokeWidthPlusButton);
// 改变画笔颜色
Button changeColorButton = (Button) findViewById(R.id.changeColorButton);
// 撤销上一步绘画操作
Button undoButton = (Button) findViewById(R.id.undoButton);
Button saveButton = (Button) findViewById(R.id.saveButton);
// 画笔颜色
config.setStrokeColor(Color.RED);
// 画布边界
config.setShowCanvasBounds(true);
// 设置画笔宽度
config.setStrokeWidth(10.0f);
// 缩放
config.setMinZoom(1.0f);
config.setMaxZoom(3.0f);
// 高和宽
config.setCanvasHeight(500);
config.setCanvasWidth(700);
drawableView.setConfig(config);
strokeWidthPlusButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 增宽则每次增加10
config.setStrokeWidth(config.getStrokeWidth() + 10);
}
});
strokeWidthMinusButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 减宽则每次减小10
config.setStrokeWidth(config.getStrokeWidth() - 10);
}
});
changeColorButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 测试期间,随机生成一些颜色
Random random = new Random();
config.setStrokeColor(Color.argb(255, random.nextInt(256), random.nextInt(256), random.nextInt(256)));
}
});
undoButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
drawableView.undo();
}
});
saveButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
saveBitmapToSDCard();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
// 将用户手绘的DrawableView转化为图片保存到本地系统默认的图片库中。
private void saveBitmapToSDCard() throws IOException {
// 从DrawableView获得Bitmap
Bitmap bmp = drawableView.obtainBitmap();
File parent_path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File f = new File(parent_path.getAbsoluteFile(), "myDrawableView.png");
f.createNewFile();
Log.d("保存图片的路径", f.getAbsolutePath());
FileOutputStream fos = new FileOutputStream(f);
bmp.compress(Bitmap.CompressFormat.PNG, 100, fos);
fos.flush();
fos.close();
Log.d("保存图片", "成功");
}
}
运行结果如图:
默认的,在未发布的debug阶段,DrawableView会在画布上添加一些log日志输出。如果不打算在画布中显示log,可以修改DrawableView的源代码去掉DrawableView默认的log日志。关键代码有两行,在CanvasDrawer的库文件源代码中:
initLogger();
...
canvasLogger.log(canvas, canvasRect, viewRect, scaleFactor);
将这两行注释掉即可,如图:
附录参考文章:
【文章1】《Android写文件到SDCard的一般过程和代码》链接地址:http://blog.csdn.net/zhangphil/article/details/49976687
【文章2】《Android View转换成图片保存》链接地址:http://blog.csdn.net/zhangphil/article/details/44217539