我在android中做一个绘画应用程序。我能够在画布上展示一幅画,并能够画画。我只需要在图像中绘制,就像市场上的应用程序colorfy,Coloring Bunny,Happy Zoo那样。我不确定如何实现这项任务。需要你的建议。
这是我的代码。
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();
}}
我的输出:
我只需要在图像和特定形状上绘制而不会散布颜色。(我知道我们可以减少笔划宽度)但是如果你能看一下上面提到的应用程序,你可能会完全理解这个问题。
需要你的建议,比如我们如何才能实现这种功能。
提前致谢。
答案 0 :(得分:1)
我有同样的问题,经过长时间的研究,我认为解决方案FloodFill
模式的一部分?这意味着什么:这意味着当你在图像的任何一点点击都有相同的颜色(targetColor) - &gt;在我们的例子中是白色,它转换为(replacementColor) - &gt;如果您的情况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++;
}
}
}