【问题标题】:android draw line on scaled and transformed image on canvasandroid在画布上缩放和转换的图像上画线
【发布时间】:2015-05-12 10:15:36
【问题描述】:
我在画布上的缩放和变换图像上画线时遇到问题,对于变换后的图像,我可以在图像上画线,但如果图像被缩放(放大或缩小),那么使用手指触摸会意外地画出像素。由于我正在研究油漆应用程序,但对此没有更多了解,所以我需要您的帮助,我在谷歌上搜索过但没有运气,我没有找到任何东西
这是第一个图像默认正常工作,第二个移动图像正常工作正确绘制线
虽然在第三个缩放图像上没有正确绘制,我的意思是如果从上/左角开始绘制,那么画线点与这里不同
如果您需要代码,请说出来,我会编辑问题
【问题讨论】:
标签:
android
image-manipulation
android-canvas
【解决方案1】:
好的,经过多次实施,我得到了解决方案。
这是我在 onDraw() 中绘制的代码
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.save();
canvas.translate(mPosX, mPosY);
canvas.scale(mScaleFactor, mScaleFactor);
canvas.drawBitmap(MoveImageTestActivity.bmp, 0,0,null);
if(mScaleFactor!=1.f)
canvas.restore();
if(isDrawing)
canvas.drawPath(tempPath,get_paint());
if(mScaleFactor==1.f)
canvas.restore();
}
在这里您必须检查比例因子值以恢复画布。如果比例因子值默认为 1.f 并且图像只是移动然后在绘制线/路径之后恢复,如果比例因子不等于 1.f(默认值)然后恢复画布 1st 然后绘制线/使用手指触摸绘图时的路径。
这是我的 onTouch() 代码
@Override
public boolean onTouchEvent(MotionEvent ev) {
mScaleDetector.onTouchEvent(ev);
final int action = ev.getAction();
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: {
final float x = ev.getX();
final float y = ev.getY();
if(isDrawing){
float dx = ev.getX();
float dy = ev.getY();;
if(mScaleFactor==1.f){
dx = ev.getX() - mPosX;
dy = ev.getY() - mPosY;
}
tempPath = new Path();
tempPath.moveTo(dx,dy);
}else{
mLastTouchX = x;
mLastTouchY = y;
// Save the ID of this pointer
mActivePointerId = ev.getPointerId(0);
}
break;
}
case MotionEvent.ACTION_MOVE: {
// Find the index of the active pointer and fetch its position
if(isDrawing){
float dx = ev.getX();
float dy = ev.getY();;
if(mScaleFactor==1.f){
dx = ev.getX() - mPosX;
dy = ev.getY() - mPosY;
}
tempPath.lineTo(dx,dy);
}else{
final int pointerIndex = ev.findPointerIndex(mActivePointerId);
final float x = ev.getX(pointerIndex);
final float y = ev.getY(pointerIndex);
final float dx = x - mLastTouchX;
final float dy = y - mLastTouchY;
mPosX += dx;
mPosY += dy;
mLastTouchX = x;
mLastTouchY = y;
}
break;
}
case MotionEvent.ACTION_UP: {
points.clear();
mActivePointerId = INVALID_POINTER_ID;
break;
}
case MotionEvent.ACTION_CANCEL: {
mActivePointerId = INVALID_POINTER_ID;
break;
}
case MotionEvent.ACTION_POINTER_UP: {
if(!isDrawing){
// Extract the index of the pointer that left the touch sensor
final int pointerIndex = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
final int pointerId = ev.getPointerId(pointerIndex);
if (pointerId == mActivePointerId) {
// This was our active pointer going up. Choose a new
// active pointer and adjust accordingly.
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
mLastTouchX = ev.getX(newPointerIndex);
mLastTouchY = ev.getY(newPointerIndex);
mActivePointerId = ev.getPointerId(newPointerIndex);
}
}
break;
}
}
invalidate();
return true;
}