繁体   English   中英

使用画布在图像而非空白上绘画

[英]Draw paint over image not blank space using canvas

我试图在图像上画线,效果很好,但是我遇到了一些问题。 问题是我只想在图像上画线,而不是空白。 这是我在此声明的sizechanged方法的代码。

class DrawingPaint extends View implements View.OnTouchListener {

private Canvas mCanvas;
private Path mPath;
private Paint mPaint, mBitmapPaint;
public ArrayList<PathPoints> paths = new ArrayList<PathPoints>();
private ArrayList<PathPoints> undonePaths = new ArrayList<PathPoints>();
private Bitmap mBitmap;
private int color;
private int x, y;
private String textToDraw = null;
private boolean isTextModeOn = false;
int lastColor = 0xFFFF0000;
static final float STROKE_WIDTH = 15f;
Matrix m;
int imageHeight,imageWidth;

public DrawingPaint(Context context/*, int color*/) {
    super(context);
    //this.color = color;
    setFocusable(true);
    setFocusableInTouchMode(true);

    this.setOnTouchListener(this);

    mBitmapPaint = new Paint(Paint.DITHER_FLAG);
    /*mPaint = new Paint();
    mPaint.setAntiAlias(true);
    mPaint.setDither(true);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeJoin(Paint.Join.ROUND);
    mPaint.setStrokeCap(Paint.Cap.ROUND);
    mPaint.setStrokeWidth(STROKE_WIDTH);
    mPaint.setTextSize(30);

    mPath = new Path();
    paths.add(new PathPoints(mPath, color, false));
    mCanvas = new Canvas();*/
}

public void colorChanged(int color) {
    this.color = color;
    mPaint.setColor(color);
}

public void setColor(int color) {

    mPaint = new Paint();
    this.color = color;
    mPaint.setAntiAlias(true);
    mPaint.setDither(true);
    mPaint.setColor(color);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeJoin(Paint.Join.ROUND);
    mPaint.setStrokeCap(Paint.Cap.ROUND);
    mPaint.setStrokeWidth(STROKE_WIDTH);
    mPaint.setTextSize(30);

   mPath = new Path();
   paths.add(new PathPoints(mPath, color, false));
   mCanvas = new Canvas();

}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    // mBitmap = AddReportItemActivity.mPhoto;
    mBitmap = CustomGalleryHandler.getmInstance().getBitmapSend();
    float xscale = (float) w / (float) mBitmap.getWidth();
    float yscale = (float) h / (float) mBitmap.getHeight();
    if (xscale > yscale) // make sure both dimensions fit (use the
        // smaller scale)
        xscale = yscale;
    float newx = (float) w * xscale;
    float newy = (float) h * xscale; // use the same scale for both
    // dimensions
    // if you want it centered on the display (black borders)
    /*mBitmap = Bitmap.createScaledBitmap(mBitmap, this.getWidth(),
            this.getHeight(), true);*/
    // mCanvas = new Canvas(mBitmap);

    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(new File(PreferenceForCustomCamera.getInstance().getImagePathForGalleryFullScreen()).getAbsolutePath(), options);
    imageHeight = options.outHeight;
    imageWidth = options.outWidth;

     m = new Matrix();
    RectF drawableRect = new RectF(0, 0, imageWidth, imageHeight);
    //onMeasure(imageWidth,imageHeight);
    RectF viewRect = new RectF(0, 0, w, h);
    m.setRectToRect(drawableRect, viewRect, Matrix.ScaleToFit.CENTER);

    mBitmap = Bitmap.createBitmap(mBitmap,0,0,imageWidth,
            imageHeight, m,true);

}

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    int width = MeasureSpec.getSize(widthMeasureSpec);
    int height = MeasureSpec.getSize(heightMeasureSpec);

    setMeasuredDimension(width, height);
    //setMeasuredDimension(this.getWidth(), this.getHeight());
    //setMeasuredDimension(560, 100);even though give a ensured size, it can't //anyway.
}

@Override
protected void onDraw(Canvas canvas) {
    float[] pts = {0, 0};
    m.mapPoints(pts);
    canvas.drawBitmap(mBitmap, pts[0], pts[1], mBitmapPaint);
   // canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
    for (PathPoints p : paths) {
        mPaint.setColor(p.getColor());
        Log.v("", "Color code : " + p.getColor());
        if (p.isTextToDraw()) {
            canvas.drawText(p.textToDraw, p.x, p.y, mPaint);
        } else {
            canvas.drawPath(p.getPath(), mPaint);
        }
    }
}

private float mX, mY;
private static final float TOUCH_TOLERANCE = 0;

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);
    // commit the path to our offscreen
    mCanvas.drawPath(mPath, mPaint);
    // kill this so we don't double draw
    mPath = new Path();
    paths.add(new PathPoints(mPath, color, false));

}

private void drawText(int x, int y) {

    this.x = x;
    this.y = y;
    paths.add(new PathPoints(color, textToDraw, true, x, y));
    // mCanvas.drawText(textToDraw, x, y, mPaint);
}

