android Bitmap旋转问题

wx_1021 2014-09-17 11:44:26

//画笔,定义绘制属性
private Paint myPaint;
private Paint mBitmapPaint;

// 绘制路径
private Path myPath;

// 画布及其底层位图
private Bitmap myBitmap0;
private Bitmap myBitmap1;
private Canvas myCanvas;
public MyPaintView(Context context, AttributeSet attrs){
super(context, attrs);
myBitmap0 = BitmapFactory.decodeFile("/storage/sdcard/a.png").copy(Bitmap.Config.ARGB_8888, true);
myBitmap1 = Bitmap.createBitmap(myBitmap0);
if(i == 0){
initialize();
}else if(i == 1){
initWhite();
}
// 开启线程
new Thread(this).start();
}
public void initialize(){
// 绘制自由曲线用的画笔
myPaint = new Paint();
myPaint.setAntiAlias(true);
myPaint.setDither(true);
myPaint.setColor(RGBColor.getColor());
myPaint.setStyle(Paint.Style.STROKE);
myPaint.setStrokeJoin(Paint.Join.ROUND);
myPaint.setStrokeCap(Paint.Cap.ROUND);
myPaint.setStrokeWidth(RGBColor.getFontSize());
myPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
}
@Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
// 背景颜色
canvas.drawColor(R.color.white);
canvas.drawBitmap(myBitmap1, 0, 0, mBitmapPaint);

canvas.drawPath(myPath, myPaint);
myCanvas = new Canvas(myBitmap1);
}

/**
* 图片旋转
* */
public void picPost(int nPostExtent){
matrix.reset();
matrix.postScale(Scale, Scale);
matrix.postRotate(nPostExtent);
// 下面这句话如果把myBitmap1都改为myBitmap0的话顺时针和逆时针旋转都没有问题,现在需要用myBitmap1,是因为在这个位图上面先涂鸦了再旋转的话就会清空以前涂鸦内容,所以选用myBitmap1,但是用它的话只能朝着一个方向旋转,先顺时针完了,逆时针就回不来了
myBitmap1 = Bitmap.createBitmap(myBitmap1, 0, 0, myBitmap1.getWidth(), myBitmap1.getHeight(), matrix, true);
}
...全文
361 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
wx_1021 2014-09-22
  • 打赏
  • 举报
回复
引用 9 楼 danielinbiti 的回复:
哦,不是90度角呀,45度角那回不来了。因为图片是在不断变大了,右上角不断填充了白色区域。 把path存起来,底图不变,每次画图都是底图+path 或者把path画在一个canvas上,把底图在另一个bitmap上,两个叠加。
叠加的方法确实可行,我试过,但是不是想要的效果;
danielinbiti 2014-09-19
  • 打赏
  • 举报
回复
哦,不是90度角呀,45度角那回不来了。因为图片是在不断变大了,右上角不断填充了白色区域。 把path存起来,底图不变,每次画图都是底图+path 或者把path画在一个canvas上,把底图在另一个bitmap上,两个叠加。
danielinbiti 2014-09-18
  • 打赏
  • 举报
回复
引用 2 楼 wx_1021 的回复:
[quote=引用 1 楼 danielinbiti 的回复:] 怎么涂鸦的,光看你这几行ondraw的代码,myBitmap1位图上是不会画上内容的,除非是画在myCanvas上
在onDraw这个里面的canvas.drawBitmap(myBitmap1, 0, 0, mBitmapPaint);这句就是了 myCanvas就是canvas了,因为每次执行都会执行onDraw,是可以画上的 现在想知道旋转完了如何归位顺时针完了 逆时针回不来了,点两下逆时针就算回来了,Bitmap.createBitmap这里的x,y坐标也是变了,但是我设置的就是0,我就不明白了[/quote] 如果光是图片旋转的画 picPost(90)后picPost(-90)类似肯定是能旋转回来的。你这代码不全,也没图片,就无法推测了
wx_1021 2014-09-18
  • 打赏
  • 举报
