Android simple paint - android

Why it doesn't work properly ? I'm trying to "paint" where i put my finger, to write something. For example, when i am trying to make a C he looks like this: http://postimg.org/image/5obyif4o1/ ........................................................................
I think the mX and the mY from touch_move function remain the same from touch_start.
public class BlackPixel extends View implements OnTouchListener{
private Bitmap mBitmap;
Canvas mCanvas=new Canvas();
Path mPath=new Path();
Paint mBitmapPaint=new Paint(Paint.DITHER_FLAG);
Paint mPaint=new Paint();
Paint circlePaint=new Paint();
Path circlePath = new Path();
Context context;
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
}
public BlackPixel(Context context) {
super(context);
setFocusable(true);
setFocusableInTouchMode(true);
this.setOnTouchListener(this);
}
#Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
canvas.drawBitmap( mBitmap, 0, 0, mBitmapPaint);
canvas.drawPath( mPath, mPaint );
canvas.drawPath( circlePath,circlePaint );
}
// #Override
public boolean onTouch(View v, MotionEvent event) {
float x=event.getX();
float y=event.getY();
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
touch_start(x,y);
invalidate();
return true;
case MotionEvent.ACTION_MOVE:
touch_move(x,y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touch_up(x,y);
invalidate();
break;
}
return true;
}
private void touch_start(float x, float y)
{
mPath.reset();
mPath.moveTo(x, y);
mX = x;
mY = y;
}
private float mX,mY;
private static final float TOUCH_TOLERANCE = 4;
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(float x , float y)
{
mPath.lineTo(mX, mY);
// commit the path to our offscreen
mCanvas.drawPath(mPath, mPaint);
// kill this so we don't double draw
mPath.reset();
}
class Point
{
float x,y;
}

quadTo(float x1, float y1, float x2, float y2)
Add a quadratic bezier from the last point, approaching control point (x1,y1), and ending at (x2,y2).
That is, your control point in touch_move() is (mX, mY). You always draw a line from (mX, mY) to ((x + mX)/2, (y + mY)/2).

Related

Draw color using finger on custom view in android

I am working in a app, in which I have to develop ALPHABETS, one alphabet in one screen, and so on.
when some one move finger over the Alphabet, it draws color over the alphabet.
The color is visible only over the alphabet, not over the background of the screen.
I wish i can post screenshot. please refer this app for more information-
https://play.google.com/store/apps/details?id=kr.co.smartstudy.phonicsiap_android_googlemarket
in this app we draw alphabet. Same I want to draw.
I have no idea how to develop it, if anyone have some idea in it, please help me.
I am answering to my question.
My requirement was to draw only over the ALPHABETS. I achieved this functionality by creating custom view with override draw method.
Below is my code snippet:
public class DrawingView extends View{
private final Paint mAlphaPaint;
private final Paint clearPaint;
public int width;
public int height;
private Bitmap mBitmap;
private Canvas mCanvas,mCanvasWhite;
private Path mPath,alphaPath;
private Paint mBitmapPaint;
Context context;
private Paint circlePaint;
private Path circlePath;
private Bitmap mBitmapWhite;
public DrawingView(Context c) {
super(c);
context = c;
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
circlePaint = new Paint();
circlePath = new Path();
circlePaint.setAntiAlias(true);
circlePaint.setColor(Color.BLUE);
circlePaint.setStyle(Paint.Style.STROKE);
circlePaint.setStrokeJoin(Paint.Join.ROUND);
circlePaint.setStrokeCap(Paint.Cap.ROUND);
circlePaint.setStrokeWidth(110f);
DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
width = displayMetrics.widthPixels;
height = displayMetrics.heightPixels;
alphaPath = new Path();
alphaPath.moveTo(width*.5f, height*0.1f);
alphaPath.lineTo(100, 100);
alphaPath.lineTo(100, 150);
alphaPath.lineTo(width/2, height/2);
alphaPath.lineTo(100, height - 300);
mAlphaPaint = new Paint();
mAlphaPaint.setAntiAlias(true);
mAlphaPaint.setColor(Color.WHITE);
mAlphaPaint.setStyle(Paint.Style.STROKE);
mAlphaPaint.setStrokeJoin(Paint.Join.ROUND);
mAlphaPaint.setStrokeCap(Paint.Cap.ROUND);
mAlphaPaint.setStrokeWidth(220f);
clearPaint = new Paint();
clearPaint.setStyle(Paint.Style.STROKE);
clearPaint.setStrokeJoin(Paint.Join.ROUND);
clearPaint.setStrokeCap(Paint.Cap.ROUND);
clearPaint.setStrokeWidth(220f);
clearPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
clearPaint.setColor(Color.TRANSPARENT);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mBitmap.eraseColor(Color.GREEN);
mCanvas = new Canvas(mBitmap);
mCanvas.drawPath(alphaPath, clearPaint);
mBitmapWhite = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mBitmapWhite.eraseColor(Color.WHITE);
mCanvasWhite = new Canvas(mBitmapWhite);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap(mBitmapWhite,0,0,circlePaint);
canvas.drawBitmap(mBitmap, 0, 0, circlePaint);
mCanvasWhite.drawPath(mPath, circlePaint);
}
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;
circlePath.reset();
circlePath.addCircle(mX, mY, 30, Path.Direction.CW);
}
}
private void touch_up() {
mPath.lineTo(mX, mY);
circlePath.reset();
// commit the path to our offscreen
mCanvasWhite.drawPath(mPath, circlePaint);
// kill this so we don't double draw
mPath.reset();
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
Log.d("onTouchEvent",x+","+y);
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;
}
}
Add this view in your layout. In it we can draw on line not on whole surface.
I hope it will help you.