@Override
public boolean onTouch(View arg0, MotionEvent event) {
    float x = event.getX();
    float y = event.getY();

    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            if (!isTextModeOn) {
                touch_start(x, y);
                invalidate();
            }
            break;
        case MotionEvent.ACTION_MOVE:
            if (!isTextModeOn) {
                touch_move(x, y);
                invalidate();
            }
            break;
        case MotionEvent.ACTION_UP:
            if (isTextModeOn) {
                drawText((int) x, (int) y);
                invalidate();
            } else {
                touch_up();
                invalidate();
            }
            break;
    }
    return true;
}

public void onClickUndo() {
    try {
        if (paths.size() > 0) {
            undonePaths.add(paths.remove(paths.size() - 1));
            invalidate();
        } else {

        }
    } catch (Exception e) {
        e.toString();
    }

}

public void onClickRedo() {
    try {

       if (undonePaths.size() > 0) {
            paths.add(undonePaths.remove(undonePaths.size() - 1));
            invalidate();
        } else {

        }
    } catch (Exception e) {
        e.toString();
    }
}


/*class PathPoints {
    private Path path;
    // private Paint mPaint;
    private int color;
    private String textToDraw;
    private boolean isTextToDraw;
    private int x, y;

    public PathPoints(Path path, int color, boolean isTextToDraw) {
        this.path = path;
        this.color = color;
        this.isTextToDraw = isTextToDraw;
    }

    public PathPoints(int color, String textToDraw, boolean isTextToDraw,
                      int x, int y) {
        this.color = color;
        this.textToDraw = textToDraw;
        this.isTextToDraw = isTextToDraw;
        this.x = x;
        this.y = y;
    }

    public Path getPath() {
        return path;
    }

    public void setPath(Path path) {
        this.path = path;
    }

    public int getColor() {
        return color;
    }

    public void setColor(int color) {
        this.color = color;
    }

    public String getTextToDraw() {
        return textToDraw;
    }

    public void setTextToDraw(String textToDraw) {
        this.textToDraw = textToDraw;
    }

    public boolean isTextToDraw() {
        return isTextToDraw;
    }

    public void setTextToDraw(boolean isTextToDraw) {
        this.isTextToDraw = isTextToDraw;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

}*/

}

也许您想自己从ImageView扩展自定义视图。

public class Line extends ImageView {

private static final String TAG = "Line";
private Paint lineDraw = null;

private int mStartX = 0;
private int mStartY = 0;
private int mEndX = 0;
private int mEndY = 0;
private float mStrokeWidth = 0;

public Line(Context context) {
    super(context);

    init_Paint();
}

public Line(Context context, AttributeSet attrs) {
    super(context, attrs);

    init_Attributes(context, attrs);

    init_Paint();
}

public Line(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);

    init_Attributes(context, attrs);

    init_Paint();
}

private void init_Paint()
{
    lineDraw = new Paint(Paint.ANTI_ALIAS_FLAG);

    lineDraw.setStyle(Paint.Style.FILL);
    lineDraw.setColor(Color.BLACK);
    lineDraw.setStrokeWidth(mStrokeWidth);
}

private void init_Attributes(Context context, AttributeSet attrs)
{
    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Line);
    mStartX = a.getInteger(R.styleable.Line_startX, 0);
    mStartY = a.getInteger(R.styleable.Line_startY, 0);
    mEndX = a.getInteger(R.styleable.Line_endX, 0);
    mEndY = a.getInteger(R.styleable.Line_endY, 0);

    mStrokeWidth = a.getDimension(R.styleable.Line_strokeWidth, 0);

    a.recycle();
}

public void setStartX(int startX)
{
    this.mStartX = startX;
}

public void setStartY(int startY)
{
    this.mStartY = startY;
}

public void setEndX(int endX)
{
    this.mEndX = endX;
}

public void setEndY(int endY)
{
    this.mEndY = endY;
}

public void setStrokeWidth(float strokeWidth)
{
    this.mStrokeWidth = strokeWidth;
}

@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
    int width = MeasureSpec.getSize(widthMeasureSpec);
    int height = MeasureSpec.getSize(heightMeasureSpec);

    setMeasuredDimension(width, height);
}

@Override
public void onDraw(Canvas canvas)
{
    //Call ImageView's default onDraw() method.
    super.onDraw(canvas);

    // You can instead use canvas.drawPath();
    canvas.drawLine(mStartX, mStartY, mEndX, mEndY, lineDraw);
}
}

在您的attr.xml添加以下内容。

<resources>
    <declare-styleable name="Line">
        <attr name="startX" format="integer" />
        <attr name="endX" format="integer" />
        <attr name="startY" format="integer" />
        <attr name="endY" format="integer" />
        <attr name="strokeWidth" format="dimension" />
    </declare-styleable>
</resources>

您可以像这样使用它。

<views.customview.Line
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:startX="5"
    app:startY="5"
    app:endX="500"
    app:endY="500"
    app:strokeWidth="15dp"
    android:src="@drawable/add_bookmark"
    />

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM