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