我的 Android 手指绘画应用程序将绘画发送到图像上的不规则位置

发布于 2024-12-01 12:06:56 字数 5656 浏览 0 评论 0原文

在我的 Android Finger Paint 应用程序中,我使用了两个视图的图像视图背面和顶部绘画视图,它可以很好地进行绘画和擦除。但保存后真实的绘画位置发生了变化。

删除了图像的死链接

代码是

public MyView(Context c)  {
    super(c);
    //mBitmap = Bitmap.createScaledBitmap(originalBitmap,bw,bh,true);
    mBitmap = Bitmap.createBitmap(bw,bh,Bitmap.Config.ARGB_8888);
    mCanvas = new Canvas(mBitmap);
    mPath = new Path();
    mBitmapPaint = new Paint(Paint.DITHER_FLAG);
    mBitmapPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
}
@Override 
protected void onDraw(Canvas canvas) {   
    canvas.drawColor(Color.TRANSPARENT);
    canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
    canvas.drawPath(mPath, mPaint);
} 

myimage.setOnTouchListener(this);
public boolean onTouch(View v, MotionEvent event) {
    ImageView myimage = (ImageView) v;
    // Dump touch event to log
    dumpEvent(event);
    // Handle touch events here...
    switch (event.getAction() & MotionEvent.ACTION_MASK) {
        case MotionEvent.ACTION_DOWN:
            savedMatrix.set(matrix);
            start.set(event.getX(), event.getY());
            Log.d(TAG, "mode=DRAG");
            mode = DRAG;
            break;
        case MotionEvent.ACTION_POINTER_DOWN:
            oldDist = spacing(event);
            Log.d(TAG, "oldDist=" + oldDist);
            if (oldDist > 10f) {
                savedMatrix.set(matrix);
                midPoint(mid, event);
                mode = ZOOM;
                Log.d(TAG, "mode=ZOOM");
            }
            break;
        case MotionEvent.ACTION_UP:
        case MotionEvent.ACTION_POINTER_UP:
            mode = NONE;
            Log.d(TAG, "mode=NONE");
            break;
        case MotionEvent.ACTION_MOVE:
            if (mode == DRAG) {
                /////// limiting  the panning 
                matrix.getValues(matrixValues);
                float currentY = matrixValues[Matrix.MTRANS_Y];
                float currentX = matrixValues[Matrix.MTRANS_X];
                float currentScale = matrixValues[Matrix.MSCALE_X];
                float currentHeight = height * currentScale;
                float currentWidth = width * currentScale;
                float dx = event.getX() - start.x;
                float dy = event.getY() - start.y;
                float newX = currentX+dx;
                float newY = currentY+dy;   
                RectF drawingRect = new RectF(newX, newY, newX+currentWidth, newY+currentHeight);
                float diffUp = Math.min(viewRect.bottom-drawingRect.bottom, viewRect.top-drawingRect.top);
                float diffDown = Math.max(viewRect.bottom-drawingRect.bottom, viewRect.top-drawingRect.top);
                float diffLeft = Math.min(viewRect.left-drawingRect.left, viewRect.right-drawingRect.right);
                float diffRight = Math.max(viewRect.left-drawingRect.left, viewRect.right-drawingRect.right);
                if(diffUp > 0 ){ dy +=diffUp; }
                if(diffDown < 0){ dy +=diffDown; }  
                if( diffLeft> 0){ dx += diffLeft; }
                if(diffRight < 0){dx += diffRight; }
                matrix.postTranslate(dx, dy);
            } 
            else if (mode == ZOOM) {
                float newDist = spacing(event);
                Log.d(TAG, "newDist=" + newDist);
                if (newDist > 10f) {
                matrix.set(savedMatrix);
                float scale = newDist / oldDist;
                matrix.getValues(matrixValues);
                float currentScale = matrixValues[Matrix.MSCALE_X];
                // limit zoom
                if (scale * currentScale > maxZoom) {
                    scale = maxZoom / currentScale; 
                }
                else if(scale * currentScale < minZoom){
                    scale = minZoom / currentScale; 
                }
                matrix.postScale(scale, scale, mid.x, mid.y);
            }
        }
        break;
    }
    myimage.setImageMatrix(matrix);
    return true; // indicate event was handled
}

