涂鸦|绘制|draw|paint|view的绘制|undo|redo|恢复|撤销|保存
2016-04-07 16:12
417 查看
xml
java
screenshot
<com.cinread.note.view.DrawView android:id="@+id/paintView" android:layout_width="match_parent" android:layout_height="match_parent"/>
java
package com.cinread.note.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.view.MotionEvent; import android.view.View; import android.view.WindowManager; import com.cinread.note.utils.FileUtils; import com.cinread.note.utils.LogUtils; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.InputStream; import java.util.ArrayList; /** * @project:Note * @package:com.cinread.note.view * @author:pengjf * @update:2016/4/7 * @desc: TODO */ // Created by pengjf on 2016/4/7. public class DrawView extends View { private static final float TOUCH_TOLERANCE = 4; //thumb width private boolean isPaint = true; private Bitmap mBitmapInit; private Bitmap mBitmap; private Paint mPaint; private Paint mErase; private Paint mBitmapPaint; private Canvas mCanvas; private Path mPath; private float mX; private float mY; private int mWidth; private int mHeight; private ArrayList<Path> paths = new ArrayList<Path>(); private ArrayList<Path> undonePaths = new ArrayList<Path>(); public DrawView(Context context) { this(context, null); } public DrawView(Context context, AttributeSet attrs) { super(context, attrs); mPaint = new Paint(); mErase = new Paint(); initPaint(2); initErase(); WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); mWidth = manager.getDefaultDisplay().getWidth(); mHeight = manager.getDefaultDisplay().getHeight(); mBitmap = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888); mCanvas = new Canvas(mBitmap); mPath = new Path(); mBitmapPaint = new Paint(Paint.DITHER_FLAG); } private void initPaint(int width) { mPaint.setDither(true); mPaint.setAntiAlias(true); mPaint.setStrokeWidth(width); mPaint.setColor(Color.BLACK); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeJoin(Paint.Join.ROUND); mPaint.setStrokeCap(Paint.Cap.ROUND); } private void initErase() { mErase.setAntiAlias(true); mErase.setDither(true); mErase.setStrokeWidth(20); mErase.setColor(0xFFFFFFFF); mErase.setStyle(Paint.Style.STROKE); mErase.setStrokeJoin(Paint.Join.ROUND); mErase.setStrokeCap(Paint.Cap.ROUND); mErase.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint); if (isPaint) { for (Path p : paths) { canvas.drawPath(p, mPaint); LogUtils.d(" - -- - "); } //canvas.drawPath(mPath, mPaint); } else canvas.drawPoint(10, 10, mErase); } @Override public boolean onTouchEvent(MotionEvent event) { float x = event.getX(); float y = event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: Touch_Down(x, y); break; case MotionEvent.ACTION_MOVE: Touch_Move(x, y); break; case MotionEvent.ACTION_UP: if (isPaint) Touch_Up(mPaint); else Touch_Up(mErase); break; } invalidate(); return true; } private void Touch_Down(float x, float y) { mPath.reset(); mPath.moveTo(x, y); mX = x; mY = y; } private void Touch_Move(float x, float y) { float dx = Math.abs(x - mX); float dy = Math.abs(y - mY); if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) { mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2); mX = x; mY = y; } } private void Touch_Up(Paint paint) { mPath.lineTo(mX, mY); mCanvas.drawPath(mPath, paint); mPath = new Path(); paths.add(mPath); mPath.reset(); } public void undo() { if (paths.size() > 0) { LogUtils.d("undo " + paths.size()); clearDraw(); undonePaths.add(paths.remove(paths.size() - 1)); invalidate(); } } public void redo() { if (undonePaths.size() > 0) { LogUtils.d("redo " + undonePaths.size()); clearDraw(); paths.add(undonePaths.remove(undonePaths.size() - 1)); invalidate(); } } public void setPaint(int width) { isPaint = true; initPaint(width); invalidate(); } public void setErase() { isPaint = false; initErase(); invalidate(); } public void setBitmap(String url) { InputStream is = null; try { is = new FileInputStream(url); mBitmapInit = BitmapFactory.decodeStream(is); drawBitmapToCanvas(mBitmapInit); } catch (FileNotFoundException e) { e.printStackTrace(); } finally { FileUtils.close(is); } invalidate(); } public void clearDraw() { mBitmap = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888); mCanvas.setBitmap(mBitmap); invalidate(); } public void clear() { paths.clear(); undonePaths.clear(); invalidate(); } private void drawBitmapToCanvas(Bitmap bitmap) { if (bitmap.getHeight() > mHeight || bitmap.getWidth() > mWidth) { RectF rectF = new RectF(0, 0, mWidth, mHeight); mCanvas.drawBitmap(bitmap, null, rectF, mBitmapPaint); } else { mCanvas.drawBitmap(bitmap, 0, 0, mBitmapPaint); } } public void BitmapToPicture(File file, Bitmap bitmap) { FileOutputStream fos = null; try { fos = new FileOutputStream(file); if (null != fos) { bitmap.compress(Bitmap.CompressFormat.PNG, 10, fos); fos.flush(); } } catch (Exception e) { e.printStackTrace(); } finally { FileUtils.close(fos); } } }
screenshot
相关文章推荐
- apt-get couldn't be verified because the public key is not available: NO_PUBKEY XXX
- 7.5 mail_copy函数:向文件系统写入邮件
- 7.4 deliver_mailbox_file函数:以mbox格式接收邮件
- 7.4 deliver_mailbox_file函数:以mbox格式接收邮件
- 7.3 deliver_maildir函数:以Maildir格式接收邮件
- Ehcache项目启动时报Update check failed异常的解决方法
- 6.6 移信和 fairness策略
- 6.3.3 sendmail的别名文件和.forward文件
- RAID阵列的迁移
- LeetCode(31)-Factorial Trailing Zeroes
- LeetCode(31)-Factorial Trailing Zeroes
- LeetCode(31)-Factorial Trailing Zeroes
- 关于快速报错fail-fast想说的之fail-fast的避免方法(二)
- com.alibaba.dubbo.rpc.RpcException: Failed to invoke the method 错误处理
- Postfix-2.11+Dovecot-2.0.9+MySQL+Nginx+Cyrus-sasl+Extmail-1.2实现基于虚拟用户的邮件系统架构
- JetBrains Makes its Products Free for Students(JetBrains 对学生免费了)
- zz:Unable to open log device ‘/dev/log/main’: No such file or directory
- 百度地图(BaiduMap)定位工具类封装和使用
- postgres error : failed to read kind from backend
- 4.4.1 single_server_main函数:single_server执行模板“主函数”