200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > Android 自定义view 图片编辑(画圆 画长方形 手势缩放)

Android 自定义view 图片编辑(画圆 画长方形 手势缩放)

时间:2020-02-07 23:02:47

相关推荐

Android 自定义view 图片编辑(画圆 画长方形 手势缩放)

Android 自定义view 图片编辑(画圆,画长方形,手势缩放)

package com.bridgetek.yqm.view;

import android.annotation.SuppressLint;

import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Matrix;

import android.graphics.Paint;

import android.graphics.PaintFlagsDrawFilter;

import android.graphics.Path;

import android.graphics.PointF;

import android.graphics.RectF;

import android.os.Environment;

import android.os.Handler;

import android.os.Message;

import android.text.Layout;

import android.text.StaticLayout;

import android.text.TextPaint;

import android.util.AttributeSet;

import android.util.DisplayMetrics;

import android.view.MotionEvent;

import android.widget.ImageView;

import com.bridgetek.yqm.R;

import java.io.FileOutputStream;

import java.io.IOException;

import java.util.ArrayList;

import java.util.List;

@SuppressLint(“AppCompatCustomView”)

public class GraffitiView extends ImageView {

private List list = new ArrayList<>(); //保存每次修改后图片,回撤使用

private Paint paint; //画笔

private Bitmap originalBitmap; //源图

private Bitmap newBitmap;

private Bitmap finalBitmap; //最终保存时的图片

private Bitmap finalOvalBitmap;

private Bitmap finalRectBitmap;

private Bitmap finalArrowBitmap;

private Bitmap finalTextBitmap;

private float clickX = 0; //触摸时的x坐标private float clickY = 0; //触摸时的y坐标private float startX = 0; //每次绘制起点的x坐标private float startY = 0; //每次绘制起点的y坐标private boolean isEdit = false; //是否允许对图片进行编辑private boolean isMove = true; //是否进行绘制private boolean isClear = false; //是否进行清空private int drawType = 2; //绘制类型:0---线条;1---圆;2---矩形;3---箭头;4---文字private String text;private int color = Color.RED; //画笔颜色private float strokeWidth = 4.0f; //涂鸦线条的宽度private int textSize = 18; //字体大小private int textColor = getResources().getColor(R.color.colorPrimary); //文字颜色private int mScreenWidth;private int mScreenHeight;private String filePath;//原始图像矩阵private Matrix mMatrix=new Matrix();//过程图像矩阵private Matrix mSavedMatrix=new Matrix();//结果图像矩阵private Matrix mResultMatrix=new Matrix();//定义三种模式:None、Drag、Zoompublic static final int Mode_None=0;public static final int Mode_Drag=1;public static final int Mode_Zoom=2;//当前操作模式private int mMode=Mode_None;//当前坐标private float mDownX,mDownY;//存储两点间的距离private float mDistance=0f;//存储中点private PointF mPoint;float mScale=0f;public GraffitiView(Context context, AttributeSet attrs) {super(context, attrs);}public void setFilePath(String filePath) {this.filePath = filePath;//根据原位图的大小创建一个新位图,得到的位图是可变的DisplayMetrics dm = getResources().getDisplayMetrics();originalBitmap = BitmapFactory.decodeFile(filePath).copy(Bitmap.Config.ARGB_8888, true);mScreenWidth = dm.widthPixels;int width = originalBitmap.getWidth();double proportion = mScreenWidth / (double) width;mScreenHeight = (int) (originalBitmap.getHeight() * proportion);// new1Bitmap = Bitmap.createBitmap(originalBitmap); //得到一个不可变位图//finalBitmap = Bitmap.createScaledBitmap(originalBitmap, mScreenWidth, mScreenHeight, true);finalBitmap = Bitmap.createScaledBitmap(originalBitmap, mScreenWidth, mScreenHeight, true);list.add(finalBitmap);setImageBitmap(finalBitmap);mMatrix=new Matrix();}@Overrideprotected void onDraw(Canvas canvas) {//消除图像锯齿canvas.setDrawFilter(new PaintFlagsDrawFilter(0,Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG));canvas.save();switch (drawType) {case 0:canvas.drawBitmap(handWriting(), mMatrix, null);break;case 1:canvas.drawBitmap(drawOval(), mMatrix, null);break;case 2:canvas.drawBitmap(drawRect(), mMatrix, null);break;case 3:canvas.drawBitmap(drawArrow(), mMatrix, null);break;case 4:canvas.drawBitmap(writeText(), mMatrix, null);break;}canvas.restore();}/*** 画线条** @return*/public Bitmap handWriting() {if (isClear) {isClear = false;finalBitmap = newBitmap;return finalBitmap;} else {Bitmap bitmap = Bitmap.createScaledBitmap(finalBitmap, mScreenWidth, mScreenHeight, true);Canvas canvas = new Canvas(bitmap);paint = new Paint();paint.setStyle(Paint.Style.STROKE);paint.setAntiAlias(true);paint.setColor(color);paint.setStrokeWidth(strokeWidth);if (isMove) { //当移动时绘制canvas.drawLine(startX, startY, clickX, clickY, paint); //在画布上画线(通过起点、终点和画笔)}//起点需要不断变化,否则画出来的不是线而是面,因为起点一直不变startX = clickX;startY = clickY;finalBitmap = bitmap;return finalBitmap;}}/*** 画椭圆(包括圆,圆是一种特殊的椭圆)** @return*/public Bitmap drawOval() {if (mMode==Mode_Zoom) {return finalBitmap;}if (isClear) {isClear = false;finalBitmap = newBitmap;return finalBitmap;} else {Bitmap bitmap = Bitmap.createScaledBitmap(finalBitmap, mScreenWidth, mScreenHeight, true);Canvas canvas = new Canvas(bitmap);paint = new Paint();paint.setStyle(Paint.Style.STROKE);paint.setAntiAlias(true);paint.setColor(color);paint.setStrokeWidth(strokeWidth);if (isMove) {canvas.drawOval(new RectF(startX, startY, clickX, clickY), paint);}finalOvalBitmap = bitmap;return finalOvalBitmap;}}/*** 画矩形** @return*/public Bitmap drawRect() {if (mMode==Mode_Zoom) {return finalBitmap;}if (isClear) {isClear = false;finalBitmap = newBitmap;return finalBitmap;} else {Bitmap bitmap = Bitmap.createScaledBitmap(finalBitmap, mScreenWidth, mScreenHeight, true);Canvas canvas = new Canvas(bitmap);paint = new Paint();paint.setStyle(Paint.Style.STROKE);paint.setAntiAlias(true);paint.setColor(color);paint.setStrokeWidth(strokeWidth);if (isMove) {canvas.drawRect(startX, startY, clickX, clickY, paint);}finalRectBitmap = bitmap;return finalRectBitmap;}}/*** 画箭头*/public Bitmap drawArrow() {if (isClear) {isClear = false;finalBitmap = newBitmap;return finalBitmap;} else {Bitmap bitmap = Bitmap.createScaledBitmap(finalBitmap, mScreenWidth, mScreenHeight, true);Canvas canvas = new Canvas(bitmap);paint = new Paint();paint.setStyle(Paint.Style.STROKE);paint.setAntiAlias(true);paint.setColor(color);paint.setStrokeWidth(strokeWidth);if (isMove) {drawArrow(startX, startY, clickX, clickY, canvas, paint);}finalArrowBitmap = bitmap;return finalArrowBitmap;}}public void drawArrow(float startX, float startY, float endX, float endY, Canvas canvas, Paint paint) {double H = 10; //箭头高度double L = 6; //底边的一半int x3 = 0;int y3 = 0;int x4 = 0;int y4 = 0;double awrad = Math.atan(L / H); //箭头角度double arraow_len = Math.sqrt(L * L + H * H); //箭头的长度double[] arrXY_1 = rotateVec(endX - startX, endY - startY, awrad, true, arraow_len);double[] arrXY_2 = rotateVec(endX - startX, endY - startY, -awrad, true, arraow_len);double x_3 = endX - arrXY_1[0]; //(x3,y3)是第一端点double y_3 = endY - arrXY_1[1];double x_4 = endX - arrXY_2[0]; //(x4,y4)是第二端点double y_4 = endY - arrXY_2[1];Double X3 = new Double(x_3);x3 = X3.intValue();Double Y3 = new Double(y_3);y3 = Y3.intValue();Double X4 = new Double(x_4);x4 = X4.intValue();Double Y4 = new Double(y_4);y4 = Y4.intValue();//画线canvas.drawLine(startX, startY, endX, endY, paint);Path triangle = new Path();triangle.moveTo(endX, endY);triangle.lineTo(x3, y3);triangle.lineTo(x4, y4);triangle.close();canvas.drawPath(triangle, paint);}public double[] rotateVec(float px, float py, double ang, boolean isChLen, double newLen) {double mathstr[] = new double[2];//矢量旋转函数,参数含义分别是x分量、y分量、旋转角、是否改变长度、新长度double vx = px * Math.cos(ang) - py * Math.sin(ang);double vy = px * Math.sin(ang) + py * Math.cos(ang);if (isChLen) {double d = Math.sqrt(vx * vx + vy * vy);vx = vx / d * newLen;vy = vy / d * newLen;mathstr[0] = vx;mathstr[1] = vy;}return mathstr;}/*** 在图片上写字** @param text*/public void writeTextToBitmap(String text) {drawType = 4;this.text = text;invalidate();}public Bitmap writeText() {if (isClear) {isClear = false;finalBitmap = newBitmap;finalTextBitmap = finalBitmap;return finalBitmap;} else {Bitmap bitmap = Bitmap.createScaledBitmap(finalBitmap, mScreenWidth, mScreenHeight, true);Canvas canvas = new Canvas(bitmap);TextPaint textPaint = new TextPaint();textPaint.setColor(textColor);textPaint.setTextSize(textSize * getResources().getDisplayMetrics().density);textPaint.setAntiAlias(true);StaticLayout staticLayout = new StaticLayout(text, textPaint, mScreenWidth * 3 / 4, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);canvas.translate(clickX, clickY);staticLayout.draw(canvas);finalTextBitmap = bitmap;return finalTextBitmap;}}@Overridepublic boolean onTouchEvent(MotionEvent event) {clickX = event.getX();clickY = event.getY();int action = event.getAction();if (event.getAction() == MotionEvent.ACTION_DOWN) {//当按下并不移动时,刷新并记下按下时的坐标点但不绘制mMode=Mode_Drag;startX = clickX;startY = clickY;isMove = false;invalidate();return true;} else if (event.getAction() == MotionEvent.ACTION_MOVE) {//当移动时,进行绘制,从按下的坐标点起//缩放处理if(mMode==Mode_Zoom){mResultMatrix.set(mSavedMatrix);//获取缩放比率try {mScale=getDistance(event)/mDistance;} catch (Exception e) {}//获取旋转角,这里可以不用//float Angle=getAngle(Event)-mAngle;//以中点为中心,进行缩放mResultMatrix.postScale(mScale, mScale, mPoint.x, mPoint.y);//以中点为中心,进行旋转,这里可以不用//mResultMatrix.postRotate(Angle, mPoint.x, mPoint.y);mMatrix.set(mResultMatrix);} else if (mMode==Mode_Drag){if (isEdit) {isMove = true;}}invalidate();return true;} else if (event.getAction() == MotionEvent.ACTION_UP && mMode == Mode_Drag) {isMove = false;switch (drawType) {case 1:finalBitmap = finalOvalBitmap;break;case 2:finalBitmap = finalRectBitmap;break;case 3:finalBitmap = finalArrowBitmap;break;}list.add(finalBitmap);return true;} else if (MotionEvent.ACTION_POINTER_1_DOWN == event.getAction() || MotionEvent.ACTION_POINTER_2_DOWN == event.getAction() || MotionEvent.ACTION_POINTER_3_DOWN == event.getAction()) {mMode=Mode_Zoom;//获取两点间距离mDistance=getDistance(event);//获取中点mPoint=getMidPoint(event);mSavedMatrix.set(mMatrix);isMove = false;return true;} else if (event.getAction() == MotionEvent.ACTION_POINTER_UP) {mMode = Mode_None;}return super.onTouchEvent(event);}//返回两点间的距离public float getDistance(MotionEvent Event){//计算X的变化量float DeltalX=Event.getX(0)-Event.getX(1);//计算Y的变化量float DeltalY=Event.getY(0)-Event.getY(1);//计算距离return (float)Math.sqrt(DeltalX*DeltalX+DeltalY*DeltalY);}//返回两点的中点public PointF getMidPoint(MotionEvent Event){float X=Event.getX(0)+Event.getX(1);float Y=Event.getY(0)+Event.getY(1);return new PointF(X/2,Y/2);}//获得旋转角public float getAngle(MotionEvent Event){double DeltalX=Event.getX(0)-Event.getX(1);double DeltalY=Event.getY(0)-Event.getY(1);return (float)Math.atan2(DeltalX, DeltalY);}/*** 设置画的类型** @param drawType*/public void setDrawType(int drawType) {if (this.drawType == 4) {finalBitmap = finalTextBitmap;}this.drawType = drawType;}/*** 恢复原图大小*/public void setRestore() {mMatrix = new Matrix();invalidate();}/***设置撤回*/public void setWithdraw() {if (list.size() > 1) {finalBitmap = list.get(list.size() - 2);setImageBitmap(finalBitmap);list.remove(list.size() - 1);}}/*** 设置是否允许对图片进行编辑** @param isEdit*/public void setIdEdit(boolean isEdit) {this.isEdit = isEdit;}/*** 清空*/public void clear() {isClear = true;newBitmap = Bitmap.createScaledBitmap(originalBitmap, mScreenWidth, mScreenHeight, true);invalidate();}/*** 设置画笔颜色** @param color*/public void setColor(int color) {this.color = color;}/*** 设置画笔的宽度** @param strokeWidth*/public void setStyle(float strokeWidth) {this.strokeWidth = strokeWidth;}/*** 设置字体大小** @param textSize*/public void setTextSize(int textSize) {this.textSize = textSize;}/*** 设置字体颜色** @param textColor*/public void setTextColor(int textColor) {this.textColor = textColor;}/*** 保存图片*/public void saveBitmap(Handler handler) {if (drawType == 4) {finalBitmap = finalTextBitmap;}if (!filePath.equals(Environment.getExternalStorageDirectory().getPath() + "/JCamera/image.jpeg")) {int bitmapWidth = originalBitmap.getWidth();int bitmapHeight = originalBitmap.getHeight();finalBitmap = Bitmap.createScaledBitmap(finalBitmap, mScreenWidth, mScreenHeight, true);}FileOutputStream fos = null;try {fos = new FileOutputStream(filePath);press(pressFormat.PNG, 90, fos);fos.flush();} catch (IOException e) {e.printStackTrace();} finally {if (fos != null) {try {fos.close();} catch (IOException e) {e.printStackTrace();}}handler.sendMessage(Message.obtain());}}

}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。