Related
I want to remove the background of photo .but not able to find anything relevant actually I want this type of application https://play.google.com/store/apps/details?id=com.outthinking.bgeraser
of feature in android java code remove the background.
My code is :
public class FingerText extends Activity
{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new MyView(this));
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
//this is the line that sets the initial pen color
mPaint.setColor(inkColor);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(2);
}
private Paint mPaint;
private Bitmap mBitmap;
private boolean inkChosen;
private int bgColor = 0x00000000; //set initial bg color var to white
private int inkColor = 0xFF000000; //set initial ink color var to black
public void colorChanged(int color) {
//This is the implementation of the interface from colorpickerdialog.java
if (inkChosen) {
mPaint.setColor(color);
inkColor = color;
} else {
mBitmap.eraseColor(color);
bgColor = color;
//set the color to the user's last ink color choice
mPaint.setColor(inkColor);
}
}
public class MyView extends View {
private Canvas mCanvas;
private Path mPath;
private Paint mBitmapPaint;
public MyView(Context c) {
super(c);
mBitmap = Bitmap.createBitmap(320, 480, Bitmap.Config.ARGB_8888);
//this sets the bg color for the bitmap
mBitmap.eraseColor(bgColor);
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) {
//this is the line that changes the bg color in the initial canvas
canvas.drawColor(bgColor);
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
canvas.drawPath(mPath, mPaint);
canvas.drawBitmap(((BitmapDrawable)getResources().getDrawable(
R.drawable.ic_alphabets)).getBitmap(),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;
}
}
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.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;
}
}
private static final int BG_COLOR_ID = Menu.FIRST;
private static final int INK_MENU_ID = Menu.FIRST + 1;
private static final int CLEAR_MENU_ID = Menu.FIRST + 2;
private static final int ERASER_MENU_ID = Menu.FIRST + 3;
private static final int SEND_MENU_ID = Menu.FIRST + 4;
#Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(0, BG_COLOR_ID, 0, "Background Color").setShortcut('3', 'b');
menu.add(0, INK_MENU_ID, 0, "Ink Color").setShortcut('4', 'c');
menu.add(0, CLEAR_MENU_ID, 0, "Clear All").setShortcut('5', 'e');
menu.add(0, ERASER_MENU_ID, 0, "Eraser").setShortcut('6', 'x');
menu.add(0, SEND_MENU_ID, 0, "Send").setShortcut('7', 's');
return true;
}
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
mPaint.setXfermode(null);
mPaint.setAlpha(0xFF);
switch (item.getItemId()) {
case BG_COLOR_ID:
inkChosen = false;
return true;
case INK_MENU_ID:
inkColor = mPaint.getColor();
inkChosen = true;
return true;
case CLEAR_MENU_ID:
mBitmap.eraseColor(bgColor);
return true;
case ERASER_MENU_ID:
//set pen color to bg color for 'erasing'
mPaint.setColor(bgColor);
return true;
case SEND_MENU_ID:
FileInputStream ifs;
try {
FileOutputStream fs = openFileOutput("message_image", Context.MODE_PRIVATE);
mBitmap.compress(Bitmap.CompressFormat.PNG, 100, fs);
ifs = openFileInput("message_image");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return true;
}
// inserts file pointed to by ifs into image gallery
String url = MediaStore.Images.Media.insertImage(getContentResolver(),
BitmapFactory.decodeStream(ifs),
"Message image1", "Message image");
Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.putExtra("sms_body", "Message created using FingerText");
sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse(url));
sendIntent.setType("image/png");
startActivity(sendIntent);
bgColor = 0xFFFFFFFF; //set bg color var back to white
inkColor = 0xFF000000; //set ink color var back to black
mBitmap.eraseColor(bgColor);
return true;
}
return super.onOptionsItemSelected(item);
}
}
Please Help Me Thanks in advance.
i am done it here is my code use as it is:
public class DrawView extends View implements View.OnTouchListener {
private ArrayList<PathPoints> paths = new ArrayList<PathPoints>();
private ArrayList<PathPoints> undonePaths = new ArrayList<PathPoints>();
private Path mPath;
private int x = 0;
private int y = 0;
Bitmap bitmap;
Bitmap bitmap2;
Canvas bitmapCanvas;
Drawable d;
private final Paint paint = new Paint();
private final Paint eraserPaint = new Paint();
Matrix matrix;
// We can be in one of these 3 states
static final int NONE = 0;
static final int DRAG = 1;
static final int ZOOM = 2;
int mode = NONE;
// Remember some things for zooming
PointF last = new PointF();
PointF start = new PointF();
float minScale = 1f;
float maxScale = 3f;
float[] m;
int viewWidth, viewHeight;
static final int CLICK = 3;
float saveScale = 1f;
protected float origWidth, origHeight;
int oldMeasuredWidth, oldMeasuredHeight;
ScaleGestureDetector mScaleDetector;
Context context;
public DrawView(Context context) {
super(context);
setFocusable(true);
setFocusableInTouchMode(true);
this.setOnTouchListener(this);
// Set background
this.setBackgroundResource(R.drawable.transparentbg);
// Set bitmap
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.shert).copy(Bitmap.Config.ARGB_8888, true);
bitmap = Bitmap.createScaledBitmap(bitmap, 600, 900, true);
bitmapCanvas = new Canvas();
bitmapCanvas.setBitmap(bitmap);//Bitmap.createScaledBitmap(bitmap, 350,400, true)
bitmapCanvas.drawColor(Color.TRANSPARENT);
// Set eraser paint properties
eraserPaint.setColor(Color.TRANSPARENT);
eraserPaint.setAlpha(0);
eraserPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
eraserPaint.setAntiAlias(true);
mPath = new Path();
paths.add(new PathPoints(mPath, Color.TRANSPARENT, false));
}
#Override
public void onDraw(Canvas canvas) {
canvas.drawColor(Color.TRANSPARENT);
bitmapCanvas.drawColor(Color.TRANSPARENT);
bitmapCanvas.drawCircle(x, y, 20, eraserPaint);
canvas.drawBitmap(bitmap, 0, 0, paint);
}
public boolean onTouch(View view, MotionEvent event) {
x = (int) event.getX();
y = (int) 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;
}
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
bitmapCanvas.drawPath(mPath, eraserPaint);
// kill this so we don't double draw
mPath = new Path();
paths.add(new PathPoints(mPath, Color.TRANSPARENT, false));
}
public static Bitmap scaleDown(Bitmap realImage, float maxImageSize,
boolean filter) {
float ratio = Math.min(
(float) maxImageSize / realImage.getWidth(),
(float) maxImageSize / realImage.getHeight());
int width = Math.round((float) ratio * realImage.getWidth());
int height = Math.round((float) ratio * realImage.getHeight());
Bitmap newBitmap = Bitmap.createScaledBitmap(realImage, width,
height, filter);
return newBitmap;
}
void fixTrans() {
matrix.getValues(m);
float transX = m[Matrix.MTRANS_X];
float transY = m[Matrix.MTRANS_Y];
float fixTransX = getFixTrans(transX, viewWidth, origWidth * saveScale);
float fixTransY = getFixTrans(transY, viewHeight, origHeight
* saveScale);
if (fixTransX != 0 || fixTransY != 0)
matrix.postTranslate(fixTransX, fixTransY);
}
float getFixTrans(float trans, float viewSize, float contentSize) {
float minTrans, maxTrans;
if (contentSize <= viewSize) {
minTrans = 0;
maxTrans = viewSize - contentSize;
} else {
minTrans = viewSize - contentSize;
maxTrans = 0;
}
if (trans < minTrans)
return -trans + minTrans;
if (trans > maxTrans)
return -trans + maxTrans;
return 0;
}
float getFixDragTrans(float delta, float viewSize, float contentSize) {
if (contentSize <= viewSize) {
return 0;
}
return delta;
}
public void onClickUndo() {
if (paths.size() > 0) {
undonePaths.add(paths.remove(paths.size() - 1));
invalidate();
} else {
}
// toast the user
}
public void onClickRedo() {
if (undonePaths.size() > 0) {
paths.add(undonePaths.remove(undonePaths.size() - 1));
invalidate();
} else {
}
// toast the user
}
class PathPoints {
private Path path;
// private Paint eraserPaint;
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;
}
}
}
This code is working in my live project thanks.
What i have: Using the below code i am able to draw a pattern(Ex: Line) in the canvas.
What i am planning to do Or How to do this: I am trying to plot dots on that pattern in a uniform distance. (Hope i am clear)
ActDrawPaintImage.java
public class ActDrawPaintImage extends AppCompatActivity implements ColorPickerDialog.OnColorChangedListener {
MyView mv;
AlertDialog dialog;
#Bind(R.id.toolbar)
Toolbar mToolbar;
#Bind(R.id.btnNxtId)
Button btnNxtId;
private Paint mPaint;
private MaskFilter mEmboss;
private MaskFilter mBlur;
LinearLayout canvasLayoutId;
boolean mDotToDraw=false;
private int BRUSHSIZE=20;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act_draw_paint_image);
//Bind the views
ButterKnife.bind(this);
initToolbar();
onClickSet();
//ADD THE VIEW WHERE THE IMAGE IS DRAWN
setTheCanvasView();
//SET BRUSH PROPERTIES
setUpBrushProperties();
mEmboss = new EmbossMaskFilter(new float[] { 1, 1, 1 },0.4f, 6, 3.5f);
mBlur = new BlurMaskFilter(8, BlurMaskFilter.Blur.NORMAL);
}
private void onClickSet() {
btnNxtId.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(mDotToDraw==false){
mDotToDraw=true;
}else{
mDotToDraw=false;
}
}
});
}
private void setTheCanvasView() {
mv= new MyView(this);
mv.setDrawingCacheEnabled(true);
canvasLayoutId=(LinearLayout) findViewById(R.id.canvasLayoutId);
canvasLayoutId.addView(mv);
}
private void setUpBrushProperties() {
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(ContextCompat.getColor(ActDrawPaintImage.this, R.color.pattern_color));
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(BRUSHSIZE);
}
private void initToolbar() {
setSupportActionBar(mToolbar);
setTitle(getString(R.string.app_name));
mToolbar.setTitleTextColor(ContextCompat.getColor(ActDrawPaintImage.this, R.color.white));
}
public void colorChanged(int color) {
mPaint.setColor(color);
}
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;
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;
Context context;
private int width;
private int height;
public MyView(Context c) {
super(c);
context=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);
width=w;
height=h;
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);
}
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.reset();
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SCREEN));
//mPaint.setMaskFilter(null);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
//Create a pointer and log the output
Log.d("POINTS", x + "," + y);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if(mDotToDraw==false){
touch_start(x, y);
}else{
touch_draw_circle(x, y);
}
invalidate();
break;
case MotionEvent.ACTION_MOVE:
if(mDotToDraw==false){
touch_move(x, y);
}else{
}
invalidate();
break;
case MotionEvent.ACTION_UP:
if(mDotToDraw==false){
touch_up();
}else{
}
invalidate();
break;
}
return true;
}
private void touch_draw_circle(float x, float y) {
/*int radius;
radius = 30;
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.WHITE);
mCanvas.drawPaint(paint);
// Use Color.parseColor to define HTML colors
paint.setColor(Color.parseColor("#FF0000"));
mCanvas.drawCircle(x / 2, y / 2, radius, paint);*/
// mPath.quadTo(x, y, x + 0.1f, y);
/*Paint mPaint = new Paint();*/
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(ContextCompat.getColor(ActDrawPaintImage.this, R.color.white));
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(BRUSHSIZE);
mPath.addCircle(x, y, mPaint.getStrokeWidth()/4f, Path.Direction.CW);
}
public void clear()
{
mBitmap = Bitmap.createBitmap(width,height , Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
invalidate();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
new MenuInflater(this).inflate(R.menu.draw_paint_image, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
mPaint.setXfermode(null);
mPaint.setAlpha(0xFF);
switch (item.getItemId()) {
case R.id.COLOR_MENU_ID:
new ColorPickerDialog(this, this, mPaint.getColor()).show();
return true;
case R.id.EMBOSS_MENU_ID:
if (mPaint.getMaskFilter() != mEmboss) {
mPaint.setMaskFilter(mEmboss);
} else {
mPaint.setMaskFilter(null);
}
return true;
case R.id.BLUR_MENU_ID:
if (mPaint.getMaskFilter() != mBlur) {
mPaint.setMaskFilter(mBlur);
} else {
mPaint.setMaskFilter(null);
}
return true;
case R.id.ERASE_MENU_ID:
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
mPaint.setAlpha(0x80);
return true;
case R.id.Clear:
mv.clear();
return true;
case R.id.Save:
AlertDialog.Builder editalert = new AlertDialog.Builder(ActDrawPaintImage.this);
editalert.setTitle("Please Enter the name with which you want to Save");
final EditText input = new EditText(ActDrawPaintImage.this);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT,
LinearLayout.LayoutParams.FILL_PARENT);
input.setLayoutParams(lp);
editalert.setView(input);
editalert.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
String name= input.getText().toString();
Bitmap bitmap = mv.getDrawingCache();
String path = Environment.getExternalStorageDirectory().getAbsolutePath();
File file = new File("/sdcard/"+name+".png");
try
{
if(!file.exists())
{
file.createNewFile();
}
FileOutputStream ostream = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 10, ostream);
ostream.close();
mv.invalidate();
}
catch (Exception e)
{
e.printStackTrace();
}finally
{
mv.setDrawingCacheEnabled(false);
}
}
});
editalert.show();
return true;
}
return super.onOptionsItemSelected(item);
}
}
EDIT
public class ActDrawPaintImage extends AppCompatActivity implements ColorPickerDialog.OnColorChangedListener {
MyView mv;
AlertDialog dialog;
#Bind(R.id.toolbar)
Toolbar mToolbar;
#Bind(R.id.btnNxtId)
Button btnNxtId;
private Paint mPaint;
private MaskFilter mEmboss;
private MaskFilter mBlur;
LinearLayout canvasLayoutId;
boolean mDotToDraw=false;
private int BRUSHSIZE=20;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act_draw_paint_image);
//Bind the views
ButterKnife.bind(this);
initToolbar();
onClickSet();
//ADD THE VIEW WHERE THE IMAGE IS DRAWN
setTheCanvasView();
//SET BRUSH PROPERTIES
setUpBrushProperties();
mEmboss = new EmbossMaskFilter(new float[] { 1, 1, 1 },0.4f, 6, 3.5f);
mBlur = new BlurMaskFilter(8, BlurMaskFilter.Blur.NORMAL);
}
private void onClickSet() {
btnNxtId.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(mDotToDraw==false){
mDotToDraw=true;
}else{
mDotToDraw=false;
}
}
});
}
private void setTheCanvasView() {
mv= new MyView(this);
mv.setDrawingCacheEnabled(true);
canvasLayoutId=(LinearLayout) findViewById(R.id.canvasLayoutId);
canvasLayoutId.addView(mv);
}
private void setUpBrushProperties() {
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(ContextCompat.getColor(ActDrawPaintImage.this, R.color.pattern_color));
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(BRUSHSIZE);
}
private void initToolbar() {
setSupportActionBar(mToolbar);
setTitle(getString(R.string.app_name));
mToolbar.setTitleTextColor(ContextCompat.getColor(ActDrawPaintImage.this, R.color.white));
}
public void colorChanged(int color) {
mPaint.setColor(color);
}
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;
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;
Context context;
private int width;
private int height;
PathMeasure pathMeasure;
float[] position = new float[2];
float[] slope = new float[2]; // slope will give you the tangent of the position on the path. Not sure if you need this.
public MyView(Context c) {
super(c);
context=c;
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
pathMeasure = new PathMeasure(mPath, false);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
width=w;
height=h;
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);
drawPlotPoints(canvas); // you should be able to implement this alone. It should draw a dot at a given x/y.
canvas.drawPath(mPath, mPaint);
}
private void drawPlotPoints(Canvas canvas) {
int amountOfPoints = (int)(pathMeasure.getLength() / 120f);
for (float distance = 0; distance <= 1; distance += 1f / amountOfPoints) {
pathMeasure.getPosTan(distance, position, slope);
touch_draw_circle(position[0], position[1]);
}
}
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;
}
//drawPlotPoints(x,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.reset();
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SCREEN));
//mPaint.setMaskFilter(null);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
//Create a pointer and log the output
//Log.d("POINTS", x + "," + y);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if(mDotToDraw==false){
touch_start(x, y);
}else{
touch_draw_circle(x, y);
}
invalidate();
break;
case MotionEvent.ACTION_MOVE:
if(mDotToDraw==false){
touch_move(x, y);
}else{
}
invalidate();
break;
case MotionEvent.ACTION_UP:
if(mDotToDraw==false){
touch_up();
}else{
}
invalidate();
break;
}
return true;
}
private void touch_draw_circle(float x, float y) {
/*int radius;
radius = 30;
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.WHITE);
mCanvas.drawPaint(paint);
// Use Color.parseColor to define HTML colors
paint.setColor(Color.parseColor("#FF0000"));
mCanvas.drawCircle(x / 2, y / 2, radius, paint);*/
// mPath.quadTo(x, y, x + 0.1f, y);
/*Paint mPaint = new Paint();*/
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(ContextCompat.getColor(ActDrawPaintImage.this, R.color.white));
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(BRUSHSIZE);
mPath.addCircle(x, y, mPaint.getStrokeWidth()/4f, Path.Direction.CW);
}
public void clear()
{
mBitmap = Bitmap.createBitmap(width,height , Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
invalidate();
}
}
}
I am getting output as below:
I am trying to get output as like this:
If I understood you correctly, you're trying to discover certain positions on a given path, then draw dots on them where the distance between each dot should be the same.
You can achieve this using a PathMeasure object. Example:
boolean forceClose = false; //(set to true if you want to close the path or leave it open).
PathMeasure pathMeasure = new PathMeasure(path, forceClose);
float[] position = new float[2];
float[] slope = new float[2]; // slope will give you the tangent of the position on the path. Not sure if you need this.
for (float distance = 0; distance <= 1; distance += 1f / AMOUNT_OF_POINTS) {
pathMeasure.getPosTan(distance, position, slope);
drawDotAtPosition(position[0], position[1]); // you should be able to implement this alone. It should draw a dot at a given x/y.
}
The getPosTan method will give you the position on a given path after a certain ratio of the length has passed. This ratio is defined by AMOUNT_OF_POINTS which you can set to anything for a constant amount of points no matter what the length of the path is, or you could calculate it according to the length of the path:
// this will produce an amount of points equal to 1 point per 10 pixels along the whole path
int amountOfPoints = (int)(pathMeasure.getLength() / 10f);
Hope this helps.
I made this a while back, its not exactly my best work but it worked at the time. Maybe you can use it as a reference.
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
public class line_graph extends View
{
private int padding = 0;
private int width = 0;//this is automatically
private int height = 0;
private Paint paint = new Paint();
private String[] labels;// labels for each column
private int[][] values;// values for each column
private String[] labelsHeadings;// headings for each segment of data
private float xInterval = 0;//space between x grid lines
private float yInterval = 0;//space between y grid lines
private int RowLineCount = 0; // amount of y grid lines
private float scale = 1; // this is automatically set according to the screen density
private int labelSpaceLeft = 0;// space on the left for labels
private int labelSpaceBottom = 0;// space on the bottom for labels
private int keySpace = 0;// space on the bottom for the key
private Path path = new Path();// bothe these paths are used for the shaded effect on the line graph
private Path path2 = new Path();
public line_graph(Context context)
{
this(context, null, 0);
}
public line_graph(Context context, AttributeSet attrs)
{
this(context, attrs, 0);
}
public line_graph(Context context, AttributeSet attrs, int defStyleAttr)
{
super(context, attrs, defStyleAttr);
if(isInEditMode())
return;
scale = context.getResources().getDisplayMetrics().density;
labelSpaceLeft = (int)(40 * scale);
labelSpaceBottom = (int)(85 * scale);
keySpace = (int)(40 * scale);
}
public void setup(String[] labels, int[][] values, String[] labelsHeadings, int padding)
{
this.labels = labels;
this.values = values;
this.padding = padding;
this.labelsHeadings = labelsHeadings;
invalidate();
}
#Override
protected void onSizeChanged(int xNew, int yNew, int xOld, int yOld){
super.onSizeChanged(xNew, yNew, xOld, yOld);
width = xNew;
height = yNew;
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (isInEditMode())
return;
try {
paint.reset();
paint.setAntiAlias(true);
paint.setTextSize(16);
paint.setTextAlign(Paint.Align.RIGHT);
int maxValue = 0;
for (int i = 0; i < values.length; i++) {
for (int j = 0; j < values[i].length; j++) {
maxValue = Math.max(maxValue, values[i][j]);
}
}
float innerWidth = width - padding * 2 - labelSpaceLeft;
float innerHeight = height - padding * 2 - labelSpaceBottom - keySpace;
float lx = padding;
paint.setTextAlign(Paint.Align.LEFT);
for (int i = 0; i < values.length; i++) {
paint.setColor(getNextColour(i));
//calculate space for circles
lx += 15 * scale;
//calculate space key label
if (labelsHeadings.length > i) {
lx += padding + paint.measureText(labelsHeadings[i]);
if (i < values.length - 1 && lx + paint.measureText(labelsHeadings[i + 1]) > width) {
lx = padding + labelSpaceLeft;
innerHeight += paint.ascent();
}
}
}
lx = padding + labelSpaceLeft;
float ly = innerHeight + padding*2 + labelSpaceBottom;
paint.setTextAlign(Paint.Align.LEFT);
for (int i = 0; i < values.length; i++) {
paint.setColor(getNextColour(i));
//draw circles
canvas.drawOval(new RectF(lx - 5 * scale, ly - 5 * scale, lx + 5 * scale, ly + 5 * scale), paint);
lx += 15 * scale;
//draw key label
canvas.drawText(labelsHeadings[i], lx, ly - paint.ascent() / 2, paint);
if (labelsHeadings.length > i) {
lx += padding + paint.measureText(labelsHeadings[i]);
if (i < values.length - 1 && lx + paint.measureText(labelsHeadings[i + 1]) > width) {
lx = padding + labelSpaceLeft;
ly -= paint.ascent();
innerHeight += paint.ascent();
}
}
}
xInterval = innerWidth / (labels.length-1);
RowLineCount = (int) Math.min(Math.max(innerHeight / Math.ceil(40 * scale), 2), maxValue/2);
yInterval = innerHeight / RowLineCount;
int currentValue = maxValue;
float y;
paint.setTextAlign(Paint.Align.RIGHT);
for (int i = 0; i < RowLineCount+1; i++) {
//draw left label
y = yInterval * i + padding;
paint.setColor(0xffaaaaaa);
canvas.drawText(String.valueOf(currentValue), labelSpaceLeft, y - paint.ascent()/2, paint);
currentValue = Math.max(currentValue - maxValue/RowLineCount,0);
//draw x grid line
paint.setColor(0xffeeeeee);
canvas.drawLine(padding + labelSpaceLeft, y, innerWidth + padding + labelSpaceLeft, y, paint);
}
float x;
for (int i = 0; i < labels.length; i++) {
//draw bottom label rotated
x = xInterval * i + padding + labelSpaceLeft;
if(i != labels.length) {
canvas.save();
canvas.rotate(300, x, innerHeight + padding*2 - paint.ascent()/2);
paint.setColor(0xffaaaaaa);
canvas.drawText(labels[i], x, innerHeight + padding*2 - paint.ascent()/2, paint);
canvas.restore();
}
//draw y grid line
paint.setColor(0xffeeeeee);
canvas.drawLine(x, padding, x, innerHeight + padding, paint);
}
paint.setStyle(Paint.Style.FILL);
for (int i = 0; i < values.length; i++) {
paint.setColor(getNextColour(i));
path.rewind();
path2.rewind();
for (int j = 0; j < values[i].length; j++)
{
x = xInterval * j + padding + labelSpaceLeft;
y = innerHeight + padding - (innerHeight * values[i][j] / maxValue);
//draw lines
if(j == 0) {
path2.moveTo(padding + labelSpaceLeft, innerHeight + padding);
path.moveTo(x, y);
}
else
path.lineTo(x,y);
path2.lineTo(x, y);
//canvas.drawLine(xOld,yOld,x,y,paint);
//draw circles
canvas.drawOval(new RectF(x - 5 * scale, y - 5 * scale, x + 5 * scale, y + 5 * scale), paint);
}
//draw line
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(2);
canvas.drawPath(path, paint);
//draw shaded area
path2.lineTo(innerWidth + padding + labelSpaceLeft, innerHeight + padding);
paint.setARGB(20, Color.red(paint.getColor()), Color.green(paint.getColor()), Color.blue(paint.getColor()));
paint.setStyle(Paint.Style.FILL);
canvas.drawPath(path2, paint);
}
}
catch (Exception ignored){}
}
//used to get the next color in the series
public static int getNextColour(int index)
{
int[] colours = new int[]{0xFF4CAF50,
0xFF9C27B0,
0xFFF44336,
0xFF00BCD4,
0xFFE91E63,
0xFF03A9F4,
0xFFFF9800,
//0xFFFFEB3B,//removed bright yellow
0xFF9E9E9E,
0xFF795548,
0xFF8BC34A,
0xFF607D8B,
0xFF009688,
0xFFFFC107,
0xFF673AB7,
0xFF2196F3,
0xFFCDDC39,
0xFF3F51B5,
0xFFFF5722};
return colours[index % colours.length];
}
}
its used like this:
line_graph graph = (line_graph)findViewById(R.id.lineGraph);
graph.setup(
//labels
new String[]{"heading1","heading2","heading3","heading4","heading5","heading6","heading7"},
//Values
new int[][]{new int[]{1,4,8,2,5,9,12},new int[]{2,5,2,8,5,2,6},new int[]{8,2,9,23,7,1,11}},
//Series Headings
new String[]{"Series 1", "Series 2", "Series 3"},
//Padding
20);
xml:
<line_graph
android:id="#+id/lineGraph"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
it looks like this:
And yes i do realize this could be made better and that it had poor exception handling. But its just an example.
I am using the following code to draw a path based on variable width changes on a Canvas, So far everything works fine and i can easily draw path using this code.
But the path drawn is not smooth, Especially when i draw a curved path all the lines look broken, Why does this happen? Is anything wrong in my code?
public class FingerPaint extends GraphicsActivity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(new MyView(this));
}
public void colorChanged(int color)
{
}
public class MyView extends View implements OnTouchListener
{
private static final float STROKE_WIDTH = 3f;
private Paint paint = new Paint();
private Path mPath = new Path();
ArrayList<Path> mPaths = new ArrayList<Path>();
private Canvas m_CanvasView;
private Bitmap m_CanvasBitmap;
int variableWidthDelta = 1;
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;
ArrayList<Point> points = new ArrayList<Point>(64);
public MyView(Context context)
{
super(context);
setFocusable(true);
setFocusableInTouchMode(true);
this.setOnTouchListener(this);
paint.setAntiAlias(true);
paint.setDither(true);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStrokeWidth(STROKE_WIDTH);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh)
{
super.onSizeChanged(w, h, oldw, oldh);
m_CanvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
m_CanvasView = new Canvas(m_CanvasBitmap);
}
#Override
protected void onDraw(Canvas canvas)
{
canvas.drawBitmap(m_CanvasBitmap, 0f, 0f, null);
m_CanvasView.drawPath(mPath, paint);
}
public boolean onTouch(View arg0, MotionEvent event)
{
float x = event.getX();
float y = event.getY();
switch (event.getAction())
{
case MotionEvent.ACTION_DOWN:
{
mPath.reset();
mPath.moveTo(x, y);
mX = x;
mY = y;
break;
}
case MotionEvent.ACTION_MOVE:
{
if (event.getPressure()>=0.00 && event.getPressure()<0.05)
{
variableWidthDelta = 1;
}
else if (event.getPressure()>=0.05 && event.getPressure()<0.10)
{
variableWidthDelta = 1;
}
else if (event.getPressure()>=0.10 && event.getPressure()<0.15)
{
variableWidthDelta = 2;
}
else if (event.getPressure()>=0.15 && event.getPressure()<0.20)
{
variableWidthDelta = 2;
}
else if (event.getPressure()>=0.20 && event.getPressure()<0.25)
{
variableWidthDelta = 1;
}
else if (event.getPressure() >= 0.25 && event.getPressure()<0.30)
{
variableWidthDelta = 1;
}
else if (event.getPressure() >= 0.30 && event.getPressure()<0.35)
{
variableWidthDelta = 2;
}
else if (event.getPressure() >= 0.35 && event.getPressure()<0.40)
{
variableWidthDelta = 2;
}
else if (event.getPressure() >= 0.40 && event.getPressure()<0.45)
{
variableWidthDelta = 3;
}
else if (event.getPressure() >= 0.45 && event.getPressure()<0.50)
{
variableWidthDelta = 4;
}
paint.setStrokeWidth(STROKE_WIDTH + variableWidthDelta);
float dx = Math.abs(x - mX);
float dy = Math.abs(y - mY);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE)
{
points.add(new Point(event.getX(), event.getY()));
mPath = new Path();
mPath = generatePath();
}
break;
}
case MotionEvent.ACTION_UP:
{
break;
}
}
invalidate();
return true;
}
class Point
{
public final float x;
public final float y;
public Point(float x, float y)
{
this.x = x;
this.y = y;
}
}
public Path generatePath()
{
final float tangentScale = 0.3F;
int pointcount = points.size();
mPath.moveTo(points.get(0).x, points.get(0).y);
mPath.cubicTo(
points.get(0).x + (points.get(1).x - points.get(0).x)*tangentScale,
points.get(0).y + (points.get(1).y - points.get(0).y)*tangentScale,
points.get(1).x - (points.get(2).x - points.get(0).x)*tangentScale,
points.get(1).y - (points.get(2).y - points.get(0).y)*tangentScale,
points.get(1).x, points.get(1).y
);
for(int p=2; p<pointcount-1; p++)
{
mPath.cubicTo(
points.get(p-1).x + (points.get(p).x - points.get(p-2).x)*tangentScale,
points.get(p-1).y + (points.get(p).y - points.get(p-2).y)*tangentScale,
points.get(p).x - (points.get(p+1).x - points.get(p-1).x)*tangentScale,
points.get(p ).y - (points.get(p+1).y - points.get(p-1).y)*tangentScale,
points.get(p).x, points.get(p).y
);
}
mPath.cubicTo(
points.get(pointcount-2).x + (points.get(pointcount-1).x - points.get(pointcount-3).x)*tangentScale,
points.get(pointcount-2).y + (points.get(pointcount-1).y - points.get(pointcount-3).y)*tangentScale,
points.get(pointcount-1).x - (points.get(pointcount-1).x - points.get(pointcount-2).x)*tangentScale,
points.get(pointcount-1).y - (points.get(pointcount-1).y - points.get(pointcount-2).y)*tangentScale,
points.get(pointcount-1).x, points.get(pointcount-1).y
);
return mPath;
}
}
}
The onTouch event is not fired fast enough, so if you draw curves fast enough you will see this happening.
You can improve the point resolution by getting all recorded points between this onTouch event and the last one. Use event.getHistorySize() to get the amount of available points, and get their positions with event.getHistoricalX(int) and event.getHistoricalY(int).
If you still have problems, you would probably have to implement some sort of interpolation of the points.
Here is a simple example using cubicTo() to get a smooth path:
points is an array of all points that are to be drawn.
pointcount is the amount of points
//This code is untested
public Path generatePath(){
Path path = new Path();
if( points.size() < 3 ) return path;
final float tangentScale = 0.3;
path.moveTo(points[0].x, points[0].y);
path.cubicTo(
points[0].x + (points[1].x - points[0].x)*tangentScale,
points[0].y + (points[1].y - points[0].y)*tangentScale,
points[1].x - (points[2].x - points[0].x)*tangentScale,
points[1].y - (points[2].y - points[0].y)*tangentScale,
points[1].x, points[1].y
);
for(int p=2; p<pointcount-1; p++){
path.cubicTo(
points[p-1].x + (points[p].x - points[p-2].x)*tangentScale,
points[p-1].y + (points[p].y - points[p-2].y)*tangentScale,
points[p ].x - (points[p+1].x - points[p-1].x)*tangentScale,
points[p ].y - (points[p+1].y - points[p-1].y)*tangentScale,
points[p].x, points[p].y
);
}
path.cubicTo(
points[pointcount-2].x + (points[pointcount-1].x - points[pointcount-3].x)*tangentScale,
points[pointcount-2].y + (points[pointcount-1].y - points[pointcount-3].y)*tangentScale,
points[pointcount-1].x - (points[pointcount-1].x - points[pointcount-2].x)*tangentScale,
points[pointcount-1].y - (points[pointcount-1].y - points[pointcount-2].y)*tangentScale,
points[pointcount-1].x, points[pointcount-1].y
);
return path;
}
Adapting this for your specific case:
(You will have to modify the above method to use .get() instead of array accessors, since I am using a list here)
//A class for holding x and y values:
class Point{
public final float x;
public final float y;
public Point(float x, float y){
this.x = x;
this.y = y;
}
}
//In your View:
ArrayList<Point> points = new ArrayList<Points>(64);
//In the onTouch-method if the tolerance is ok:
points.add(new Point(event.getX(), event.GetY());
mPath = generatePath();
The above will generate a rounded path that you can draw. Note that it uses all points, so they will all be redrawn every time (you might have to clear the canvas to avoid some artiefacts). You might want to move the generatePath-call to when you lift the finger, so you get a faster, but jagged preview path while drawing.
this has been driving me a little crazy today. I've implimented this class which enables me to draw lines over an image file. however I want to be able to to add a template mask at creation time. Whatever I try i.e. within the class or from the calling class it causes a Null pointer exception, if however I put the call into a button in the calling class then I can get it to work?
here is the class I'm using. You can see the commented out section, if I call "coverScreen()" from here it causes the NPE. Also from the main Activity where I create the maskBoard if I call "coverScreen()" it causes NPE. But as mentioned if I add a button, and put the "coverScreen()" into this button onclick then it works?
public class MaskBoard extends View {
private String TAG = "Test APP - maskboard";
private int mx = -1;
private int my = -1;
private Bitmap mainImage = null;
private Bitmap bm = null;
private Paint mPaint = null;
public final int CLOSER = 50;
public final int CLOSE = 100;
private Bitmap mBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint mBitmapPaint;
public MaskBoard(Context c, AttributeSet s) {
super(c, s);
String fileToMask = "/__temppic.png";
File imagePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES + "/temp/");
File imgFile = new File(imagePath+fileToMask);
if (imgFile.exists()) {
bm = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
Log.i(TAG, "found image");
}
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
mPaint = new Paint();
mPaint.setAntiAlias(false);
mPaint.setDither(true);
mPaint.setColor(0xFFFE0000); // FFFF0000
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(50);
/* coverScreen() */
setEraser();
}
public void coverScreen() {
Bitmap maskImage = BitmapFactory.decodeResource(getResources(), R.drawable.mask); //get mask image
maskImage = Bitmap.createScaledBitmap(maskImage, bm.getWidth(), bm.getHeight(), true);
mPaint.setXfermode(null);
mCanvas.drawBitmap(maskImage,0,0,mPaint);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
}
public void setEraser() {
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
}
public void setPaint() {
mPaint.setXfermode(null);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
Log.i(TAG, "onsizechanged");
mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
}
#Override
protected void onDraw(Canvas canvas) {
Log.i(TAG, "onDraw");
canvas.drawRect(0,0, getWidth(), getHeight(), mPaint);
canvas.drawColor(0xFFAAAAAA);
canvas.drawBitmap(bm, mx, my, null);
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
canvas.drawPath(mPath, mPaint);
}
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;
Log.i(TAG, " touchdown: X(" + x + "), Y(" + 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;
Log.i(TAG, " touchmove: X(" + x + "), Y(" + 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.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);
// coverScreen() ;
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touch_move(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touch_up();
invalidate();
break;
}
return true;
}
}
I want to do a game, a scratch game (mPaint1.setXfermode(new PorterDuffXfermode(Mode.CLEAR)); ) with 3 independants cases center on the screen. How to do that?
http://img822.imageshack.us/img822/868/35861879.png
Only one case on the screen display. When theses 3 cases are cleared then the score display in function of displayed images. Thank you.
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImageView image = new ImageView(this);
image.setImageResource(R.drawable.ic_launcher);
CaseView caseOne=new CaseView(this, R.drawable.ic_launcher, 0);
//TableLayout table = (TableLayout)findViewById(R.id.matable);
TableRow tablerow = (TableRow)findViewById(R.id.marow);
//table.setLayoutParams(tableParams);
tablerow.addView(caseOne);
}
public class CaseView extends View {
private static final float MINP = 1f;
private static final float MAXP = 1f;
private Bitmap mBitmap1, _scratch = null;
private Canvas mCanvas1;
private Canvas mCanvas2, mCanvas3;
private Path mPath1;
private Paint mBitmapPaint1;
private Paint mPaint1;
private int IdImage;
private int positionTop = 0;
private String colorGold = "#E29F2B";
private boolean firstTime = false;
// private Bitmap image;
// private Paint paint;
boolean isErase;
public CaseView(Context ctx, AttributeSet attrs) {
super(ctx, attrs);
}
public CaseView(Context c, int resId, int positionTop) {
super(c);
this.positionTop = positionTop;
firstTime = true;
mPaint1 = new Paint();
mPaint1.setAntiAlias(true);
mPaint1.setDither(true);
mPaint1.setColor(Color.TRANSPARENT);
mPaint1.setStyle(Paint.Style.STROKE);
mPaint1.setStrokeWidth(60);
// create a square
mBitmap1 = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
for (int i = 0; i < 100; i++) {
for (int j = 0; j < 100; j++) {
mBitmap1.setPixel(i, j, Color.parseColor(colorGold));
}
}
mCanvas1 = new Canvas(mBitmap1);
mPath1 = new Path();
mBitmapPaint1 = new Paint(Paint.DITHER_FLAG);
// mBitmapPaint3 = new Paint(Paint.DITHER_FLAG);
IdImage = resId;
if (_scratch == null) {
_scratch = BitmapFactory.decodeResource(getResources(), IdImage);
}
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
}
#Override
protected void onDraw(Canvas canvas) {
// Log.v("", "onDraw");
canvas.drawColor(Color.WHITE);
// logo
canvas.drawBitmap(_scratch, 0, positionTop, null);
// canvas.drawBitmap(mBitmap1, null, new Rect(0,0,100,100),
// mBitmapPaint1);
canvas.drawBitmap(mBitmap1, 0, positionTop, mBitmapPaint1);
canvas.drawBitmap(_scratch, 0, 400, null);
canvas.drawBitmap(mBitmap2, 0, 400, mBitmapPaint2);
// mBitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
if ((mX < 100 && mX >= 0)
&& (mY < positionTop + 100 && mY >= positionTop)) {
// Log.v("onDraw", "x:" + mX + "/y:" + mY);
mPaint1.setMaskFilter(null);
mPath1.reset();
mPaint1.setXfermode(new PorterDuffXfermode(Mode.CLEAR));
// mBitmap.setPixel((int) mY,(int) mX, Color.TRANSPARENT);
// mBitmap1.eraseColor(Color.TRANSPARENT);
mCanvas1.setBitmap(mBitmap1);
canvas.drawBitmap(mBitmap1, 0, positionTop, mBitmapPaint1);
invalidate();
} else {
mPaint1.setXfermode(null);
}
super.onDraw(canvas);
int pixelColor = mBitmap1.getPixel(50, 50);
int red = Color.red(pixelColor);
int green = Color.green(pixelColor);
Log.v("red", "red:" + red + " /green:" + green);
// invalidate();
}
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;
private void touch_start(float x, float y) {
mPath1.reset();
mPath1.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) {
mPath1.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
mPath2.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
mX = x;
mY = y;
}
}
private void touch_up() {
mPath1.lineTo(mX, mY);
mPath2.lineTo(mX, mY);
// commit the path to our offscreen
mCanvas1.drawPath(mPath1, mPaint1);
// kill this so we don't double draw
mPath1.reset();
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
Log.v("onTouchEvent", "x:" + x + "/y:" + y);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if ((mX < 100 && mX >= 0)
&& (mY < positionTop + 100 && mY >= positionTop)) {
mPath1.reset();
mPaint1.setMaskFilter(null);
mPaint1.setStrokeWidth(90);
mPaint1.setXfermode(new PorterDuffXfermode(Mode.CLEAR));
// mCanvas1.draw(x, y, 10, mPaint1);
isErase = true;
} else {
mPaint1.setXfermode(null);
isErase = false;
}
touch_start(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
if (isErase) {
mCanvas1.drawCircle(x, y, 20, mPaint1);
}
touch_move(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
if (isErase) {
mCanvas1.drawCircle(x, y, 20, mPaint1);
}
touch_up();
invalidate();
break;
}
return true;
}
}