/I got the following code:
public class SketchActivity extends Activity implements OnClickListener, OnSeekBarChangeListener {
private MyView myView;
private Button clearBtn;
private ToggleButton embossBtn, blurBtn, eraseBtn, srcaBtn;
private RelativeLayout layout, layout2;
private TextView penSizeTxt;
SharedPreferences pref;
private Preview preview;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_main);
init();
preview = new Preview(this);
layout2 = (RelativeLayout) findViewById(R.id.paint_layout2);
layout = (RelativeLayout) findViewById(R.id.paint_layout);
layout.addView(preview);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
myView = new MyView(SketchActivity.this, layout.getWidth(), layout.getHeight());
layout2.addView(myView);
layout2.bringToFront();
}
}, 50);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(0xFF000000);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(5);
mEmboss = new EmbossMaskFilter(new float[] { 1, 1, 1 }, 0.4f, 6, 3.5f);
mBlur = new BlurMaskFilter(8, BlurMaskFilter.Blur.NORMAL);
}
private void init() {
clearBtn = (Button) findViewById(R.id.clearBtn);
embossBtn = (ToggleButton) findViewById(R.id.embossBtn);
blurBtn = (ToggleButton) findViewById(R.id.blurBtn);
eraseBtn = (ToggleButton) findViewById(R.id.eraseBtn);
srcaBtn = (ToggleButton) findViewById(R.id.srcatopBtn);
clearBtn.setOnClickListener(this);
embossBtn.setOnClickListener(this);
blurBtn.setOnClickListener(this);
eraseBtn.setOnClickListener(this);
srcaBtn.setOnClickListener(this);
}
private static Paint mPaint;
private MaskFilter mEmboss;
private MaskFilter mBlur;
public void colorChanged(int color) {
mPaint.setColor(color);
}
private void setToggleOf() {
embossBtn.setChecked(false);
eraseBtn.setChecked(false);
blurBtn.setChecked(false);
srcaBtn.setChecked(false);
}
#Override
public void onClick(View v) {
if (v.getId() == embossBtn.getId()) {
if (mPaint.getMaskFilter() != mEmboss) {
setToggleOf();
mPaint.setXfermode(null);
mPaint.setAlpha(0xFF);
mPaint.setMaskFilter(mEmboss);
embossBtn.setChecked(true);
} else {
mPaint.setMaskFilter(null);
embossBtn.setChecked(false);
}
} else if (v.getId() == blurBtn.getId()) {
if (mPaint.getMaskFilter() != mBlur) {
setToggleOf();
mPaint.setXfermode(null);
mPaint.setAlpha(0xFF);
mPaint.setMaskFilter(mBlur);
blurBtn.setChecked(true);
} else {
mPaint.setMaskFilter(null);
blurBtn.setChecked(false);
}
} else if (v.getId() == eraseBtn.getId()) {
if (eraseBtn.isChecked()) {
setToggleOf();
eraseBtn.setChecked(true);
mPaint.setMaskFilter(null);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
} else {
mPaint.setMaskFilter(null);
mPaint.setXfermode(null);
mPaint.setAlpha(0xFF);
}
} else if (v.getId() == srcaBtn.getId()) {
if (srcaBtn.isChecked()) {
setToggleOf();
mPaint.setMaskFilter(null);
srcaBtn.setChecked(true);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));
mPaint.setAlpha(0x80);
} else {
mPaint.setMaskFilter(null);
mPaint.setXfermode(null);
mPaint.setAlpha(0xFF);
}
}
else if (v.getId() == clearBtn.getId()) {
layout2.removeAllViews();
myView = new MyView(SketchActivity.this, layout.getWidth(), layout.getHeight());
layout2.addView(myView);
}
}
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;
Bitmap bitmap;
int x = 0;
int y = 0;
int r = 0;
public MyView(Context c, int width, int height) {
super(c);
WindowManager wm = (WindowManager) c.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
int w = display.getWidth(); // deprecated
int h = display.getHeight();
// setFocusable(true);
// setBackgroundResource(R.drawable.download);
// setting paint
mPath = new Path();
mPaint = new Paint();
mPaint.setAlpha(0);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
mPaint.setAntiAlias(true);
mPaint.setMaskFilter(new BlurMaskFilter(10, BlurMaskFilter.Blur.NORMAL));
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
this.getContext().getResources();
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.smoke);
Bitmap bm2 = getResizedBitmap(bm, h, w);
// converting image bitmap into mutable bitmap
bitmap = bm2.createBitmap(w, h, Config.ARGB_8888);
mCanvas = new Canvas();
mCanvas.setBitmap(bitmap); // drawXY will result on that Bitmap
mCanvas.drawBitmap(bm2, 0, 0, null);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
}
#Override
protected void onDraw(Canvas canvas) {
//mCanvas.drawCircle(x, y, r, mPaint);
// canvas.drawBitmap(bitmap, 0, 0, null);
canvas.drawBitmap(bitmap, 0, 0, mBitmapPaint);
canvas.drawPath(mPath, mPaint);
super.onDraw(canvas);
}
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);
// mPath.lineTo(x, y);
// mCanvas.drawPoint(x, y, mPaint);
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;
}
// invalidate();
}
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;
}
public Bitmap getImage() {
return mBitmap;
}
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
// TODO Auto-generated method stub
penSizeTxt.setText(String.valueOf(progress + 2));
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
public Bitmap getResizedBitmap(Bitmap bm, int newHeight, int newWidth) {
int width = bm.getWidth();
int height = bm.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// CREATE A MATRIX FOR THE MANIPULATION
Matrix matrix = new Matrix();
// RESIZE THE BIT MAP
matrix.postScale(scaleWidth, scaleHeight);
// RECREATE THE NEW BITMAP
Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);
return resizedBitmap;
}
}
I want it to clear the second layout and show the content of the camera, on touch. So that if i make a curved line with my finger on the screen it would set those pixels to alpha, and see the camera from the back layout. The problem is that if for example, i make a curved line, the app erases the content of that curve too. So that if i would make a circle with my finger it would erase the content of the circle too, not only the margin.
A screenshot with how it looks: http://imgur.com/5gjNB
onCreate i had:
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(0xFF000000);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(5);
And then on my View i had:
mPaint = new Paint();
mPaint.setAlpha(0);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
mPaint.setAntiAlias(true);
mPaint.setMaskFilter(new BlurMaskFilter(10, BlurMaskFilter.Blur.NORMAL));
Overriding the mPaint, and that's what made it not work properly. By deleting the second:
mPaint = new Paint();
I made it work
Related
I am trying to use the method mCanvas.drawBitmap(iconBitmap,x-100,y-100, mBitmapPaint); on my MotionEvent.ACTION_DOWN event in my custom view class. However, the image I want to show does not appear on the canvas at that point. I am trying to make a paint application where users can draw free hand and insert images at the same time to play with them.
This is my custom view class:
package com.example.shazs.autismate;
public class PaintView extends View {
public static int BRUSH_SIZE = 20;
public static final int DEFAULT_COLOR = Color.RED;
public static final int DEFAULT_BG_COLOR = Color.WHITE;
private static final float TOUCH_TOLERANCE = 4;
private float mX, mY;
private Path mPath;
private Paint mPaint;
private ArrayList<FingerPath> paths = new ArrayList<>();
private int currentColor;
private int backgroundColor = DEFAULT_BG_COLOR;
private int strokeWidth;
private boolean emboss;
private boolean blur;
private MaskFilter mEmboss;
private MaskFilter mBlur;
private Bitmap mBitmap;
private Paint mBitmapPaint;
private Canvas mCanvas;
private Bitmap iconBitmap;
private static AtomicBoolean drawIcon = new AtomicBoolean();
public PaintView(Context context) {
this(context, null);
}
public PaintView(Context context, AttributeSet attrs) {
super(context, attrs);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(DEFAULT_COLOR);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setXfermode(null);
mPaint.setAlpha(0xff);
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
mEmboss = new EmbossMaskFilter(new float[] {1, 1, 1}, 0.4f, 6, 3.5f);
mBlur = new BlurMaskFilter(5, BlurMaskFilter.Blur.NORMAL);
}
public void init(DisplayMetrics metrics) {
int height = metrics.heightPixels;
int width = metrics.widthPixels;
mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
currentColor = DEFAULT_COLOR;
strokeWidth = BRUSH_SIZE;
}
public void normal() {
emboss = false;
blur = false;
}
public void emboss() {
emboss = true;
blur = false;
}
public void blur() {
emboss = false;
blur = true;
}
public void setPaintColor(int color){
if (currentColor!=color)
Log.d("xyzn","current color changed");
else
Log.d("xyzn","current color not changed");
currentColor=color;
}
public void drawBitmap(Bitmap bm){
drawIcon.set(true);
iconBitmap = bm;
}
public int getPaintColor(){
return currentColor;
}
public void clear() {
backgroundColor = DEFAULT_BG_COLOR;
paths.clear();
normal();
invalidate();
}
#Override
protected void onDraw(Canvas canvas) {
canvas.save();
mCanvas.drawColor(backgroundColor);
for (FingerPath fp : paths) {
mPaint.setColor(fp.color);
mPaint.setStrokeWidth(fp.strokeWidth);
mPaint.setMaskFilter(null);
if (fp.emboss)
mPaint.setMaskFilter(mEmboss);
else if (fp.blur)
mPaint.setMaskFilter(mBlur);
mCanvas.drawPath(fp.path, mPaint);
}
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
canvas.restore();
}
private void touchStart(float x, float y) {
mPath = new Path();
FingerPath fp = new FingerPath(currentColor, emboss, blur, strokeWidth, mPath);
paths.add(fp);
mPath.reset();
mPath.moveTo(x, y);
mX = x;
mY = y;
}
private void touchMove(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 touchUp() {
mPath.lineTo(mX, mY);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch(event.getAction()) {
case MotionEvent.ACTION_DOWN :
if (drawIcon.get()){
mCanvas.drawBitmap(iconBitmap,x-100,y-100, mBitmapPaint);
mCanvas.save();
break;
}
touchStart(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE :
if (drawIcon.get())
break;
touchMove(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP :
if (drawIcon.get()){
drawIcon.set(false);
break;
}
touchUp();
invalidate();
break;
}
return true;
}
}
Main Activity which uses this custom view class and passes the bitmap of object to draw:
public class drawActivity extends AppCompatActivity implements
ColorPickerDialog.OnColorChangedListener {
private PaintView paintView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.css_layout);
paintView = (PaintView) findViewById(R.id.paintView);
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
paintView.init(metrics);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.main, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case R.id.draw:
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.apple);
paintView.drawBitmap(bm);
break;
I use drawIcon to see if the user needs to insert icon or just draw freehand.
Interestingly, when I go into application view of my phone to view all currently running applications, the icon/image shows on the canvas. However when I return to the application, it dissappears. It only happens once after I insert the icon, not repeatedly.
OK, I had to remove the line
mCanvas.drawColor(backgroundColor);
from my onDraw(Canvas canvas) method and call invalidate()
MainActivity.java
public class MainActivity extends Activity implements OnClickListener {
private DrawingView drawView;
int mColor;
String savedFilePath = "";
public static ArrayList<Path> undonePaths = new ArrayList<Path>();
public static ArrayList<Path> paths = new ArrayList<Path>();
//buttons
Canvas bitmapCanvas;
RelativeLayout mRelativeLayoutScreenShot;
static String mImagePath;
private ImageButton currPaint, drawBtn, eraseBtn, newBtn, saveBtn;
//sizes
private float smallBrush, mediumBrush, largeBrush;
ImageButton mImageViewPicklColor;
private boolean isFileAlreadySaved = false;
ImageButton mImageButtonList;
ImageButton mImageButtonShare;
File file;
Bitmap bitmap;
Button mButtonUNDo;
Dialog mDialogDate;
Button mButtonRedo;
boolean isStartAdl=false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mDialogDate= new Dialog(MainActivity.this, android.R.style.Theme_NoTitleBar| android.R.style.Theme_Translucent|android.R.style.Theme_Holo_Dialog);
mDialogDate.setCancelable(true);
mDialogDate.requestWindowFeature(Window.FEATURE_NO_TITLE);
}
#Override
protected void onResume() {
super.onResume();
savedFilePath="";
mColor = 0xff0000ff;
//get drawing view
mButtonUNDo=(Button)findViewById(R.id.btn_undo);
mButtonRedo=(Button)findViewById(R.id.btn_redo);
drawView = (DrawingView)findViewById(R.id.drawing);
mImageViewPicklColor=(ImageButton)findViewById(R.id.pick_color);
RelativeLayout paintLayout = (RelativeLayout)findViewById(R.id.paint_colors);
mImageButtonShare=(ImageButton)findViewById(R.id.share);
mImageButtonList=(ImageButton)findViewById(R.id.list);
mRelativeLayoutScreenShot=(RelativeLayout)findViewById(R.id.rr_draw);
mImageButtonList.setOnClickListener(this);
//sizes from dimensions
smallBrush = getResources().getInteger(R.integer.small_size);
mediumBrush = getResources().getInteger(R.integer.medium_size);
largeBrush = getResources().getInteger(R.integer.large_size);
//draw button
drawBtn = (ImageButton)findViewById(R.id.draw_btn);
drawBtn.setOnClickListener(this);
File direct = new File(Environment.getExternalStorageDirectory() + "/androidpaint");
if(!direct.exists())
{
if(direct.mkdir());//directory is created;
}
mImagePath = Environment.getExternalStorageDirectory() + "/androidpaint";
//set initial size
drawView.setBrushSize(mediumBrush);
//erase button
eraseBtn = (ImageButton)findViewById(R.id.erase_btn);
eraseBtn.setOnClickListener(this);
//new button
newBtn = (ImageButton)findViewById(R.id.new_btn);
newBtn.setOnClickListener(this);
//save button
saveBtn = (ImageButton)findViewById(R.id.save_btn);
saveBtn.setOnClickListener(this);
mButtonRedo.setOnClickListener(this);
mButtonUNDo.setOnClickListener(this);
mImageViewPicklColor.setOnClickListener(this);
mImageButtonShare.setOnClickListener(this);
drawView.setErase(false);
drawView.setBrushSize(drawView.getLastBrushSize());
drawView.setColor(mColor);
if (isStartAdl==true) {
Intent intent = getIntent();
finish();
startActivity(intent);
}
}
#Override
public void onClick(View view){
if (view.getId()==R.id.btn_undo) {
System.out.println("UNDO "+paths.size());
if (paths.size() > 0) {
undonePaths.add(paths
.remove(paths.size() - 1));
drawView.invalidate();
}
}
else if(view.getId()==R.id.erase_btn)
{
drawView.setErase(true);
}
else if (view.getId()==R.id.btn_redo) {
if (undonePaths.size()>0) {
paths.add(undonePaths.remove(undonePaths.size()-1));
drawView.invalidate();
}
}
});
}
DrawingView.java
public class DrawingView extends View {
private float mX, mY;
private static final float TOUCH_TOLERANCE = 0;
//drawing path
private Path drawPath;
//drawing and canvas paint
private Paint drawPaint, canvasPaint;
//initial color
private int paintColor = 0xFF660000;
//canvas
private Canvas drawCanvas;
//canvas bitmap
private Bitmap canvasBitmap;
//brush sizes
private float brushSize, lastBrushSize;
//erase flag
private boolean erase=false;
public DrawingView(Context context, AttributeSet attrs){
super(context, attrs);
setupDrawing();
}
//setup drawing
private void setupDrawing(){
//prepare for drawing and setup paint stroke properties
brushSize = getResources().getInteger(R.integer.medium_size);
lastBrushSize = brushSize;
drawPath = new Path();
drawPaint = new Paint();
drawPaint.setColor(paintColor);
drawPaint.setAntiAlias(true);
drawPaint.setStrokeWidth(brushSize);
drawPaint.setStyle(Paint.Style.STROKE);
drawPaint.setStrokeJoin(Paint.Join.ROUND);
drawPaint.setStrokeCap(Paint.Cap.ROUND);
canvasPaint = new Paint(Paint.DITHER_FLAG);
System.out.println("cadslfjds");
MainActivity.paths.add(drawPath);
}
//size assigned to view
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
canvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
drawCanvas = new Canvas(canvasBitmap);
}
//draw the view - will be called after touch event
#Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(canvasPaints);
for (Path p : MainActivity.paths) {
if(colorsMap.size()>0)
{
drawPaint.setColor(colorsMap.get(p));
canvas.drawPath(p, drawPaint);
}
}
drawPaint.setColor(paintColor);
canvas.drawPath(drawPath, drawPaint);
private void touch_start(float x, float y) {
drawPath.reset();
drawPath.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) {
drawPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
mX = x;
mY = y;
}
}
private void touch_up() {
drawPath.lineTo(mX, mY);
drawCanvas.drawPath(drawPath, drawPaint);
MainActivity.paths.add(drawPath);
colorsMap.put(drawPath, paintColor);
drawPath = new Path();
drawPath.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;
}
public void setColor(int newColor){
invalidate();
paintColor = newColor;
drawPaint.setColor(paintColor);
}
//set brush size
public void setBrushSize(float newSize){
float pixelAmount = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
newSize, getResources().getDisplayMetrics());
brushSize=pixelAmount;
drawPaint.setStrokeWidth(brushSize);
}
//get and set last brush size
public void setLastBrushSize(float lastSize){
lastBrushSize=lastSize;
}
public float getLastBrushSize(){
return lastBrushSize;
}
//set erase true or false
public void setErase(boolean isErase){
erase=isErase;
if(erase)
drawPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
else
drawPaint.setXfermode(null);
}
//start new drawing
public void startNew(){
drawCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
invalidate();
}
When I paint normal picture, it will come like below
When I click erase Button, it will come like below
When I run above code, the issue is when I click erase button then erase not working properly whole picture convert it into black, so any idea how can I solve it ?
Your code is looking perfect, but problem is you are setting white color as a background on canvas while erasing on canvas then white background also is being erased. So you have to again set white background after erasing some portion on canvas.
#Override
protected void onDraw(Canvas canvas) {
//set background white
canvas.drawColor(Color.WHITE);
super.dispatchDraw(canvas);
}
Check this demo code
All you're doing in setErase is setting a porter duff mode. You aren't actually redrawing anything. At a minimum you need to call invalidate to update the screen.
I am working on canvas application and I have created a canvas with color picker ,Undo,Redo and clear functions and it is also working fine.Now, I want to validate whether the user is currently drawing a line on the background line on the canvas.
For example,
I am having a background image with dotted lines,now I want the user to draw on the dotted lines and I have to validate it whether it is correct or not? Is it possible in canvas and how can I proceed with this?
Could someone give any suggestion about this which will be really help full for me to proceed with next step in my application and my code is here,
public class HomeScreen extends Activity implements ColorPickerDialog.OnColorChangedListener {
public int width;
public int height;
public Arrays paths1;
private Bitmap mBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint mBitmapPaint;
Context context;
private Paint circlePaint;
private Path circlePath;
/* MyView mv; */
DrawingPanel dp;
AlertDialog dialog;
private ArrayList<Path> undonePaths = new ArrayList<Path>();
private ArrayList<Path> paths = new ArrayList<Path>();
FrameLayout frmLayout;
Canvas canvas;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home_screen);
dp = new DrawingPanel(this);
frmLayout = (FrameLayout) findViewById(R.id.frameLayout);
frmLayout.addView(dp);
((Button) findViewById(R.id.Clear)).setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
paths = new ArrayList<Path>();
if (paths != null)
paths.clear();
if (dp != null)
dp.invalidate();
}
});
((Button) findViewById(R.id.Undo)).setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (paths.size() > 0) {
undonePaths.add(paths.remove(paths.size() - 1));
dp.invalidate();
}
}
});
((Button) findViewById(R.id.Redo)).setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (undonePaths.size() > 0) {
paths.add(undonePaths.remove(undonePaths.size() - 1));
dp.invalidate();
}
}
});
((Button) findViewById(R.id.letters)).setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
startActivity(new Intent(HomeScreen.this, Letters.class));
}
});
((Button) findViewById(R.id.color)).setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
mCanvas=new Canvas();
new ColorPickerDialog(HomeScreen.this, HomeScreen.this, mPaint.getColor()).show();
}
});
dp.setDrawingCacheEnabled(true);
Bundle extras = getIntent().getExtras();
Integer userName;
if (extras != null) {
userName = extras.getInt("name");
// and get whatever type user account id is
}
dp.setBackgroundResource(R.drawable.atemplate);// set the back
// ground if you wish
mPaint = new Paint();
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(20);
mEmboss = new EmbossMaskFilter(new float[] { 1, 1, 1 }, 0.4f, 6, 3.5f);
// mBlur = new BlurMaskFilter(8, BlurMaskFilter.Blur.NORMAL);
}
private Paint mPaint;
private MaskFilter mEmboss;
private MaskFilter mBlur;
public void colorChanged(int color) {
mPaint.setColor(color);
}
public class DrawingPanel extends View implements OnTouchListener {
private Canvas mCanvas;
private Path mPath;
private Paint mPaint, circlePaint, outercirclePaint;
// private ArrayList<Path> undonePaths = new ArrayList<Path>();
private float xleft, xright, xtop, xbottom;
public DrawingPanel(Context context) {
super(context);
setFocusable(true);
setFocusableInTouchMode(true);
this.setOnTouchListener(this);
circlePaint = new Paint();
mPaint = new Paint();
outercirclePaint = new Paint();
outercirclePaint.setAntiAlias(false);
circlePaint.setAntiAlias(false);
mPaint.setAntiAlias(false);
mPaint.setColor(0xFF000000);
outercirclePaint.setColor(0x44FFF000);
circlePaint.setColor(0xF57F35);
outercirclePaint.setStyle(Paint.Style.FILL_AND_STROKE);
circlePaint.setStyle(Paint.Style.FILL);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.MITER);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(10);
outercirclePaint.setStrokeWidth(10);
mCanvas = new Canvas();
mPath = new Path();
paths.add(mPath);
}
public void colorChanged(int color) {
mPaint.setColor(color);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
}
#Override
protected void onDraw(Canvas canvas) {
for (Path p : paths) {
canvas.drawPath(p, mPaint);
}
}
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
mCanvas.drawPath(mPath, mPaint);
// kill this so we don't double draw
mPath = new Path();
paths.add(mPath);
}
#Override
public boolean onTouch(View arg0, MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// if (x <= cx+circleRadius+5 && x>= cx-circleRadius-5) {
// if (y<= cy+circleRadius+5 && cy>= cy-circleRadius-5){
// paths.clear();
// return true;
// }
// }
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;
}
}
}
Are you thinking to create a app like pattern locker which are in android devices, try to implement like this way.
#Override
public boolean onTouchEvent(MotionEvent event) {
// MotionEvent object holds X-Y values
if(event.getAction() == MotionEvent.ACTION_DOWN) {
String text = "You click at x = " + event.getX() + " and y = " + event.getY();
Toast.makeText(this, text, Toast.LENGTH_LONG).show();
}
return super.onTouchEvent(event);
}
this link may help
Your programming skills are good. Difficulty here depends on how complicated the lines are. Have you tried saving the position of the dots? and then compare it to getX and getY when the user presses the screen.
I have a Custom View on which I have to draw with my finger(like in the FingerPaint example).
I've tried to add a button below this view programmatically by Making a LinearLayout and adding the required views to it.
However, I cannot see the button itself.
I understand this is a problem due to my implementation of onMeasure, since if I revert to the default, the button is displayed but the view is not.
MainActivity Class
public class FingerPaintActivity extends Activity implements ColorPickerDialog.OnColorChangedListener
{
MyView mv;
AlertDialog dialog;
ArrayList<Integer> colorList;
private LinearLayout.LayoutParams params;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
LinearLayout layout = new LinearLayout(this);
params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
layout.setLayoutParams(params);
Button submitButton = new Button(this);
params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
submitButton.setLayoutParams(params);
submitButton.setGravity(Gravity.CENTER);
submitButton.setText("Done");
mv = new MyView(this);
params = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
mv.setLayoutParams(params);
mv.setDrawingCacheEnabled(true);
mv.setAdjustViewBounds(true);
layout.addView(mv);
layout.addView(submitButton);
setContentView(layout);
mPaint = new Paint();
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(6);
}
private Paint mPaint;
#Override
public void colorChanged(int color)
{
mPaint.setColor(color);
Log.i("COLOR", color + "");
}
public class MyView extends ImageView
{
private Bitmap mBitmap, originalBitmap, originalNonResizedBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint mBitmapPaint;
Context context;
private BitmapFactory.Options options = new BitmapFactory.Options();
public MyView(Context c)
{
super(c);
context = c;
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
options.inMutable = true;
originalNonResizedBitmap = Bitmap.createBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.amsler_boundary, options));
originalNonResizedBitmap = getResizedBitmap(originalNonResizedBitmap);
originalBitmap = originalNonResizedBitmap.copy(Bitmap.Config.ARGB_8888, true);
mBitmap = originalBitmap.copy(Bitmap.Config.ARGB_8888, true);
mCanvas = new Canvas(mBitmap);
}
public MyView(Context context, AttributeSet attrs)
{
super(context, attrs);
}
#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 = 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 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();
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SCREEN));
// mPaint.setMaskFilter(null);
}
#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();
// Need to set null or clogs the Paint
mPaint.setXfermode(null);
invalidate();
break;
}
return true;
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
int newWidthMeasure = MeasureSpec.makeMeasureSpec(mBitmap.getWidth(), MeasureSpec.EXACTLY);
int newHeightMeasure = MeasureSpec.makeMeasureSpec(mBitmap.getHeight(), MeasureSpec.EXACTLY);
setMeasuredDimension(newWidthMeasure, newHeightMeasure);
// super.setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec),
// MeasureSpec.getSize(heightMeasureSpec));
// super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
public void clearScreen()
{
mCanvas.drawColor(Color.TRANSPARENT);
mCanvas.drawBitmap(originalBitmap, 0, 0, mBitmapPaint);
invalidate();
}
public Rect getCoordinateRect()
{
return new Rect(0, 0, mBitmap.getWidth(), mBitmap.getHeight());
}
}
public Bitmap getResizedBitmap(Bitmap bm)
{
int width = bm.getWidth();
int height = bm.getHeight();
WindowManager wm = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int newDimen = size.x;
float scaleWidth = ((float) newDimen) / width;
float scaleHeight = ((float) newDimen) / height;
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);
return resizedBitmap;
}
This is how the layout looks with the above code:
For now I want the canvas to just draw a color.
public class AndroidTentaTestActivity extends Activity {
private Bitmap bm;
private Canvas c;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.main);
bm = Bitmap.createBitmap(100, 100, Config.ARGB_8888);
c = new Canvas(bm);
c.drawARGB(100, 0, 0, 150);
}
}
The code above is what I´ve written so far that obviously does not work. I suspect the Bitmap is somehow not connected to what I am doing but I don´t know how to fix it. How do I?
Change the desired color in mPaint.setColor().
public class AndroidTentaTestActivity extends AppCompatActivity {
MyView mv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mv = new MyView(this);
mv.setDrawingCacheEnabled(true);
setContentView(mv);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(0xFFFF0000);
}
private Paint mPaint;
#Override
public void onClick(View v) {
}
public class MyView extends View {
private Bitmap mBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint mBitmapPaint;
Context context;
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);
mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(0xFFFFFFFF);
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
canvas.drawPath(mPath, mPaint);
}
private float mX, mY;
private static final float TOUCH_TOLERANCE = 1;
private void touch_start(float x, float y) {
//showDialog();
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); //2,2.old values
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;
}
}
LinearLayout ll = (LinearLayout) findViewById(R.id.rect);
Paint paint = new Paint();
paint.setColor(Color.parseColor("#CD5C5C"));
Bitmap bg = Bitmap.createBitmap(ll.getWidth(),ll.getHeight() , Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bg);
canvas.drawARGB(200, 0, 225, 255);
ll.setBackgroundDrawable(new BitmapDrawable(bg));