Android 简易画板

用到的方法
画布Canvas 画笔Paint 路径Path 文件 File 位图 Bitmap 菜单 menu
创建一个Android项目,实现手绘功能的简易画板,并可以储存。
activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <cn.edu.neusfoft.note_drawer.DrawView
        android:id="@+id/drawView1"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</FrameLayout>

添加了一个帧布局管理器,并在帧布局中天机了创建的自定义视图
在xml中写入< DrawView >即可添加布局。
在res目录中,创建一个menu目录,在目录中创建toolsmenu.xml的菜单资源文件,在该文件中编写实例中所应用的功能菜单。

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:title="afa">
        <menu >
            <!--定义一组单选菜单项-->
            <group android:checkableBehavior="single">
            <!--定义子菜单-->
                <item android:id="@+id/red" android:title="color_red"/>

                <item android:id="@+id/green" android:title="color_green"/>

                <item android:id="@+id/blue" android:title="color_blue"/>

            </group>
        </menu>

    </item>

    <item android:title="width">

        <menu >

            <!--定义子菜单-->
            <group>
                <item android:id="@+id/width_1" android:title="width_1"/>
                <item android:id="@+id/width_2" android:title="width_2"/>
                <item android:id="@+id/width_3" android:title="width_3"/>
            </group>
        </menu>
    </item>
    <item android:id="@+id/clear" android:title="clear"/>
    <item android:id="@+id/sava" android:title="save"/>
</menu>

创建一个DrawView的类,该类继承android.view.View类。

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.os.Environment;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.graphics.Path;
import android.widget.Toast;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

public class DrawView extends View {
    /*
    * 首先定义程序中所需的属性,然后添加构造方法
    * 重写onDraw(Canvas canvas)方法
    */
    private int view_width = 0;          //屏幕的宽度
    private int view_height = 0;         //屏幕的高度
    private float preX;                  //起始点的x坐标
    private float preY;                  //起始点的y坐标
    private android.graphics.Path path;                   //路径
    public Paint paint = null;          //画笔
    Bitmap cacheBitmap = null;          //定义一个内存中的图片,该图片作为缓冲区
    Canvas cacheCanvas = null;          //定义cacheBitmap上的Canvas对象
    