// Show an event in the LogCat view, for debugging 
private void dumpEvent(MotionEvent event) {
    String names[] = { "DOWN", "UP", "MOVE", "CANCEL", "OUTSIDE",
                      "POINTER_DOWN", "POINTER_UP", "7?", "8?", "9?" };
    StringBuilder sb = new StringBuilder();
    int action = event.getAction();
    int actionCode = action & MotionEvent.ACTION_MASK;
    sb.append("event ACTION_").append(names[actionCode]);
    if (actionCode == MotionEvent.ACTION_POINTER_DOWN || actionCode ==   MotionEvent.ACTION_POINTER_UP) {
        sb.append("(pid ").append(action >> MotionEvent.ACTION_POINTER_ID_SHIFT);
        sb.append(")");
    }
    sb.append("[");
    for (int i = 0; i < event.getPointerCount(); i++) {
        sb.append("#").append(i);
        sb.append("(pid ").append(event.getPointerId(i));
        sb.append(")=").append((int) event.getX(i));
        sb.append(",").append((int) event.getY(i));
        if (i + 1 < event.getPointerCount())
            sb.append(";");
        }
        sb.append("]");
        Log.d(TAG, sb.toString());
    }

    //Determine the space between the first two fingers
    private float spacing(MotionEvent event) {
        float x = event.getX(0) - event.getX(1);
        float y = event.getY(0) - event.getY(1);
        return FloatMath.sqrt(x * x + y * y);
    }

    // Calculate the mid point of the first two fingers 
    private void midPoint(PointF point, MotionEvent event) {
        float x = event.getX(0) + event.getX(1);
        float y = event.getY(0) + event.getY(1);
        point.set(x / 2, y / 2);
    }
}

In my Android Finger Paint app I used two view's imageview backside and paintview on top, it's working fine for painting and erasing. But after saving the real painting position is changed.

removed dead links to images

Code is

public MyView(Context c)  {
    super(c);
    //mBitmap = Bitmap.createScaledBitmap(originalBitmap,bw,bh,true);
    mBitmap = Bitmap.createBitmap(bw,bh,Bitmap.Config.ARGB_8888);
    mCanvas = new Canvas(mBitmap);
    mPath = new Path();
    mBitmapPaint = new Paint(Paint.DITHER_FLAG);
    mBitmapPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
}
@Override 
protected void onDraw(Canvas canvas) {   
    canvas.drawColor(Color.TRANSPARENT);
    canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
    canvas.drawPath(mPath, mPaint);
} 

myimage.setOnTouchListener(this);
public boolean onTouch(View v, MotionEvent event) {
    ImageView myimage = (ImageView) v;
    // Dump touch event to log
    dumpEvent(event);
    // Handle touch events here...
    switch (event.getAction() & MotionEvent.ACTION_MASK) {
        case MotionEvent.ACTION_DOWN:
            savedMatrix.set(matrix);
            start.set(event.getX(), event.getY());
            Log.d(TAG, "mode=DRAG");
            mode = DRAG;
            break;
        case MotionEvent.ACTION_POINTER_DOWN:
            oldDist = spacing(event);
            Log.d(TAG, "oldDist=" + oldDist);
            if (oldDist > 10f) {
                savedMatrix.set(matrix);
                midPoint(mid, event);
                mode = ZOOM;
                Log.d(TAG, "mode=ZOOM");
            }
            break;
        case MotionEvent.ACTION_UP:
        case MotionEvent.ACTION_POINTER_UP:
            mode = NONE;
            Log.d(TAG, "mode=NONE");
            break;
        case MotionEvent.ACTION_MOVE:
            if (mode == DRAG) {
                /////// limiting  the panning 
                matrix.getValues(matrixValues);
                float currentY = matrixValues[Matrix.MTRANS_Y];
                float currentX = matrixValues[Matrix.MTRANS_X];
                float currentScale = matrixValues[Matrix.MSCALE_X];
                float currentHeight = height * currentScale;
                float currentWidth = width * currentScale;
                float dx = event.getX() - start.x;
                float dy = event.getY() - start.y;
                float newX = currentX+dx;
                float newY = currentY+dy;   
                RectF drawingRect = new RectF(newX, newY, newX+currentWidth, newY+currentHeight);
                float diffUp = Math.min(viewRect.bottom-drawingRect.bottom, viewRect.top-drawingRect.top);
                float diffDown = Math.max(viewRect.bottom-drawingRect.bottom, viewRect.top-drawingRect.top);
                float diffLeft = Math.min(viewRect.left-drawingRect.left, viewRect.right-drawingRect.right);
                float diffRight = Math.max(viewRect.left-drawingRect.left, viewRect.right-drawingRect.right);
                if(diffUp > 0 ){ dy +=diffUp; }
                if(diffDown < 0){ dy +=diffDown; }  
                if( diffLeft> 0){ dx += diffLeft; }
                if(diffRight < 0){dx += diffRight; }
                matrix.postTranslate(dx, dy);
            } 
            else if (mode == ZOOM) {
                float newDist = spacing(event);
                Log.d(TAG, "newDist=" + newDist);
                if (newDist > 10f) {
                matrix.set(savedMatrix);
                float scale = newDist / oldDist;
                matrix.getValues(matrixValues);
                float currentScale = matrixValues[Matrix.MSCALE_X];
                // limit zoom
                if (scale * currentScale > maxZoom) {
                    scale = maxZoom / currentScale; 
                }
                else if(scale * currentScale < minZoom){
                    scale = minZoom / currentScale; 
                }
                matrix.postScale(scale, scale, mid.x, mid.y);
            }
        }
        break;
    }
    myimage.setImageMatrix(matrix);
    return true; // indicate event was handled
}