Drawing Straight line in android using single pan tool or single finger scratches?

how can draw straight line using single finger or pan tool movement in android ?? when we draw one line through finger scratches, which is draw some zigzag. my exact Q? is that how to automatic straight ??
Hey ,i am using both quadTo() & lineTo() method but not exact straight line, plz improve that ANS.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
dv = new DrawingView(this);
setContentView(dv);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(Color.WHITE);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(4);
}
public class DrawingView extends View {
public int width;
public int height;
private Bitmap mBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint mBitmapPaint;
Context context;
private Paint circlePaint;
private Path circlePath;
public DrawingView(Context c) {
super(c);
context=c;
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
circlePaint = new Paint();
circlePath = new Path();
circlePaint.setAntiAlias(true);
circlePaint.setColor(Color.BLUE);
circlePaint.setStyle(Paint.Style.STROKE);
circlePaint.setStrokeJoin(Paint.Join.MITER);
circlePaint.setStrokeWidth(4f);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap( mBitmap, 0, 0, mBitmapPaint);
canvas.drawPath( mPath, mPaint);
canvas.drawPath( circlePath, circlePaint);
}
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;
circlePath.reset();
circlePath.addCircle(mX, mY, 30, Path.Direction.CW);
}
}
private void touch_up() {
mPath.lineTo(mX, mY);
circlePath.reset();
// commit the path to our offscreen
mCanvas.drawPath(mPath, mPaint);
// kill this so we don't double draw
mPath.reset();
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
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;
}
}
}
That's a BIG question, dude! If I were you, I'd start with a code sample like this. That will get you finger drawing non-straight lines on the Canvas. After that you, could start thinking about how to adapt this code to your purposes. Note that there are methods for touch_down and touch_up. You could experiment with redrawing a subset of the canvas each time touch_up is called, replacing whatever has been drawn since the last touch_down with a simple line (using canvas.lineTo()) that links the x/y on touch_down with the x/y on touch_up.

When Zooming the view,the canvas is cleared

I created one application. In that application I implementing the finger drawing using canavs.It works perfectly.But When i Zoom the View ,the finger drawing is cleared.how to avoid ths. If you have any idea,Kindly Share it. Thanks in advance
This is My Code:
This is for finger drawing
PageView.Java:
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
}
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);
// commit the path to our offscreen
mCanvas.drawPath(mPath, MuPDFActivity.mPaint);
// kill this so we don't double draw
mPath.reset();
}
#Override
public boolean onTouchEvent(MotionEvent event)
{
if(MuPDFActivity.onDrawModeFlag == 1)
{
float x = event.getX();
float y = event.getY();
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();
}
return true;
}
else
{
return false;
}
}
#Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
canvas.save();
//canvas.translate(mX, mY);
//canvas.scale(ReaderView.mScale, ReaderView.mScale);
System.out.println("On Canvas Calling");
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
canvas.drawPath(mPath,MuPDFActivity.mPaint);
}
MuPdfActivity:
In activity oncreate function, I call the paint feautures
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(0xFFFF0000);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(12);
mEmboss = new EmbossMaskFilter(new float[] { 1, 1, 1 },
0.4f, 6, 3.5f);
mBlur = new BlurMaskFilter(8, BlurMaskFilter.Blur.NORMAL);
I found the answer i removed one line in touch_up function mPath.reset(). And then i removed mPath.reset() in touch_start function.

