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

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));

Related

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();

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;
}
}

Draw a Bitmap on a Canvas replacing Black Pixels to Transparent

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.

paint canvas android

I'm developing in android, and I have to do a Paint for android.
I'm using the code below and, when I execute the code, the draw works, but, it seems that there are 2 surfaces to paint, and when you draw in one, the other one disappears.
I was looking for the exact error, but cannot find it.
Here is the code :
import java.util.Random;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.RelativeLayout;
public class MainActivity extends Activity {
MySurfaceView mySurfaceView;
Button Cuadrado;
Button Circulo;
Button Color;
Button Linea;
private boolean Bcuadrado,Bcirculo,Bcolor=false;
private boolean Blinea=true;
Canvas canvas = new Canvas();
#TargetApi(11)
#SuppressLint("NewApi")
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RelativeLayout mainLayout =(RelativeLayout)findViewById(R.id.main_layout_id );
View view =getLayoutInflater().inflate(R.layout.itemlayout, mainLayout,false);
mainLayout.addView(view);
mySurfaceView = new MySurfaceView(this);
Cuadrado=(Button)findViewById(R.id.button1);
Circulo=(Button)findViewById(R.id.button2);
Color=(Button)findViewById(R.id.button3 );
Linea=(Button)findViewById(R.id.button4 );
int w= view.getWidth();
int h= view.getHeight();
float x=view.getX();
float y= view.getY();
mySurfaceView.setY(100);
mainLayout.addView(mySurfaceView);
Cuadrado.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(Bcuadrado==false){
Bcuadrado=true;
Bcirculo=false;
Bcolor=false;
Blinea=false;
}
}
});
Circulo.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(!Bcirculo){
Bcuadrado=false;
Bcirculo=true;
Bcolor=false;
Blinea=false;
}
}
});
Color.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(!Bcolor){
Bcuadrado=false;
Bcirculo=false;
Bcolor=true;
Blinea=false;
}
}
});
Linea.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(!Blinea){
Bcuadrado=false;
Bcirculo=false;
Bcolor=false;
Blinea=true;
}
}
});
}
class MySurfaceView extends SurfaceView{
Path path;
SurfaceHolder surfaceHolder;
volatile boolean running = false;
private Paint paint = new Paint();
float x0=0;
float x1=0;
float y0=0;
float y1=0;
Random random = new Random();
public MySurfaceView(Context context) {
super(context);
surfaceHolder = getHolder();
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(3);
paint.setColor(android.graphics.Color.WHITE);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if(Blinea){
if(event.getAction() == MotionEvent.ACTION_DOWN){
path = new Path();
path.moveTo(event.getX(), event.getY());
}else if(event.getAction() == MotionEvent.ACTION_MOVE){
path.lineTo(event.getX(), event.getY());
}else if(event.getAction() == MotionEvent.ACTION_UP){
path.lineTo(event.getX(), event.getY());
}
if(path != null){
canvas = surfaceHolder.lockCanvas();
canvas.drawPath(path, paint);
surfaceHolder.unlockCanvasAndPost(canvas);
}
}else if(Bcuadrado){
if(event.getAction()==MotionEvent.ACTION_DOWN){
x0=event.getX();
y0=event.getY();
}
else if(event.getAction()==MotionEvent.ACTION_UP){
x1=event.getX();
y1=event.getY();
canvas = surfaceHolder.lockCanvas();
canvas.drawRect(x0, y0, x1, y1, paint);
surfaceHolder.unlockCanvasAndPost(canvas);
}
}else if(Bcirculo){
if(event.getAction()==MotionEvent.ACTION_DOWN){
x0=event.getX();
y0=event.getY();
}
else if(event.getAction()==MotionEvent.ACTION_UP){
x1=event.getX();
canvas=surfaceHolder.lockCanvas();
canvas.drawCircle(x0, y0,(x1-x0), paint);
surfaceHolder.unlockCanvasAndPost(canvas);
}
}else if(Bcolor){
int r = random.nextInt(255);
int g = random.nextInt(255);
int b = random.nextInt(255);
canvas=surfaceHolder.lockCanvas();
paint.setColor(0xff000000 + (r << 16) + (g << 8) + b);
surfaceHolder.unlockCanvasAndPost(canvas);
}
return true;
}
}
}
it seems that there are 2 surfaces to paint, and when you draw in one, the other one disappears.
That is exactly how SurfaceView works - it's double buffered. You need to redraw whole frame each time.
From Android's doc: SurfaceHolder
The content of the Surface is never preserved between unlockCanvas() and lockCanvas(), for this reason, every pixel within the Surface area must be written. The only exception to this rule is when a dirty rectangle is specified, in which case, non-dirty pixels will be preserved.
The canvas does not save what you previously wrote to it. Every time you call unlock(), you must redraw everything all over again.

