I have made a paint app in which i have used ImageView in layout to show image that can be taken from camera or gallery.I want to draw transparent line over image so that image can be seen after drawing.please help me.
Thanks for support
I have used the code to make draw line transparent is :
myPaint.setAlpha(50);
My code is:
protected void onDraw(Canvas canvas) {
Toast.makeText(PaintScreen.this, "onDraw is called", Toast.LENGTH_SHORT).show();
// myPaint.setAlpha(100);
canvas.drawBitmap(PaintScreen.this.localBitmap, 0,0,null);
// canvas.drawPath(myPath, paintBlur);
canvas.drawPath(myPath, myPaint); Log.i("OnDRAWING", "REACH ON DRAW"); }
public class CustomView extends ImageView {
private float mX, mY;
public CustomView(Context context) {
super(context);
localBitmap = Bitmap.createBitmap(myBitmap.getWidth(), myBitmap.getHeight(), Config.ARGB_8888);
myCanvas = new Canvas(localBitmap);
myPaint = new Paint(); setPaintForDraw(paintcolor, false, 30);
setFocusable(true);
setFocusableInTouchMode(true); myPath = new Path();
}
}
private void setPaintForDraw(int color, boolean eraseMode, int brushSize) {
//myPaint.setAlpha(100);
myPaint.setAntiAlias(true);
myPaint.setDither(true);
myPaint.setStyle(Paint.Style.STROKE);
myPaint.setColor(color);
myPaint.setStrokeCap(Paint.Cap.ROUND);
myPaint.setStrokeJoin(Paint.Join.ROUND);
myPaint.setStrokeWidth(brushSize);
myPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
if (eraseMode) {
myPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
}
else { myPaint.setXfermode(null); }
}
see this thread How to maintain multi layers of ImageViews and keep their aspect ratio based on the largest one?, here you can use multiple Draeable layers that are drawn over the image
First, you have to check that your Bitmap is mutable. If it is not, make a copy of it. And here is how you can draw a line on your image:
Bitmap copyBmp = yourBMP.copy(Bitmap.Config.ARGB_8888, true); //Copy if yourBMP is not mutable
Canvas canvas = new Canvas(copyBmp);
Paint paint = new Paint();
paint.setAlpha(50); //Put a value between 0 and 255
paint.setColor(Color.GRAY); //Put your line color
paint.setStrokeWidth(5); //Choose the width of your line
canvas.drawLine(startX, startY, stopX, stopY, paint); //Set the coordinates of the line
Now, if you display copyBmp, you should see a line drawn over it.
Related
What steps are required to create a shape e.g. rectangle with a shadow from scratch using a Canvas?
Adding a shadow layer to the paint used to draw the rectangle yielded no success.
No need for a Bitmap, just needed to set the layer type to LAYER_TYPE_SOFTWARE the original approach worked.
public class TestShapeShadow extends View
{
Paint paint;
public TestShapeShadow(Context context)
{
super(context);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setShadowLayer(12, 0, 0, Color.YELLOW);
// Important for certain APIs
setLayerType(LAYER_TYPE_SOFTWARE, paint);
}
#Override
protected void onDraw(Canvas canvas)
{
canvas.drawRect(20, 20, 100, 100, paint);
}
}
I followed the ideas in #pskink's answer and found a solution.
I put the code snippet here for anyone in need.
public class MyViewWithShadow extends View {
Paint paint;
int mainColor;
int shadowColor;
// shadow properties
int offsetX = -25;
int offsetY = 30;
int blurRadius = 5;
public MyViewWithShadow(Context context)
{
super(context);
mainColor = Color.RED;
shadowColor = Color.BLACK; // this color can also have alpha
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setStyle(Paint.Style.FILL);
}
#Override
protected void onDraw(Canvas canvas)
{
// Create paint for shadow
paint.setColor(shadowColor);
paint.setMaskFilter(new BlurMaskFilter(
blurRadius /* shadowRadius */,
BlurMaskFilter.Blur.NORMAL));
// Draw shadow before drawing object
canvas.drawRect(20 + offsetX, 20 + offsetY, 100 + offsetX, 100 + offsetY, paint);
// Create paint for main object
paint.setColor(mainColor);
paint.setMaskFilter(null);
// Draw main object
canvas.drawRect(20, 20, 100, 100, paint);
}
}
[Link is now broken:]
If you wonder what shadow properties are, you can refer to this tester:
https://okawa-h.github.io/box-shadow_tester/~
create. a Path, add some elements to it
set BlurMaskFilter to a Paint
draw a path with dx, dy shadow offset
unset mask filter
draw a path again with no. offset
Hello i added rectangle in my canvas now i want to add textview or some other view in that rectangle.Suggest me some tutorial also. Thanks in advance
public class DrawView extends View {
public DrawView(Context context) {
super(context);
}
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Rect rect = new Rect();
rect.set(20 ,10 ,canvas.getWidth()/2, canvas.getHeight()/2);
Paint paint = new Paint();
paint.setColor(Color.GREEN);
canvas.drawRect(rect, paint);
}
}
You can draw text on your canvas.
Paint mpaint= new Paint();
mpaint.setColor(Color.RED);//set red color for rectangle
mpaint.setStyle(Paint.Style.FILL);//mpaint will fill the rectangle
Paint paint2 = new Paint();
paint2.setColor(Color.GREEN);//green color for text
paint2.setTextSize(30f);//set text size. you can change the stroke width also
#Override
protected void onDraw(Canvas canvas)
{
canvas.drawRect(30, 30, 600, 600, mpaint);
canvas.drawText("hello", 150, 150, paint2);//change x and y according to your needs
}
Resulting snapshot on samsung galaxy s3
Adding a View of any kind is out of question here since you are simply drawing on a canvas. But Canvas.drawText(...) might be exactly what you are looking for.
So I've been struggling with this for a better part of a day. Suppose I have a custom ImageView that I want to overlay over a background View (both within a RelativeLayout), which when touched, it erases portions of the View's source bitmap like an erase tool in MS Paint, exposing the View below it. I've checked pretty much all of the threads (like this one) and they suggest to use PorterDuff SRC Mode in the Paint object as well as creating a Canvas out out the ARGB_8888 shadow copy of the source bitmap to apply the masking.
Also, I can't set the source of the overlay ahead of time since I have to download it over the network so that the ImageView's scale type takes care of the scaling for me.
Every time I override onDraw, when I apply the erase on the IV's Bitmap, it unveils a black background instead of the view below it, even though I set the background to transparent. So I'm at my last rope as to what to do in order to unveil the background view.
Here's what I have so far:
view constructor:
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
paint.setColor(Color.TRANSPARENT);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeWidth(STROKE_WIDTH);
paint.setAntiAlias(true);
overrode setImageBitmap to set my canvas from my re-configed source bitmap:
public void setImageBitmap(Bitmap bitmap){
super.setImageBitmap(bitmap);
Drawable bd = getDrawable();
if(bd == null){
return;
}
Bitmap fullSizeBitmap = ((BitmapDrawable) bd).getBitmap();
overlay = fullSizeBitmap.copy(Config.ARGB_8888, true);
c2 = new Canvas(overlay);
}
onDraw method:
protected void onDraw(Canvas canvas) {
/*
* Override paint call by re-drawing the view's Bitmap first, then overlaying our path on top of it
*/
Drawable bd = getDrawable();
if(bd == null){
return;
}
Bitmap fullSizeBitmap = ((BitmapDrawable) bd).getBitmap();
if(fullSizeBitmap != null && c2 != null){
canvas.drawColor(Color.TRANSPARENT);
c2.drawBitmap(fullSizeBitmap, 0, 0, null);
c2.drawPath(path, paint);
canvas.drawBitmap(overlay, 0, 0, null);
}
}
I know this is a really old question but here is what I did to fix a similar problem I had. Maybe it helps someone in the future.
From API level 11 and up you have to specify this piece of code for your ImageView to unveil the image in the back and not a black area.
if (Build.VERSION.SDK_INT >= 11) {
imageview.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
This helped me displaying the back image successfully
Can you try this solution it will help you with the erasing images in android on touch .. Or download a demo example
public class MainActivity extends Activity {
Bitmap bp;
Canvas bitmapCanvas;
DrawView drawImg;
LinearLayout ln1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ln1 = (LinearLayout) findViewById(R.id.ln1);
drawImg = new DrawView(this);
ln1.addView(drawImg);
}
public class DrawView extends View implements View.OnTouchListener {
private int x = 0;
private int y = 0;
Bitmap bitmap;
Path circlePath;
Paint circlePaint;
private final Paint paint = new Paint();
private final Paint eraserPaint = new Paint();
public DrawView(Context context){
super(context);
setFocusable(true);
setFocusableInTouchMode(true);
this.setOnTouchListener(this);
// Set background
this.setBackgroundColor(Color.CYAN);
bp = BitmapFactory.decodeResource(getResources(), R.drawable.bg);
// Set bitmap
bitmap = Bitmap.createBitmap(320, 480, Bitmap.Config.ARGB_8888);
bitmapCanvas = new Canvas();
bitmapCanvas.setBitmap(bitmap);
bitmapCanvas.drawColor(Color.TRANSPARENT);
bitmapCanvas.drawBitmap(bp, 0, 0, null);
circlePath = new Path();
circlePaint = new Paint();
circlePaint.setAntiAlias(true);
circlePaint.setColor(Color.BLUE);
circlePaint.setStyle(Paint.Style.STROKE);
circlePaint.setStrokeJoin(Paint.Join.MITER);
circlePaint.setStrokeWidth(4f);
// Set eraser paint properties
eraserPaint.setAlpha(0);
eraserPaint.setStrokeJoin(Paint.Join.ROUND);
eraserPaint.setStrokeCap(Paint.Cap.ROUND);
eraserPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
eraserPaint.setAntiAlias(true);
}
#Override
public void onDraw(Canvas canvas) {
canvas.drawBitmap(bitmap, 0, 0, paint);
bitmapCanvas.drawCircle(x, y, 30, eraserPaint);
canvas.drawPath(circlePath, circlePaint);
}
public boolean onTouch(View view, MotionEvent event) {
x = (int) event.getX();
y = (int) event.getY();
bitmapCanvas.drawCircle(x, y, 30, eraserPaint);
circlePath.reset();
circlePath.addCircle(x, y, 30, Path.Direction.CW);
int ac=event.getAction();
switch(ac){
case MotionEvent.ACTION_UP:
Toast.makeText(MainActivity.this, String.valueOf(x), Toast.LENGTH_SHORT).show();
circlePath.reset();
break;
}
invalidate();
return true;
}
}
}
I would like to animate a single Path on the android canvas.
public class MyView extends View {
private Path paths[];
protected void onDraw( Canvas canvas ) {
Paint paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth( 8 );
paint.setColor(Color.BLUE);
Path path = new Path();
path.moveTo(75, 11);
path.quadTo(62, 87, 10, 144);
canvas.drawPath( path, paint );
paths[0] = path;
path.reset();
path.moveTo(50, 100);
path.lineTo(150, 200);
canvas.drawPath( path, paint );
paths[1] = path;
}
}
Now I have paths[], I would like to animate each one separately. I would like it to change alpha like it was growing. At first there is just a little dot, then it grows into a line, repeat.
Can it be done?
How?
I would add a new float ranging from 0 to 1 that keeps the current animation percentage and use it to set the current alpha
public class MyView extends View {
private Path paths[];
private float mAnimPercentage = 0.0f;
private static final int clip(int value){ //forces the value to be between 0 and 255
return Math.max(0, Math.min(255, value));
}
protected void onDraw( Canvas canvas ) {
Paint paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth( 8 );
paint.setColor(Color.BLUE);
Path path = new Path();
path.moveTo(75, 11);
path.quadTo(62, 87, 10, 144);
//edited here
paint.setAlpha(clip(mAnimPercentage*255*2));
canvas.drawPath( path, paint );
paths[0] = path;
path.reset();
path.moveTo(50, 100);
path.lineTo(150, 200);
//edited here
paint.setAlpha(clip(-127 + mAnimPercentage*255*2)); //the biggest is the negative value, the latter this path will show, the biggest is the number multiplied by mAnimPercentage, the fastest this path will get completely opaque
canvas.drawPath( path, paint );
paths[1] = path;
mAnimPercentage+= 0.01; //FIXME this is for TEST only, you should update it with an animator
postInvalidate();
}
}
I want to draw an oval shape around the text on Canvas, I am displaying the 3 texts on Canvas using drawwText() method.
Now when I click on a particular text, I need to draw an oval around that text and again when we click on another text, the oval shape should appear on the clicked text. For this give me some code suggestions.Thanks in advance
use drawOval method().. here is the signature of the method..
public void drawOval (RectF oval, Paint paint)
RectF is class for drawing rectangle...whose constructor is defined as following...
RectF(x,y,x+width,y+height);
you can make its object as follows
RectF rect = new RectF(x,y,x+width,y+height);...
now pass this object in drawOval method....
canvas.drawOval(rect,paint);
for resolution (480 x 800)
in onCreate()
setContentView(new SampleView(this));
create class
private static class SampleView extends View {
// CONSTRUCTOR
public SampleView(Context context) {
super(context);
setFocusable(true);
}
#SuppressLint("DrawAllocation")
#Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
//1
Paint paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.GRAY);
RectF oval1 = new RectF(0, 0, 250,250);
Paint p1 = new Paint();
p1.setColor(Color.BLACK);
canvas.drawText("Parent", 30, 50, p1);
canvas.drawOval(oval1, paint);
//2
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.BLUE);
RectF oval2 = new RectF(50, 50, 150, 150);
Paint p2 = new Paint();
p2.setColor(Color.GREEN);
canvas.drawText("Child", 75, 75, p2);
canvas.drawOval(oval2, paint);
}
}