android 涂鸦与延时问题

最近在做android 涂鸦,采用的是在 FramLayout布局,后面一层加载的是背景图片,前面一层是自定义的view

public class PicEditView extends View {

	private int screenWidth, screenHeight;// 屏幕長寬
	private Bitmap mBitmap;
	private Canvas mCanvas;
	private Path mPath;
	private Paint mBitmapPaint;// 画布的画笔
	private Paint mPaint;// 真实的画笔
	private float mX, mY;// 临时点坐标
	private static final float TOUCH_TOLERANCE = 4;

	public PicEditView(Context context, int w, int h) {
		this(context, null);
		screenWidth = w;
		screenHeight = h;
		mBitmap = Bitmap.createBitmap(screenWidth, screenHeight,
				Bitmap.Config.ARGB_8888);
		mCanvas = new Canvas(mBitmap);

		mBitmapPaint = new Paint(Paint.DITHER_FLAG);
		mPaint = new Paint();
		mPaint.setAntiAlias(true);
		mPaint.setStyle(Paint.Style.STROKE);
		mPaint.setStrokeJoin(Paint.Join.ROUND);// 设置外边缘
		mPaint.setStrokeCap(Paint.Cap.SQUARE);// 形状
		mPaint.setStrokeWidth(5);// 画笔宽度

	}

	public void setPaintColor(int color){
		mPaint.setColor(color);
	}

	@Override
	protected void onAttachedToWindow() {
		// TODO Auto-generated method stub
		super.onAttachedToWindow();
	}
	public PicEditView(Context context, AttributeSet attrs) {
		super(context, attrs);

	}

	@Override
	protected void onDraw(Canvas canvas) {
		canvas.drawColor(0x00000000);
		// 将前面已经画过得显示出来
		canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
		if (mPath != null) {
			// 实时的显示
			canvas.drawPath(mPath, mPaint);
		}
		super.onDraw(canvas);
	}

	private void touch_start(float x, float y) {
		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(mY - y);
		
		//触摸间隔大于阈值才绘制路径
		if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
		// 从x1,y1到x2,y2画一条贝塞尔曲线,更平滑(直接用mPath.lineTo也是可以的)
		mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
		mX = x;
		mY = y;
		}
	}
	private void touch_up() {
		mPath.lineTo(mX, mY);
		mCanvas.drawPath(mPath, mPaint);
	}

	public boolean onTouchEvent(MotionEvent event) {
		float x = event.getX();
		float y = event.getY();

		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			// 每次down下去重新new一个Path
			mPath = new Path();

			touch_start(x, y);
			System.out.println("ACTION_DOWN");
			this.postInvalidate();
//			invalidate();
			break;
		case MotionEvent.ACTION_MOVE:
			System.out.println("--MOVE--");
			touch_move(x, y);
			this.postInvalidate();
//			invalidate();
			break;
		case MotionEvent.ACTION_UP:
			touch_up();
			System.out.println("--ACTION_UP--");
			this.postInvalidate();
//			invalidate();
			break;
		}
		return true;
	}

	
}

然而,在demo上,绘制很实时流畅,整合进代码里,就有很明显的延时与卡顿,对比分析后发现,是由于从相册获取的背景层图片比较大,消耗了内存,导致绘制的延时。

因此在加载图片是,缩小了图片的大小,从而可以流畅的涂鸦。

		try {
			BitmapFactory.Options options = new BitmapFactory.Options();
			//图片宽高都为原来的二分之一,即图片为原来的四分之一
			//这样可以避免内存消耗,否则,后面绘图时,会出现很大的延时
            options.inSampleSize = 2;//
			bitmap = BitmapFactory.decodeStream(getContentResolver()
					.openInputStream(imageFileUri),null,options);
			imgView.setImageBitmap(bitmap);
//			bitmap.recycle();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

保存涂鸦结果(底图+涂鸦):

		layout = (FrameLayout) findViewById(R.id.container);

		DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
		mView = new MView(this, displayMetrics.widthPixels, displayMetrics.heightPixels - dip2px(this, 40));
		layout.addView(mView);
		findViewById(R.id.tSave).setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View arg0) {
				// TODO Auto-generated method stub

				layout.setDrawingCacheEnabled(true);
				layout.buildDrawingCache();
				Bitmap b1 = layout.getDrawingCache();
				//copy 缓存图像
				 Bitmap b = Bitmap.createBitmap(b1);  

				layout.destroyDrawingCache();//这个之后,b1 就被 recycle了
				System.out.println(Environment.getExternalStorageDirectory().getPath() );
				File file = new File(Environment.getExternalStorageDirectory().getPath() +"/test1.png");
				savePic(b, file);
			}
		});





你可能感兴趣的:(android 涂鸦与延时问题)