回复
引用 5 楼 danielinbiti 的回复:
看着有点乱,既然以mCanvas作为画布,那么在ondraw中,应该直接画myBitmap1就可以了,没必要在画一遍涂鸦路径吧。
我的问题是旋转问题不归位,跟画笔什么关系
danielinbiti 2014-09-18
  • 打赏
  • 举报
回复
看着有点乱,既然以mCanvas作为画布,那么在ondraw中,应该直接画myBitmap1就可以了,没必要在画一遍涂鸦路径吧。
wx_1021 2014-09-18
  • 打赏
  • 举报
回复
引用 3 楼 danielinbiti 的回复:
[quote=引用 2 楼 wx_1021 的回复:] [quote=引用 1 楼 danielinbiti 的回复:] 怎么涂鸦的,光看你这几行ondraw的代码,myBitmap1位图上是不会画上内容的,除非是画在myCanvas上
在onDraw这个里面的canvas.drawBitmap(myBitmap1, 0, 0, mBitmapPaint);这句就是了 myCanvas就是canvas了,因为每次执行都会执行onDraw,是可以画上的 现在想知道旋转完了如何归位顺时针完了 逆时针回不来了,点两下逆时针就算回来了,Bitmap.createBitmap这里的x,y坐标也是变了,但是我设置的就是0,我就不明白了[/quote] 如果光是图片旋转的画 picPost(90)后picPost(-90)类似肯定是能旋转回来的。你这代码不全,也没图片,就无法推测了[/quote] 这是我所有的代码了,帮忙推断下

public class MyPaintView extends View implements Runnable {
	//画笔,定义绘制属性
	private Paint myPaint;
	private Paint mBitmapPaint;
	
	// 绘制路径
	private Path myPath;
	
	// 画布及其底层位图
	private Bitmap myBitmap0;
	private Bitmap myBitmap1;
	private Canvas myCanvas;
	
	private float mX, mY;
	
	private static final float TOUCH_TOLERANCE = 4;
	
	// 判断是画笔还是橡皮擦
	private static int i = 0;
	// 缩放
	float Scale = 1.0f;
	Matrix matrix = new Matrix();

	private boolean isPicOK = false;
	public MyPaintView(Context context, AttributeSet attrs){
		super(context, attrs);
		myBitmap0 = BitmapFactory.decodeFile("/storage/sdcard/a.png").copy(Bitmap.Config.ARGB_8888, true);
		myBitmap1 = Bitmap.createBitmap(myBitmap0);
		if(i == 0){
			initialize();
		}else if(i == 1){
			initWhite();
		}
		//	开启线程
		new Thread(this).start();
	}
	/**
	 * 画笔
	 * */
	public void initialize(){
		// 绘制自由曲线用的画笔
		myPaint = new Paint();
		myPaint.setAntiAlias(true);
		myPaint.setDither(true);
		myPaint.setColor(RGBColor.getColor());
		myPaint.setStyle(Paint.Style.STROKE);
		myPaint.setStrokeJoin(Paint.Join.ROUND);
		myPaint.setStrokeCap(Paint.Cap.ROUND);
		myPaint.setStrokeWidth(RGBColor.getFontSize());

		myPath = new Path();
		mBitmapPaint = new Paint(Paint.DITHER_FLAG);
		
		i = 0;
	}
	/**
	 * 橡皮擦
	 * */
	private void initWhite(){
		// 绘制自由曲线用的画笔
		myPaint = new Paint();
		myPaint.setAntiAlias(true);
		myPaint.setDither(true);
		myPaint.setColor(Color.WHITE);
		myPaint.setStyle(Paint.Style.STROKE);
		myPaint.setStrokeJoin(Paint.Join.ROUND);
		myPaint.setStrokeCap(Paint.Cap.ROUND);
		myPaint.setStrokeWidth(RGBColor.getFontSize());

		myPath = new Path();
		mBitmapPaint = new Paint(Paint.DITHER_FLAG);
		
		i = 1;
	}
	@Override
	protected void onDraw(Canvas canvas){
		super.onDraw(canvas);
		// 背景颜色
		canvas.drawColor(R.color.white);
		if(isPicOK){
			canvas.drawBitmap(myBitmap1, matrix, mBitmapPaint);			
		}else{
			// 如果不调用这个方法,绘制结束后画布将清空
			canvas.drawBitmap(myBitmap1, 0, 0, mBitmapPaint);
		}
		canvas.drawPath(myPath, myPaint);
		//myBitmap1 = Bitmap.createBitmap(myBitmap1, 0, 0, myBitmap1.getWidth(), myBitmap1.getHeight(), matrix, true);
		myCanvas = new Canvas(myBitmap1);
	}
	// 保存
	public void save(){
		/*myCanvas.save(Canvas.ALL_SAVE_FLAG);
		myCanvas.restore();*/
		File f = new File("/storage/sdcard/","a.png");
        if(f.exists()){
        	f.delete();
        }
		FileOutputStream fos = null;
		try {
			fos = new FileOutputStream(f);
			myBitmap1.compress(Bitmap.CompressFormat.PNG, 100, fos);  
			try {
				fos.flush();
				fos.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	@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;
	}
	public void touch_start(float x, float y){
		myPath.reset();
		myPath.moveTo(x, y);
		mX = x;
		mY = y;
	}
	public 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;
		}
	}
	public 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:重新生成位图
		//myBitmap0 = BitmapFactory.decodeFile("/storage/sdcard/a.jpg").copy(Bitmap.Config.ARGB_8888, true);
		//myBitmap1 = Bitmap.createBitmap(myBitmap0);
		myBitmap1.eraseColor(getResources().getColor(R.color.white));
		myCanvas = new Canvas(myBitmap1);
		
