import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Path; import android.graphics.Rect; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import com.landicorp.android.unionpay.util.TerminalInfo; public class PaintView extends View { private Resources myResources; // 画笔,定义绘制属性 private Paint myPaint; private Paint mBitmapPaint; // 绘制路径 private Path myPath; // 画布及其底层位图 private Bitmap myBitmap; private Canvas myCanvas; private float mX, mY; private static final float TOUCH_TOLERANCE = 4; // 记录宽度和高度 private int mWidth; private int mHeight; public PaintView(Context context) { super(context); } public PaintView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public PaintView(Context context, AttributeSet attrs) { super(context, attrs); } public Bitmap getBitmap() { return myBitmap; } public void recycleBitmap() { if (myBitmap != null && !myBitmap.isRecycled()) { myBitmap.recycle(); myBitmap = null; } } /** * 初始化工作 */ private void initialize() { // Get a reference to our resource table. myResources = getResources(); float strokeWidth = 10; switch (TerminalInfo.getInstance().getDensityDPI()) { case 120: case 160: strokeWidth = 4f; break; case 240: strokeWidth = 6f; break; case 320: strokeWidth = 8f; break; case 480: default: strokeWidth = 12f; break; } // 绘制自由曲线用的画笔 myPaint = new Paint(); myPaint.setAntiAlias(true); myPaint.setDither(true); myPaint.setColor(myResources.getColor(android.R.color.background_dark)); myPaint.setStyle(Paint.Style.STROKE); myPaint.setStrokeJoin(Paint.Join.ROUND); myPaint.setStrokeCap(Paint.Cap.ROUND); myPaint.setStrokeWidth(strokeWidth); myPath = new Path(); myBitmap = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.RGB_565); myCanvas = new Canvas(myBitmap); myCanvas.drawColor(0xffffffff); mBitmapPaint = new Paint(Paint.DITHER_FLAG); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { if(myCanvas == null) { this.mWidth = right - left; this.mHeight = bottom - top; initialize(); } super.onLayout(changed, left, top, right, bottom); } // @Override // protected void onSizeChanged(int w, int h, int oldw, int oldh) { // super.onSizeChanged(w, h, oldw, oldh); // mWidth = w; // mHeight = h; // } @Override public boolean onTouchEvent(MotionEvent event) { float x = event.getX(); float y = event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: touch_start(x, y); invalidate(); break; case MotionEvent.ACTION_MOVE: touch_move(x, y); invalidate(); break; case MotionEvent.ACTION_UP: touch_up(); invalidate(); break; } return true; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (myBitmap != null && !myBitmap.isRecycled()) { // 背景颜色 // canvas.drawColor(getResources().getColor(R.color.blue_dark)); // 如果不调用这个方法,绘制结束后画布将清空 canvas.drawBitmap(myBitmap, 0, 0, mBitmapPaint); // 绘制路径 canvas.drawPath(myPath, myPaint); } } private void touch_start(float x, float y) { myPath.reset(); myPath.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) { myPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2); mX = x; mY = y; } } private void touch_up() { myPath.lineTo(mX, mY); // commit the path to our offscreen // 如果少了这一句,笔触抬起时myPath重置,那么绘制的线将消失 myCanvas.drawPath(myPath, myPaint); // kill this so we don‘t double draw myPath.reset(); } /** * 清除整个图像 */ public void clear() { // 清除方法1:重新生成位图 // myBitmap = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888); // myCanvas = new Canvas(myBitmap); // 清除方法2:将位图清除为白色 myBitmap.eraseColor(myResources.getColor(android.R.color.white)); // 两种清除方法都必须加上后面这两步: // 路径重置 myPath.reset(); myCanvas.drawColor(0xffffffff); // 刷新绘制 invalidate(); } public Bitmap getWaterMarkBitmap(String transCode, int width, int height) { // Typeface fontFace = // Typeface.createFromAsset(getContext().getAssets(), // "fonts/TIMES.TTF"); Bitmap bitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); int fontSize = 20; Path path = new Path(); path.moveTo(0, height / 2); path.lineTo(width, height / 2); path.close(); Paint paint = new Paint(); paint.setColor(0xfff4f4f4); paint.setTextSize(fontSize); paint.setTypeface(TerminalInfo.getInstance().getSigndataTypeface( getContext())); paint.setStyle(Paint.Style.FILL_AND_STROKE); paint.setStrokeWidth(0); paint.setAntiAlias(false); paint.setDither(true); Rect bounds = new Rect(); paint.getTextBounds(transCode, 0, transCode.length(), bounds); // float[] pos = new float[16]; // for(int i=0; i<16; i++) { // pos[i] = 30 + i*12; // pos[i++] = 30; // } // canvas.drawPosText(transCode, pos, paint); // 璁剧疆闂磋窛 int extend = 7;// 1px*7 int hOffset = (width - (bounds.right - bounds.left) - extend) / 2; for (int i = 0; i < transCode.length(); i++) { canvas.drawTextOnPath(transCode.substring(i, i + 1), path, hOffset, fontSize / 2, paint); hOffset += (bounds.right - bounds.left + extend) / 7; } return bitmap; } public Bitmap getOverLayBitmap(Bitmap src, Bitmap watermark) { if (src == null) { return null; } int srcWidth = src.getWidth(); int srcHeight = src.getHeight(); int markWidth = watermark.getWidth(); int markHeight = watermark.getHeight(); int width = srcWidth > markWidth ? srcWidth : markWidth; int height = srcHeight > markHeight ? srcHeight : markHeight; // 鍒涘缓涓?釜鍜屾簮浣嶅浘涓?牱澶у皬鐨勬柊浣嶅浘 Bitmap bitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); canvas.drawBitmap(src, Math.abs(width - srcWidth) / 2, Math.abs(height - srcHeight), null);// 浠?0,0)浣嶇疆寮?鐢绘簮浣嶅浘 canvas.drawBitmap(watermark, Math.abs(width - markWidth) / 2, Math.abs(height - markHeight), null);// 浠?0,0)浣嶇疆寮?鐢绘按鍗? canvas.save(Canvas.ALL_SAVE_FLAG); canvas.restore(); return bitmap; } }