繁体   English   中英

如何使用画布设置仅绘制图像形状

[英]How to set Paint only image shape using Canvas

我正在用android做绘画应用程序。 我能够在画布上显示图片并能够绘画。 我只需要在图像中绘制,例如像市场colorfy,着色兔子,快乐动物园这样的应用程序。 我不确定如何完成这项任务。 需要您的建议。

这是我的代码。

activity_main.xml中

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"
android:background="#FFF">

<ImageView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:src="@drawable/bug"/>

<code.android.com.kidscolorbook.DrawingPad
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/drawingPad"
    android:textColor="#FFFFFF"
    android:cursorVisible="true"
    />
<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/btnClear"
    android:layout_gravity="bottom|center"
    android:text="Clear Canvas"/>

MainActivity.java

public class MainActivity extends AppCompatActivity {

DrawingPad drawingPad;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Settings.System.putInt(getBaseContext().getContentResolver(),
            "show_touches", 1);
    drawingPad = (DrawingPad) findViewById(R.id.drawingPad);
   // drawingPad.setBackgroundResource(R.drawable.bug);
    Button btnClear = (Button) findViewById(R.id.btnClear);
    btnClear.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            drawingPad.clearCanvas();
        }
    });
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}

@Override
protected void onPause() {
    super.onPause();
    Settings.System.putInt(getBaseContext().getContentResolver(),
            "show_touches", 0);

}}

Drawingpad.java

public class DrawingPad extends View {

private Context mContext;
private Path mPath;
private Paint mPaint;

private Bitmap mBitmap;
private Canvas mCanvas;

private float mX,mY;
private static final float TOLERANCE = 5;

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

    this.mContext = context;
    mPath = new Path();
    mPaint = new Paint();

    mPaint.setAntiAlias(true);
    mPaint.setColor(Color.RED);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeJoin(Paint.Join.ROUND);
    mPaint.setStrokeWidth(50f);


}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    Resources resources = getResources();
    mBitmap = BitmapFactory.decodeResource(resources, R.drawable.circle);
    mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
    mCanvas = new Canvas(mBitmap);

}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.drawPath(mPath, mPaint);

}


@Override
public boolean onTouchEvent(MotionEvent event) {

    float x = event.getX();
    float y = event.getY();


    switch (event.getAction()){
        case MotionEvent.ACTION_DOWN :
            startTouch(x, y);
            invalidate();
            break;
        case MotionEvent.ACTION_MOVE:
            moveTouch(x, y);
            invalidate();
            break;
        case MotionEvent.ACTION_UP:
            upTouch(mX,mY);
            invalidate();
            break;

    }

    return true;
}

private void startTouch(float x,float y){
    mPath.moveTo(x,y);
    mX = x;
    mY = y;
}

private void moveTouch(float x,float y)
{
    float dx = Math.abs(x - mX);
    float dy = Math.abs(y - mY);
    System.out.print("******"+x+y);
    if(dx >= TOLERANCE || dy>= TOLERANCE){
        mPath.quadTo(mX,mY,(x+mX)/2,(y+mY)/2);

        mX = x;
        mY = y;
    }
}

private void upTouch(float x, float y)
{
    mPath.lineTo(x,y);
}

public void clearCanvas()
{
    mPath.reset();
    invalidate();
}}

我的输出:

在此处输入图片说明

我只需要在图像中绘制特定形状的图像,而不会散布颜色。(我知道我们可以减小笔画宽度),但是如果您可以看一下上面提到的应用,您可能会完全理解问题。

需要您的建议,例如我们如何实现这种功能。

提前致谢。

我有同样的问题,经过长期研究,我发现解决方案FloodFill Pattern的一部分吗? 这是什么意思:这意味着当您在图像的任何一点上单击具有相同颜色(targetColor)->在我们的情况下为白色,它将转换为(replacementColor)->无论您使用哪种颜色, mPaint都为红色,这是您可能需要进行一些更改的代码

@Override
public boolean onTouchEvent(MotionEvent event) {

    float x = event.getX();
    float y = event.getY();


    switch (event.getAction()){
        case MotionEvent.ACTION_DOWN :
            startTouch(x, y);
            int sourceColor = bgImg.getPixel((int) x, (int) y);
            int desColor = paint.getColor();
            // pass the bitmap you want paint
            FloodFill(  mBitmap , new Point((int) x, (int) y) , sourceColor , desColor  );
            invalidate();
            break;
        case MotionEvent.ACTION_MOVE:
            moveTouch(x, y);
            invalidate();
            break;
        case MotionEvent.ACTION_UP:
            upTouch(mX,mY);
            invalidate();
            break;

    }

    return true;
}



private void FloodFill(Bitmap bmp, Point pt, int targetColor, int replacementColor) {
        Queue<Point> q = new LinkedList<Point>();
        q.add(pt);
        while (q.size() > 0) {
            Point n = q.poll();
            if (bmp.getPixel(n.x, n.y) != targetColor)
                continue;

            Point w = n, e = new Point(n.x + 1, n.y);
            while ((w.x > 0) && (bmp.getPixel(w.x, w.y) == targetColor)) {
                bmp.setPixel(w.x, w.y, replacementColor);
                if ((w.y > 0) && (bmp.getPixel(w.x, w.y - 1) == targetColor))
                    q.add(new Point(w.x, w.y - 1));
                if ((w.y < bmp.getHeight() - 1)
                        && (bmp.getPixel(w.x, w.y + 1) == targetColor))
                    q.add(new Point(w.x, w.y + 1));
                w.x--;
            }
            while ((e.x < bmp.getWidth() - 1)
                    && (bmp.getPixel(e.x, e.y) == targetColor)) {
                bmp.setPixel(e.x, e.y, replacementColor);

                if ((e.y > 0) && (bmp.getPixel(e.x, e.y - 1) == targetColor))
                    q.add(new Point(e.x, e.y - 1));
                if ((e.y < bmp.getHeight() - 1)
                        && (bmp.getPixel(e.x, e.y + 1) == targetColor))
                    q.add(new Point(e.x, e.y + 1));
                e.x++;
            }
        }
    }

暂无
暂无

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

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