		// 刷新绘制
		invalidate();
	}
	/**
	 * 橡皮擦
	 * */
	public void white() {
		// TODO Auto-generated method stub
		initWhite();
	}
	/**
	 * 图片放大
	 * */
	public void picBig() {
		// TODO Auto-generated method stub
		Scale += 0.1;
		matrix.reset();
		matrix.postScale(Scale, Scale);
		matrix.postRotate(RGBColor.getnPostExtent());
		myBitmap1 = Bitmap.createBitmap(myBitmap0, 0, 0, myBitmap0.getWidth(), myBitmap0.getHeight(), matrix, true);
		//MyPaintView.drawImage(myCanvas, myBitmapBig, 0, 0);
		isPicOK = false;
	}
	/**
	 * 图片缩小
	 * */
	public void picSmall() {
		// TODO Auto-generated method stub
		Scale -= 0.1;
		matrix.reset();
		matrix.postScale(Scale, Scale);
		matrix.postRotate(RGBColor.getnPostExtent());
		myBitmap1 = Bitmap.createBitmap(myBitmap0, 0, 0, myBitmap0.getWidth(), myBitmap0.getHeight(), matrix, true);
		isPicOK = false;
	}
	/**
	 * 图片旋转
	 * */
	public void picPost(int nPostExtent){
		matrix.reset();
		matrix.postScale(Scale, Scale);
		matrix.postRotate(nPostExtent);
		//matrix.setRotate(nPostExtent, (float)myBitmap0.getWidth()/2, (float)myBitmap0.getHeight()/2);
		myBitmap1 = Bitmap.createBitmap(myBitmap0, 0, 0, myBitmap0.getWidth(), myBitmap0.getHeight(), matrix, true);
		//MyPaintView.drawImage(myCanvas, myBitmapPost, 0, 0);
		//myBitmapPost = null;
		
		//myCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
		isPicOK = false;
	}
	/**
	 * 圆心旋转
	 * */
	public void picRotate(){
		int width = myBitmap0.getWidth();
		int height = myBitmap0.getHeight();
		matrix.reset();
		matrix.postRotate(90f, width/2, height/2);
		//matrix.postTranslate(10, 10);
		isPicOK = true;
		//this.invalidate();
//		matrix.postTranslate(width, height);
		//myBitmap1 = Bitmap.createBitmap(myBitmap1, 0, 0, myBitmap0.getWidth(), myBitmap0.getHeight(), matrix, true);
	}
	/**
	 * 圆心缩放
	 * */
	public void picZoom(){
		matrix.reset();
		matrix.postScale(0.5f,0.5f);
		matrix.postTranslate(130, 130);
		//matrix.postSkew(0.3f, 0.3f, 100, 100);
		isPicOK = true;
	}
	/**
	 * 线程处理
	 * */
	public void run(){
		while(!Thread.currentThread().isInterrupted()){
			try{
				Thread.sleep(100);
			}catch(InterruptedException e){
				Thread.currentThread().interrupt();
			}
			postInvalidate();
		}
	}
	// 绘制Bitmap
	public static void drawImage(Canvas canvas, Bitmap bitmap, int x, int y) {
		//canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
		canvas.drawBitmap(bitmap, x, y, null);
	}
