当前位置: 首页 > 知识库问答 >
问题:

油漆应用程序。2种油漆类型,实线和喷枪,喷枪绘制到mCanvas,只能看到实线当它被选中

岑彬炳
2023-03-14

默认是实线,我可以开始绘图,切换到Airbrush,一切看起来都很好。如果我切换回实线,喷枪画消失,但以前的实线画保留。如果我然后切换回Airbrush,先前的Airbrush绘图将再次出现,而先前的实线绘图将保留。在函数touch_up(event)中,In(line_type==SOLID_LINE),如果我注释掉

//mcanvas.drawpath(mPath,mPaint);

任何想法都将非常感谢!

我的onDraw函数

    @Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    if(line_type == SOLID_LINE){
        for (Pair<Path, Paint> p : paths) {
            canvas.drawPath(p.first, p.second);
        }
        canvas.drawPath(mPath, mPaint);
    }else if(line_type == AIRBRUSH){
        Log.d(DTAG, "onDraw: AIRBRUSH: no call");
        canvas.drawBitmap(mSourceBM, 0,0, null);
    }
}

我的初始化函数,用于上下文

    private void init(AttributeSet attrs, int defStyle) {
    if(line_type == SOLID_LINE){
        setSolidLine(); // various paint settings
    }else if(line_type == AIRBRUSH){
        setAirbrush(); // other paint settings
    }
}
    private void drawSplash(int x, int y)
{   
    mBrush.setBounds(x - strokeRadius, y - strokeRadius, x + strokeRadius, y + strokeRadius);
    mBrush.draw(mCanvas);
    //mPaint = mBrush.getPaint();
    //mCanvas.drawBitmap(mSourceBM, x, y, mPaint);

    //mCanvas.drawPaint(mPaint);
}

touch_start,从onTouchEvent调用

    private void touch_start(float x, float y) {
    if(line_type == SOLID_LINE){
        undonePaths.clear();// we clear the undonePaths because we are drawing
        mPath.reset();
        mPath.moveTo(x, y);
        mX = x;
        mY = y;
    }else if(line_type == AIRBRUSH){
        mPreviousX = x;
        mPreviousY = y;
        Log.d(DTAG, "touch_start");
    }
}

从onTouchEvent调用touch_move

private void touch_move(float x, float y) {
    if(line_type == SOLID_LINE){
        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;
        }
        // displayMemoryUsage("touch_move SOLID");
    }else if(line_type == AIRBRUSH){
        float mX = x;
        float mY = y;

        // get vector from previous to current position
        float xdist = mX - mPreviousX;
        float ydist = mY - mPreviousY;

        // get the length
        float segmentLength = (float) Math.sqrt(xdist * xdist + ydist * ydist);

        // derive a suitable step size from stroke width
        float stepSize = Math.max(strokeRadius / 10, 1f);

        // calculate the number of steps we need to take
        // NOTE: this draws a bunch of evenly spaced splashes from the start point
        // to JUST BEFORE the end point.
        int steps = Math.max(Math.round(segmentLength / stepSize), 2); 
        for(int i = 0; i < steps; ++i)
        {
            int currentX = (int) (mPreviousX + xdist * i / steps);
            int currentY = (int) (mPreviousY + ydist * i / steps);

            drawSplash(currentX, currentY);
        }
        //Log.d(DTAG, "touch_move: AIRBRUSH xdist, ydist: "+xdist+" "+ydist);
        // update the previous position
        mPreviousX = mX;
        mPreviousY = mY;
        //displayMemoryUsage("touch_move AIR");
        //Log.d(DTAG, "touch_move AIR: previous x y "+mX+" "+mY);
    }
}

从onTouchEvent调用touch_up

    private void touch_up(MotionEvent event) {
    if(line_type == SOLID_LINE){
        mPath.lineTo(mX, mY);
        // commit the path to our offscreen
        mCanvas.drawPath(mPath, mPaint);
        // kill this so we don't double draw
        Paint newPaint = new Paint(mPaint);
        paths.add(new Pair<Path, Paint>(mPath, newPaint));
        mPath = new Path();
    }else if(line_type == AIRBRUSH){
        drawSplash((int) event.getX(), (int)event.getY());
    }
}