    public DrawView(Context context, AttributeSet attrs) {
        super(context,attrs);
        init();

    }
    /*
    * 设置背景颜色,绘制cacheBitmap,绘制路径,保存当前绘图状态到栈中,调用resrore()方法恢复所保存的状态*/
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(0xFFFFFFFF);       //设置背景颜色
        Paint bmpPaint = new Paint();       //采用默认设置创建一个画笔
        canvas.drawBitmap(cacheBitmap,0,0,bmpPaint);        //绘制cacheBitmap
        canvas.drawPath(path,paint);        //绘制路径
        canvas.save();                      //保存canvas的状态
        canvas.restore();                   //回复canvas之前的保存的状态,放置保存后对canvas执行的操作对后续的绘制有影响

    }
    /*
    * 首先获取屏幕的宽度和高度,创建一个与该View相同大小的缓存区,
    * 创建一个新的画面,实例化一个路径,将内存中的位图会知道cacheCanvas中,最后实例化一个画笔,设置画笔的相关属性
    */
    public void init(){
        view_width = getContext().getResources().getDisplayMetrics().widthPixels;       //获取屏幕的宽度
        view_height = getContext().getResources().getDisplayMetrics().heightPixels;     //获取屏幕的高度
        cacheBitmap = Bitmap.createBitmap(view_width,view_height,Bitmap.Config.ARGB_8888);      //创建一个与该View相同大小的缓存区
        cacheCanvas = new Canvas();         //创建一个新的画布
        path = new Path();
        cacheCanvas.setBitmap(cacheBitmap);     //在cacheCanvas上绘制cacheBitmap
        paint = new Paint(Paint.DITHER_FLAG);
        paint.setColor(Color.RED);
       paint.setStyle(Paint.Style.STROKE);              //设置填充方式为表便
       paint.setStrokeJoin(Paint.Join.ROUND);           //设置笔刷的图形样式
       paint.setStrokeCap(Paint.Cap.ROUND);             //设置画笔转弯处的连接风格
       paint.setStrokeWidth(1);                         //设置默认比触的宽度为1像素
       paint.setAntiAlias(true);                        //使用抗锯齿功能
       paint.setDither(true);                           //使用抖动效果

    }
    /*
    * 调用saveBitmap()方法将当前绘图保存为PNG图片*/
    public void savek(){
        try{
            saveBitmap("myPicture");
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }
    /*
    *保存绘制好的位图方法saveBitmap()
    * 首先在SD卡上创建一个文件,然后创建一个文件输出流对象,调用Bitmap类的compress()方法将绘图内容压缩为PNG歌是输出到创建的文件间输出流对象中
    * 最后将缓冲区的数据全部写出到输出流中,关闭文件输出流对象
    *  */
    private void saveBitmap(String fileName)throws IOException {
        String storage = Environment.getExternalStorageDirectory().getPath();
        Toast.makeText(getContext(),storage,Toast.LENGTH_SHORT).show();     //显示得到的储存路径
        File dirFile = new File(storage + "/abcd");         //在storage/emulated/0目录下创建abcd文件夹
        dirFile.mkdir();                                        //创建一个新文件
        File file = new File(dirFile, System.currentTimeMillis() + ".jpg");
        FileOutputStream fileOS = new FileOutputStream(file);                           //创建一个文件输出流对象
        cacheBitmap.compress(Bitmap.CompressFormat.PNG,100,fileOS);             //将绘图内容压缩为PNG格式输出到输出流对象中,PNG为透明图片
        fileOS.flush();                 //将缓冲区中的数据全部写出道输出流中
        fileOS.close();                 //关闭文件输出流对象
    }
    /*
    * clear()方法,实现橡皮擦功能
    * */
    public void clear() {
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));       //设置图形重叠时的处理方式
        paint.setStrokeWidth(50);       //设置笔触的宽度
    }
    /*
    * 重写onTouchEvent()方法,为该视图添加触摸事件监听器,
    * 首先获取触摸事件发生的位置,然后应用switch语句对事件的不同状态添加相应代码,最后调用inalidat()方法更新视图*/
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                path.moveTo(x,y);       //将绘图的起始点一道(x,y)坐标的位置
                preX = x;
                preY = y;
                break;
            case MotionEvent.ACTION_MOVE:
                float dx = Math.abs(x - preX);
                float dy = Math.abs(y - preY);
                //判断是否在允许的范围内
                if(dx>=5||dy>=5) {
                    path.quadTo(preX,preY,(x+preX)/2,(y+preY)/2);
                    preX = x;
                    preY = y;
                }
                break;
            case MotionEvent.ACTION_UP:
                //绘制路径
                cacheCanvas.drawPath(path,paint);
                path.reset();
                break;
        }
        invalidate();
        //返回true表明处理方法已经处理该事务
        return true;
    }
}

MainActivity.java

import android.graphics.Color;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    //创建选项菜单
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = new MenuInflater(this);     //实例化一个MenuInflater对象
        inflater.inflate(R.menu.toolsmenu,menu);        //解析菜单文件
        return super.onCreateOptionsMenu(menu);
    }

    //当菜单项被选择时,做出相应的处理
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        DrawView dv = (DrawView)findViewById(R.id.drawView1);       //获取自定义的绘图视图
        dv.paint.setXfermode(null);                                 //取消擦除效果
        dv.paint.setStrokeWidth(1);                                 //初始化画笔的宽度
        switch (item.getItemId()) {
            case R.id.red:
                dv.paint.setColor(Color.RED);
                item.setChecked(true);
                break;
            case R.id.green:
                dv.paint.setColor(Color.GREEN);
                item.setChecked(true);
                break;
            case R.id.blue:
                dv.paint.setColor(Color.GREEN);
                item.setChecked(true);
                break;
            case R.id.width_1:
                dv.paint.setStrokeWidth(1);
                break;
            case R.id.width_2:
                dv.paint.setStrokeWidth(2);
                break;
            case R.id.width_3:
                dv.paint.setStrokeWidth(3);
                break;
            case R.id.clear:
                dv.clear();
                break;
            case R.id.sava:
                dv.savek();
                break;
        }
        return true;
    }
}

需要在SD卡保存文件,添加权限

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

简易画板图片

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值