wx_1021 2014-09-18
  • 打赏
  • 举报
回复
引用 7 楼 danielinbiti 的回复:
[quote=引用 6 楼 wx_1021 的回复:]
[quote=引用 5 楼 danielinbiti 的回复:]
看着有点乱,既然以mCanvas作为画布,那么在ondraw中,应该直接画myBitmap1就可以了,没必要在画一遍涂鸦路径吧。


我的问题是旋转问题不归位,跟画笔什么关系[/quote]
改了一下
拷代码试了试,光旋转paintView.picPost(90),paintView.picPost(-90)没有问题。
public void picPost(int nPostExtent){
matrix.reset();
matrix.postScale(Scale, Scale);
matrix.postRotate(nPostExtent);
//matrix.setRotate(nPostExtent, (float)myBitmap0.getWidth()/2, (float)myBitmap0.getHeight()/2);
//改动了下面这句话
myBitmap1 = Bitmap.createBitmap(myBitmap1, 0, 0, myBitmap1.getWidth(), myBitmap1.getHeight(), matrix, true);
//MyPaintView.drawImage(myCanvas, myBitmapPost, 0, 0);
//myBitmapPost = null;

//myCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
isPicOK = false;
}
[/quote]
给你看看我的效果,顺时针设定值为45度逆时针为-45度,第一张是原图,第二张是顺时针的,第三张是逆时针的



按说第三张应该回到第一张原图的位置上吧
danielinbiti 2014-09-18
  • 打赏
  • 举报
回复
引用 6 楼 wx_1021 的回复:
[quote=引用 5 楼 danielinbiti 的回复:] 看着有点乱,既然以mCanvas作为画布,那么在ondraw中,应该直接画myBitmap1就可以了,没必要在画一遍涂鸦路径吧。
我的问题是旋转问题不归位,跟画笔什么关系[/quote] 改了一下 拷代码试了试,光旋转paintView.picPost(90),paintView.picPost(-90)没有问题。
public void picPost(int nPostExtent){
		matrix.reset();
		matrix.postScale(Scale, Scale);
		matrix.postRotate(nPostExtent);
		//matrix.setRotate(nPostExtent, (float)myBitmap0.getWidth()/2, (float)myBitmap0.getHeight()/2);
//改动了下面这句话
		myBitmap1 = Bitmap.createBitmap(myBitmap1, 0, 0, myBitmap1.getWidth(), myBitmap1.getHeight(), matrix, true);
		//MyPaintView.drawImage(myCanvas, myBitmapPost, 0, 0);
		//myBitmapPost = null;
		
		//myCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
		isPicOK = false;
	}
wx_1021 2014-09-17
  • 打赏
  • 举报
回复
引用 1 楼 danielinbiti 的回复:
怎么涂鸦的,光看你这几行ondraw的代码,myBitmap1位图上是不会画上内容的,除非是画在myCanvas上
在onDraw这个里面的canvas.drawBitmap(myBitmap1, 0, 0, mBitmapPaint);这句就是了 myCanvas就是canvas了,因为每次执行都会执行onDraw,是可以画上的 现在想知道旋转完了如何归位顺时针完了 逆时针回不来了,点两下逆时针就算回来了,Bitmap.createBitmap这里的x,y坐标也是变了,但是我设置的就是0,我就不明白了
danielinbiti 2014-09-17
  • 打赏
  • 举报
回复
怎么涂鸦的,光看你这几行ondraw的代码,myBitmap1位图上是不会画上内容的,除非是画在myCanvas上

80,349

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