该活动设置位图。实际上我不使用BitmapDrawable。只是初始化Airbrush画布的位图mCanvas。

    /**
 * Sets the Canvas Bitmap we intend to modify
 */
public boolean setCanvasBitmapDrawable(BitmapDrawable bitmapdrawable, Bitmap sourceBM, int left_bound, int top_bound) {
    // supply bounds as parameters
    mSourceBM = sourceBM;
    // mSourceBM = convertToMutable(this, mSourceBM);

    bmDrawable = bitmapdrawable;
    mCanvas = new Canvas(mSourceBM);
    //bmDrawable.setBounds(left_bound, top_bound, bitmapdrawable.getIntrinsicWidth()+left_bound, bitmapdrawable.getIntrinsicHeight()+top_bound);

    invalidate();
    return true;
}

共有1个答案

督辉
2023-03-14
   @Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

        for (Pair<Path, Paint> p : paths) {
            canvas.drawPath(p.first, p.second);
        }
        canvas.drawPath(mPath, mPaint);

        Log.d(DTAG, "onDraw: AIRBRUSH: no call");
        canvas.drawBitmap(mSourceBM, 0,0, null);
    }

上面陈述中的如果使它只抽到一个或另一个。将它们从ondraw中取出,您的ontouch中的if语句将足以显示您使用的是哪种类型,并且它应该可以很好地工作

 类似资料:
  • 本章介绍Canvas组件,用它来生成简单的二维(2D)图形,目标是创建一个PaintPot(油漆桶)应用,让用户在手机屏幕上绘制图画,并让用户用手机给自己拍照,然后在自己的照片上绘图。回顾历史,早在20世纪70年代,PaintPot是最早运行在个人电脑上的应用之一,目的是为了证明个人电脑的潜力。那时候,开发这样一款简单的绘图应用是一项极其复杂的工作,而且绘图效果也略显粗糙。但现在,使用App In

  • 本文向大家介绍Unity实现喷漆效果,包括了Unity实现喷漆效果的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了Unity实现喷漆效果展示的具体代码,供大家参考,具体内容如下 喷漆功能 **应用场景:**如墙上的标语贴花,汽车上的喷漆等。 选择方案: 1、当然实现方法各式各异,最最最简单,也是最“不堪入目”的方法是直接给一个面片,然后获取喷漆位置,加上一个要喷漆表面法线方向的偏移,

  • 问题内容: 对不起,我进行了大量搜索,以查找这3个功能(绘画,重绘,paintComponent)之间如何相互作用,但我不知道。您能准确解释一下它们何时被调用(因为有时java会在没有我问他的情况下调用它),它们到底在做什么,它们之间有什么区别。谢谢 问题答案: 我不确定“ paint”,但是我可以解释repaint()和paintComponent()之间的关系。 根据我在Java方面的有限经验

  • 我试图编写一个小迷宫运行程序,遇到了一些与绘图组件()相关的麻烦。我已经完成了调试,出于某种原因,我的绘图组件()从未被调用,即使是由我的计时器调用的重新绘制()。 这些是我的frame和jpanel init方法。 这是我的paintComponent,图像确实已缓冲并已存储。 这就是我的ActionExecuted,它是用我的计时器调用的,默认设置为5秒的间隔。 } 如果你感兴趣,这是我的完整

  • 我正在创建html5绘画应用程序,目前正在处理混合层。我想知道在这样的程序中,哪种方法是最好的(最快的和类似gimp/photoshop的)。我的层(画布)是堆叠的。 通过CSS3属性更改混合模式(可能非常快-直接在显卡上混合) 具有隐藏的画布(图层)和一个画布来向用户显示平坦的图像。所以我们画在这些隐藏的画布上,有一些机制将每个隐藏的画布绘制到用户可见的画布上(可能较慢,但每个context.d

  • 在这种情况下,第一个坐标应该是0,0,而不是8,30。我做错了什么(我在使用NetBeans)