Draw a Bitmap on a Canvas replacing Black Pixels to Transparent - android

I need to draw a Bitmap on a canvas but I need to remove the black pixels to transparent. Is there an easy way to do this in Android? Bitmap.clearColor seems to behave differently.

Check to make sure the overlay bitmap you've created is actually transparent. Create it with config ARGB_8888 explicitly. http://developer.android.com/reference/android/graphics/Bitmap.Config.html
And you might want to move the creation of the bitmap out of the reDraw method and only create it once instead.

it will works on on touch
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BlurMaskFilter.Blur;
import android.graphics.BitmapFactory;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
public class StartActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new TouchView(this));
}
class TouchView extends View{
Bitmap bgr;
Bitmap overlayDefault;
Bitmap overlay;
Paint pTouch;
int X = -100;
int Y = -100;
Canvas c2;
public TouchView(Context context) {
super(context);
bgr = BitmapFactory.decodeResource(getResources(),R.drawable.bgr);
overlayDefault = BitmapFactory.decodeResource(getResources(),R.drawable.over);
overlay = BitmapFactory.decodeResource(getResources(),R.drawable.over).copy(Config.ARGB_8888, true);
c2 = new Canvas(overlay);
pTouch = new Paint(Paint.ANTI_ALIAS_FLAG);
pTouch.setXfermode(new PorterDuffXfermode(Mode.SRC_OUT));
pTouch.setColor(Color.TRANSPARENT);
pTouch.setMaskFilter(new BlurMaskFilter(15, Blur.NORMAL));
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN: {
X = (int) ev.getX();
Y = (int) ev.getY();
invalidate();
break;
}
case MotionEvent.ACTION_MOVE: {
X = (int) ev.getX();
Y = (int) ev.getY();
invalidate();
break;
}
case MotionEvent.ACTION_UP:
break;
}
return true;
}
#Override
public void onDraw(Canvas canvas){
super.onDraw(canvas);
//draw background
canvas.drawBitmap(bgr, 0, 0, null);
//copy the default overlay into temporary overlay and punch a hole in it
c2.drawBitmap(overlayDefault, 0, 0, null); //exclude this line to show all as you draw
c2.drawCircle(X, Y, 80, pTouch);
//draw the overlay over the background
canvas.drawBitmap(overlay, 0, 0, null);
}
}
}`

Check this answer. It's not accepted but should work. Dont forget to turn of hardware acceleration for view where you use this bitmap.

Related

Draw line progressively in android

I found some code to draw line and now i wand drawing line progressively so that i cloud see it being drawn.
This is the code
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.View;
public class DrawView extends View {
Paint paint = new Paint();
public DrawView(Context context) {
super(context);
paint.setColor(Color.BLACK);
}
#Override
public void onDraw(Canvas canvas) {
canvas.drawLine(0, 0, 20, 20, paint);
canvas.drawLine(20, 0, 0, 20, paint);
}
}
How can i do that?
Tnx
Did you see that?
Look at source code ;)
http://www.curious-creature.com/2013/12/21/android-recipe-4-path-tracing/
You will want to break up your drawing into multiple steps. Inside your onDraw call, you will want to draw a part of your line, and update a variable so that the next line segment is drawn. Then you will want to make multiple onDraw() calls in an animation loop. You will need to be careful where you make your calls to the animation loop from. Read about the View class for more information, particular event handling and threading. http://developer.android.com/reference/android/view/View.html
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.View;
public class DrawView extends View {
Paint paint = new Paint();
float x1 = 0;
float x2 = 20;
float y1 = 0;
float y2 = 20;
public DrawView(Context context) {
super(context);
paint.setColor(Color.BLACK);
}
#Override
public void onDraw(Canvas canvas) {
if(doClear) {
//clear canvas to begin new animation
}
canvas.drawLine(x1, y1, x2, y2, paint);
}
public void animateLoop() {
while(x1 < 500) {
x1 += 20;
y1 += 20;
x2 += 20;
y2 += 20;
//tell android this view needs to be redrawn
invalidate();
}
//when done set doClear to true so
}
If you really want to learn about animation, you should start with something like this example: http://developer.android.com/guide/topics/graphics/drawable-animation.html.

How to save canvas drawing and display it when the button is clicked

hey i am trying to create android app where i can draw on canvas with two buttons on the bottom
i managed to get the drawing to work however right now i need to add two buttons(one is for saving the drawing canvas into database (Sqlite if possible) or bitmap and the other one to import the image from the sqlite and display it into the graphicview)
right now i have no idea what code i have to put into it to make the save and display button works so please help me with the code and thank you for your time :)
here is my code at the moment (the graphic drawing works fine and now i need the code for the save and display button as well as what ive missed in the graphicview.java and MainActivity.java)
GraphicsView.java
package org.example.graphics;
import java.util.ArrayList;
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.graphics.Path.Direction;
import android.view.*;
public class GraphicsView extends View implements View.OnTouchListener {
public GraphicsView(Context context) {
super(context);
setBackgroundColor(Color.WHITE);
setOnTouchListener(this);
}
ArrayList<MyPoint> arrOfPoints=new ArrayList<MyPoint>();
class MyPoint
{
float x, y;
}
float downx, downy;
#Override
protected void onDraw(Canvas canvas) {
// Drawing commands go here
Paint rectPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
rectPaint.setStyle(Paint.Style.FILL_AND_STROKE);
rectPaint.setColor(Color.BLACK);
canvas.drawRoundRect(new RectF(0, 0, 100, 100), 10, 10, rectPaint);
rectPaint.setColor(Color.BLUE);
rectPaint.setAlpha(40);
canvas.drawCircle(300, 300, 200, rectPaint);
canvas.drawRect(new RectF(40, 40, 200, 200), rectPaint);
Paint textPaint = new Paint(Paint.ANTI_ALIAS_FLAG
| Paint.STRIKE_THRU_TEXT_FLAG);
canvas.drawText("Hello there!", 200, 200, textPaint);
canvas.drawText("You clicked on " + downx + "," + downy, 200, 600,
textPaint);
for(int i=0;i<arrOfPoints.size();i++)
{
canvas.drawCircle(arrOfPoints.get(i).x, arrOfPoints.get(i).y, 20, rectPaint);
}
}
#Override
public boolean onTouch(View arg0, MotionEvent arg1) {
int action = arg1.getAction();
MyPoint p=null;
switch (action) {
case MotionEvent.ACTION_DOWN:
downx = arg1.getX();
downy = arg1.getY();
p=new MyPoint();
p.x=arg1.getX();p.y=arg1.getY();
arrOfPoints.add(p);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
downx = arg1.getX();
downy = arg1.getY();
p=new MyPoint();
p.x=arg1.getX();p.y=arg1.getY();
arrOfPoints.add(p);
invalidate();
break;
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_CANCEL:
break;
default:
break;
}
return true;
}
MainActivity.java
package org.example.graphics;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Path.Direction;
import android.graphics.RectF;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new GraphicsView(this));
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/background">
<org.example.graphics.GraphicsView
android:id="#+id/graphics"
android:layout_width="fill_parent"
android:layout_height="341dp" />
<Button
android:id="#+id/ChoosePictureButton"/>
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Choose Picture"
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Save Picture" android:id="#+id/SavePictureButton"/>
</LinearLayout>
My AndroidManifest.xml is still at default because i havent edit anything in it yet
You can use this code in your save button click listener.
int canvasWidth = 500;
int canvasHeight = 500;
View v = new GraphicsView(MainActivity.this);
Bitmap bitmap = Bitmap.createBitmap(canvasWidth, canvasHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
v.draw(canvas);
//now bitmap has your canvas image
//set it to your ImageView
yourImageView.setImageBitmap(bitmap);
//or save to sdcard
File dir = new File("/sdcard/yourAppFolder/");
if (!dir.isDirectory()) {
dir.mkdirs();
}
File outputFile = new File(dir, "image.jpg");
OutputStream fout = null;
fout = new FileOutputStream(outputFile);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fout);
fout.flush();
fout.close();

setXfermode(new PorterDuffXfermode(Mode.SRC_OUT)) is giving error

I have two images, one above one and i want to make the upper image transparent when user erase it and covered image should be shown...hear is my code
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BlurMaskFilter.Blur;
import android.graphics.BitmapFactory;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
public class StartActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new TouchView(this));
}
class TouchView extends View{
Bitmap bgr;
Bitmap overlayDefault;
Bitmap overlay;
Paint pTouch;
int X = -100;
int Y = -100;
Canvas c2;
public TouchView(Context context) {
super(context);
bgr = BitmapFactory.decodeResource(getResources(),R.drawable.bgr);
overlayDefault = BitmapFactory.decodeResource(getResources(),R.drawable.over);
overlay = BitmapFactory.decodeResource(getResources(),R.drawable.over).copy(Config.ARGB_8888, true);
c2 = new Canvas(overlay);
pTouch = new Paint(Paint.ANTI_ALIAS_FLAG);
pTouch.setXfermode(new PorterDuffXfermode(Mode.SRC_OUT));
pTouch.setColor(Color.TRANSPARENT);
pTouch.setMaskFilter(new BlurMaskFilter(15, Blur.NORMAL));
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN: {
X = (int) ev.getX();
Y = (int) ev.getY();
invalidate();
break;
}
case MotionEvent.ACTION_MOVE: {
X = (int) ev.getX();
Y = (int) ev.getY();
invalidate();
break;
}
case MotionEvent.ACTION_UP: {
break;
}
}
return true;
}
#Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
//draw background
canvas.drawBitmap(bgr, 0, 0, null);
//copy the default overlay into temporary overlay and punch a hole in it
c2.drawBitmap(overlayDefault, 0, 0, null); //exclude this line to show all as you draw
c2.drawCircle(X, Y, 80, pTouch);
//draw the overlay over the background
canvas.drawBitmap(overlay, 0, 0, null);
}
}
}
But I am getting error at line:
pTouch.setXfermode(new PorterDuffXfermode(Mode.SRC_OUT));
The error is:
"SRC_OUT cannot be resolved or is not a field".
Close, you need to ensure your Mode is from the correct package. What you should use is:
android.graphics.PorterDuff.Mode
Changing the problem line to:
pTouch.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT));

Canvas is not covering the whole screen

I am using an ImageView to create a canvas and draw elements with finger touch on it. But the problem is that, firstly the canvas only covers a little portion of the screen to draw or write something and secondly it produces lines or curves far away where I touch. I have one textview and the imageview in linear layout. Please check my code and help me for the same.
DrawTestActivity.java:
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.os.Bundle;
import android.view.Display;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;
public class MainActivity extends Activity implements OnTouchListener {
ImageView imageView;
Bitmap bitmap;
Canvas canvas;
Path path;
Paint paint;
float downx = 0, downy = 0, upx = 0, upy = 0;
float startX = 0;
float startY = 0;
float endX = 0;
float endY = 0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = (ImageView) this.findViewById(R.id.imageView1);
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
canvas = new Canvas(bitmap);
paint = new Paint();
paint.setColor(Color.BLUE);
paint.setAntiAlias(true);
paint.setStrokeWidth(6f);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
imageView.setImageBitmap(bitmap);
imageView.setOnTouchListener(this);
}
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
startX=event.getX();
startY=event.getY();
break;
case MotionEvent.ACTION_MOVE:
endX = event.getX();
endY = event.getY();
canvas.drawLine(startX,startY,endX,endY, paint);
imageView.invalidate();
startX=endX;
startY=endY;
break;
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_CANCEL:
break;
default:
break;
}
return true;
}
}

How to let the diagram drawed by canvas produce onclick event

I have an imageView and I draw the diagram in imageView according to the coordinate array. Every diagram has an onclick event.
Activity.java
package com.example.floorexhibitiontest;
import com.floor.DrawView;
import android.app.Activity;
import android.os.Bundle;
import android.widget.LinearLayout;
public class HallActivity extends Activity {#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.hall);
}
float[][][] points = new float[][][] {
{
{213,264},
{247,232},
{345,338},
{310,371}
},
{
{171,305},
{205,272},
{302,373},
{267,406}
},
{
{571,320},
{606,320},
{606,428},
{571,428}
}
};
LinearLayout layout = (LinearLayout)findViewById(R.id.root);
final DrawView draw = new DrawView(this,points);
layout.addView(draw);
}
DrawView.java
package com.floor;
import com.example.floorexhibitiontest.R;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Path;
import android.graphics.Paint.Style;
import android.graphics.Shader.TileMode;
import android.graphics.Shader;
import android.util.DisplayMetrics;
import android.view.View;
public class DrawView extends View{
private float[][][] points = null;
DisplayMetrics metric = new DisplayMetrics();
public DrawView(Context context,float[][][] p) {
super(context);
metric = context.getApplicationContext().getResources().getDisplayMetrics();
points = p;
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
float density=metric.density;
for(int i = 0; i < points.length; i++){
Paint p = new Paint();
p.setAntiAlias(true);
p.setColor(Color.BLUE);
Path path=new Path();
path.moveTo(points[i][0][0] / density, points[i][0][1] / density);
path.lineTo(points[i][1][0] / density, points[i][1][1] / density);
path.lineTo(points[i][2][0] / density, points[i][2][1] / density);
path.lineTo(points[i][3][0] / density, points[i][3][1] / density);
path.close();
p.setStyle(Style.STROKE);
canvas.drawPath(path, p);
}
}
}
At present effect:
How to let each rectangular drawed produce their own onclick event?
There is an ImageView in Layout file. My purpose is to put the graphics paint on the ImageView. But the result is ImageView can display. The painted graphics can not display. If I hide
ImageView, the image can display.
Ask everyone’s help. Thanks in advice.
Try smth like this:
public boolean onTouch(View v, MotionEvent event) {
if((event.getX(0)>=x_coord) &&
(event.getY(0)>=y_coord) &&
( event.getX(0)<=x_coord + your_rectangle_width) &&
(event.getY(0)<=y_coord + your_rectangle_heigth))
{
//rectangle selected
}
return true;
}
Or use in onTouch() your actual coordinates from points[] array

Categories

Resources