java - Android Java,在缩放的 Canvas 上绘制

标签 java android bitmap drawing android-canvas

我正在开发一个 android 绘图应用程序,它有一个带有自定义 View 的 relativelayout,用于绘图。到目前为止,一切正常,除了当我缩放 Canvas 时绘图发生在错误的位置,最好显示代码而不是试图解释它。是的,我尝试过使用 path.offset 但没有成功。主要问题是当你在它被放大时绘制它,虽然它绘制在正确的位置,路径太敏感,当你的手指居中时它很好但是如果你向上/向下或左右移动路径移动速度比你的手指还快。

package com.nick.sketchr;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.view.MotionEvent;
import android.view.View;

public class CustomCanvas extends View {
private Bitmap  mBitmap;
private Canvas  mCanvas;
private Path    mPath;
private Paint   mBitmapPaint;
private Paint   mPaint;
private float   old_scale;
private float   dmx,dmy;
private double  scale;
private long    timevar2;
private Rect    bounds;
public CustomCanvas(Context c) {
    super(c);
    mPath = new Path();
    mBitmapPaint = new Paint(Paint.DITHER_FLAG);
    mPaint = new Paint();
    mPaint.setAntiAlias(true);
    mPaint.setDither(true);
    mPaint.setColor(0xFF000000);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeJoin(Paint.Join.ROUND);
    mPaint.setStrokeCap(Paint.Cap.ROUND);
    mPaint.setStrokeWidth(3);
    dmx = Main_App.w/2/2;
    dmy = Main_App.h/2/2;
    scale = 1;
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    mBitmap = Bitmap.createBitmap(Main_App.w/2, Main_App.h/2, Bitmap.Config.ARGB_8888);
    mCanvas = new Canvas(mBitmap);
    mBitmap.eraseColor(Color.WHITE);
}

@Override
protected void onDraw(Canvas canvas) {
    float sc = (float) scale;
    canvas.scale(sc, sc, Main_App.w/2, Main_App.h/2);
    canvas.drawBitmap(mBitmap, dmx, dmy, mBitmapPaint);
    canvas.drawPath(mPath, mPaint);
}
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;

private void touch_start(float x, float y) {
    mPath.reset();
    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(y - mY);
    if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
        mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);
        mX = x;
        mY = y;
    }
}
private void touch_up() {
    mPath.lineTo(mX, mY);
    mPath.offset(-dmx, -dmy); //this is the problem area
    //also the path shows wrong when canvas is scaled... o_o
    mCanvas.drawPath(mPath, mPaint);
    mPath.reset();
}
@Override
public boolean onTouchEvent(MotionEvent event){
    float x = event.getX()/(float)scale+bounds.left;
    float y = event.getY()/(float)scale+bounds.top;
    if(event.getPointerCount() == 2){
        timevar2 = event.getEventTime();
        float newx = event.getX(0);
        float newy = event.getY(0);
        float oldx = event.getX(1);
        float oldy = event.getY(1);
        mPath.reset();
        float equa = (float) (Math.pow(newx - oldx, 2) + Math.pow(newy - oldy, 2));
        float cscale = (float) Math.sqrt(equa)/100;
        float scaled = (cscale - old_scale);
        if(scaled < -0.1){
            if(scale > 0.1){
              scale -= 0.03;
            }
        }
        if(scaled > 0.1){
            scale += 0.03;
        }
        dmx = (float) (((newx + oldx)/2)-(Main_App.w/2/2)*scale);
        dmy = (float) (((newy + oldy)/2)-(Main_App.h/2/2)*scale);
        old_scale = cscale;
        invalidate();
        return true;
    }
    long dt = event.getEventTime() - timevar2;
    if(dt < 100){
        return true;
    }
    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 clear(){
    mBitmap.eraseColor(Color.TRANSPARENT);
    invalidate();
    System.gc();
}
}

最佳答案

不完全确定,但您可能错误地缩放了 Canvas。而是尝试:

canvas.scale(width_of_canvas, height_of_canvas)

在您的 onDraw() 方法中。当前您使用的比例值为 1

关于java - Android Java,在缩放的 Canvas 上绘制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17162378/

相关文章:

java - 从 html 脚本标记调用 GWT Java 函数

java - 在真实设备中膨胀类 CoordinatorLayout 时出错,但模拟器工作

c# - 如何从字节数组创建位图?

c# - 在不加载图像的情况下使用图像的特定像素格式在 C# 中创建位图

java - 大输入上的慢速字符串连接

java - runtime.exec(batchCommand) - 文件夹中的空间问题

android - 将变量从服务传递到广播接收器

c++ - 在 C++ 中将彩色位图转换为灰度

java - 为 ListView 设置背景图像

java - android studio 中的 build.gradle 依赖