Adding Undo and Deletion to FingerPaint.java

I have worked on the fingerpaint class before and I was very much comfortable but this time I found myself in deep trouble implementing both these functionalities of Undo and deletion
This is my drawing view
public class MyView extends View {
private Bitmap mBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint mBitmapPaint;
public MyView(Context c) {
super(c);
mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
}
#Override
protected void onDraw(Canvas canvas) {
/*canvas.drawColor(Color.WHITE);
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);*/
for (int i=0;i<paths.size();i++){
canvas.drawPath(paths.get(i).path, paths.get(i).paint);
}
canvas.drawPath(mPath, mPaint);
}
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;
private void touch_start(float x, float y)
{
if ( erase == true )
{
mPath.reset();
}
undonePaths.clear();
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 (check == 1 || (selectedId == ERASE_MENU_ID) )
{
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE)
{
mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);
mX = x;
mY = y;
mCanvas.drawPath(mPath, mPaint);
}
}
if(selectedId == ERASE_MENU_ID)
{
mCanvas.drawPath(mPath, mPaint);
mPath=new Path();
mX = x;
mY = y;
mPath.moveTo(x, y);
}
}
public void onClickUndo () {
if (paths.size()>0)
{
paths.remove(paths.size()-1);
invalidate();
}
else
{
}
//toast the user
}
private void touch_up() {
mCanvas.drawPath(mPath, mPaint);
MyDataHolder md=new MyDataHolder();
md.paint=mPaint;
md.path=mPath;
paths.add(md);
mPath=new Path();
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
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;
}
}
Now the problem is when I change mPaint's mode to clear
erase=true;
mPaint.setXfermode(null);
mPaint.setStrokeWidth(25.0f);
//mPaint.setColor(Color.TRANSPARENT);
mPaint.setXfermode(new PorterDuffXfermode(Mode.CLEAR));
every drawn path turns black with 25 width somebody suggested that I am using same paint so I made a wrapper class to store paint and path object but it's not working.
I can help you with Deletion (Clearing the screen). It's pretty simple and basic approach.
Create a Boolean variable (say mclears). set this to true when your "Clear" button is pressed.
in ondraw(), use
if(clears){
myBitmap.eraseColor(bcolor);
//Sets your canvas (bitmap) color to your background color. i.e. clears canvas
clears=false;
}
You may have to change your Touch_up method a bit. like
private void touch_up() {
mCanvas.drawPath(mPath, mPaint);
MyDataHolder md=new MyDataHolder();
mPath.reset();
md.paint=mPaint;
md.path=mPath;
paths.add(md);
mPath=new Path();
}
I have implemented this in my app. Hope it works for you.

tracing a font in canvas

I am creating an android app where in a user can learn to write alphabet. My requirements are like this:
An alphabet is displayed on canvas using Paint.drawText().
User will move his finger on the alphabet to trace it.
I am able to complete the above two requirements.
Now what I want is: if the user is touching his finger anywhere other than the alphabet region(path) it should vibrate/make a buzz.
The Question is: How do I come to know if the user is touching away from the alphabet path/region?
Here is the code snippet.
public class MyView extends View {
private static final float MINP = 0.25f;
private static final float MAXP = 0.75f;
private Bitmap mBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint mBitmapPaint;
public MyView(Context c) {
super(c);
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(0xFFAAAAAA);
Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
p.setTextSize(200);
p.setColor(Color.BLACK);
canvas.drawText("A", 300, 150, p);
// canvas.drawLine(mX, mY, Mx1, My1, mPaint);
// canvas.drawLine(mX, mY, x, y, mPaint);
canvas.drawPath(mPath, mPaint);
Path pa;
canvas.get
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
}
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;
}
mPath.lineTo(mX, mY);
vibe.vibrate(10);
}
private void touch_up() {
// commit the path to our offscreen
mCanvas.drawPath(mPath, mPaint);
// kill this so we don't double draw
mPath.reset();
vibe.cancel();
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
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();
// Mx1=(int) event.getX();
// My1= (int) event.getY();
invalidate();
break;
}
return true;
}
}

Categories

Resources