// Show an event in the LogCat view, for debugging 
private void dumpEvent(MotionEvent event) {
    String names[] = { "DOWN", "UP", "MOVE", "CANCEL", "OUTSIDE",
                      "POINTER_DOWN", "POINTER_UP", "7?", "8?", "9?" };
    StringBuilder sb = new StringBuilder();
    int action = event.getAction();
    int actionCode = action & MotionEvent.ACTION_MASK;
    sb.append("event ACTION_").append(names[actionCode]);
    if (actionCode == MotionEvent.ACTION_POINTER_DOWN || actionCode ==   MotionEvent.ACTION_POINTER_UP) {
        sb.append("(pid ").append(action >> MotionEvent.ACTION_POINTER_ID_SHIFT);
        sb.append(")");
    }
    sb.append("[");
    for (int i = 0; i < event.getPointerCount(); i++) {
        sb.append("#").append(i);
        sb.append("(pid ").append(event.getPointerId(i));
        sb.append(")=").append((int) event.getX(i));
        sb.append(",").append((int) event.getY(i));
        if (i + 1 < event.getPointerCount())
            sb.append(";");
        }
        sb.append("]");
        Log.d(TAG, sb.toString());
    }

    //Determine the space between the first two fingers
    private float spacing(MotionEvent event) {
        float x = event.getX(0) - event.getX(1);
        float y = event.getY(0) - event.getY(1);
        return FloatMath.sqrt(x * x + y * y);
    }

    // Calculate the mid point of the first two fingers 
    private void midPoint(PointF point, MotionEvent event) {
        float x = event.getX(0) + event.getX(1);
        float y = event.getY(0) + event.getY(1);
        point.set(x / 2, y / 2);
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我恋#小黄人 2024-12-08 12:06:56

位置没有改变!如果您仔细观察链接的图像,您会发现您的手指画并没有相对于照片的一角移动。换句话说,您保存的是绘图相对于屏幕的位置,而不是相对于照片当前滚动位置的位置。

保存时,您必须考虑背景照片被裁剪和/或缩放的事实。

The position does not change! If you look closely at your linked images, you'll see that your fingerpainting does not move relative to the corner of the photo. In other words, you are saving the drawings' positions relative to the screen rather than relative to the current scroll position of the photo.

When you save, you have to take into account the fact that the background photo is cropped and/or scaled.

你又不是我 2024-12-08 12:06:56

保持绘画/擦除模式。处于绘画/擦除模式时,禁止平移和缩放。当关闭绘制/擦除时,获取绘图缓存并将其设置为imageview。现在,所做的更改将永久保留在位图中。因此,您可以立即平移/缩放,然后再次进入绘画/擦除模式以进一步编辑。

Maintain a paint/erase mode. When in paint/erase mode, disallow panning and zooming. When paint/erase is turned off, get the drawing cache and set it to imageview. Now the changes are permanently in the bitmap. So you can pan/zoom now and again enter the paint/erase mode to edit further.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文