How to rotate image with fix point along with touch in android

I've been looking for over a day for a solution to this problem but nothing helped, even the answers here didn't helped me.
my problem is my image is rotating but bitmap size is not varying while rotating.
here is my code
package dharam.rotate;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.os.Bundle;
import android.provider.ContactsContract.CommonDataKinds.Event;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.widget.ImageView;
import android.widget.TextView;
public class Rotate extends Activity {
View baseView ;
ImageView turntable;
TextView bottomText;
GestureDetector gestureDetector;
private float x , y;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
baseView = (View) findViewById(R.id.baseView);
turntable = (ImageView) findViewById(R.id.turntable);
turntable.setOnTouchListener(onTableTouched);
baseView.setOnTouchListener(onTableTouched);
}
public android.view.View.OnTouchListener onTableTouched = new android.view.View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent evt) {
double r = Math.atan2(evt.getX() - turntable.getWidth() / 2,
(turntable.getHeight() / 2) - evt.getY());
int rotation = (int) Math.toDegrees(r);
Log.i("R is ", ""+r);
if (evt.getAction() == MotionEvent.ACTION_DOWN) {
}
if (evt.getAction() == MotionEvent.ACTION_MOVE) {
x= evt.getX();
y= evt.getY();
updateRotation(rotation);
}
if (evt.getAction() == MotionEvent.ACTION_UP) {
//
}
return true;
}
};
private void updateRotation(double rot) {
float newRot = new Float(rot);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.orsl_circle_transparent);
Matrix matrix = new Matrix();
// matrix.setTranslate(getWindowManager().getDefaultDisplay().getWidth()/2, getWindowManager().getDefaultDisplay().getHeight());
matrix.postRotate(newRot,bitmap.getWidth()/2,bitmap.getHeight()/2);
// matrix.setSinCos(newRot, newRot/2, 100, 100);
// matrix.postRotate(newRot);
Log.i("THE ROATTION ", " "+ newRot);
if(y>250)
{
Bitmap redrawnBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap
.getWidth(), bitmap.getHeight(), matrix, true);
turntable.setImageBitmap(redrawnBitmap);
}else
{
Bitmap redrawnBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap
.getWidth(), bitmap.getHeight(), matrix, true);
turntable.setImageBitmap(redrawnBitmap);
Log.i("GUITAR _IMAGE", "");
}
}
}
I presume you want to rotate an image at the point where a user touches the screen? If so, extend the SimpleOnGestureListener like this example:
public class MyGestureDetector extends SimpleOnGestureListener
{
#Override
public void onLongPress(MotionEvent event)
{
int X = (int)event.getX();
int Y = (int)event.getY();
...Rotate the image
}
}
Once you've got the screen coordinates of the touch event, you could apply a Rotation Animation about the point - see here for more details: http://developer.android.com/guide/topics/graphics/2d-graphics.html
I checked your code just by not taking the baseview and it works fine. Here is my code and it works fine in my emulator.
package com.android.practice;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;
public class JobSearch extends Activity implements OnTouchListener {
private ImageView dialer;
private float y=0;
public boolean onTouch(View v, MotionEvent event) {
double r=Math.atan2(event.getX()-dialer.getWidth()/2, dialer.getHeight()/2-event.getY());
int rotation=(int)Math.toDegrees(r);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
//x=event.getX();
y=event.getY();
updateRotation(rotation);
break;
case MotionEvent.ACTION_UP:
break;
}//switch
return true;
}//onTouch
private void updateRotation(double rot){
float newRot=new Float(rot);
Bitmap bitmap=BitmapFactory.decodeResource(getResources(),R.drawable.round_button_big);
Matrix matrix=new Matrix();
matrix.postRotate(newRot,bitmap.getWidth()/2,bitmap.getHeight()/2);
if(y>250){
Bitmap reDrawnBitmap=Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,true);
dialer.setImageBitmap(reDrawnBitmap);
}
else{
Bitmap reDrawnBitmap=Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,true);
dialer.setImageBitmap(reDrawnBitmap);
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
dialer = (ImageView) findViewById(R.id.big_button);
dialer.setOnTouchListener(this);
}//onCreate
}

Categories

Resources