Unable to draw rectangle over imageview - android

I am Getting a problem drawing rectangle over imageview. Here is the peace of code. Xml is also there . my whole concern is if we can draw rect over imageview.??
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.cropimage);
paint=new Paint();
bobj = new BaldBooth1();
bm = BaldBooth1.bMap;
d = new BitmapDrawable(bm);
iv = ((ImageView) findViewById(R.id.image));
iv.setImageDrawable(d);
createRectInView(iv);
((ImageButton) findViewById(R.id.next)).setOnClickListener(this);
}
public void createRectInView(View v) {
paint.setColor(Color.BLACK);
paint.setStrokeWidth(3);
canvas=new Canvas();
canvas.drawRect(50, 50, 80, 80, paint);
v.draw(canvas);
}

Your method createRectInView(View v) does not draw a rectangle over ImageView, it just create a canvas, draw a rectangle on that canvas, then draw the content of ImageView on that canvas, so it does not do what you expect.
Here is one possible resolution: you can extend ImageView and override its onDraw() method, for example..
public class ExtendedImageView extends ImageView {
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setColor(Color.BLACK);
paint.setStrokeWidth(3);
canvas.drawRect(50, 50, 80, 80, paint);
}
}
Updated:
Hi arun, I just test the code, and it works fine. Here are the details: for example, you can create the ExtendedImageView in package com.abc.widget, so in your cropImage.xml file, replace the <ImageView android:id="#+id/image" android:layout_width="wrap_content" android:layout_height="wrap_content"> to <com.abc.widget.ExtendedImageView android:id="#+id/image" android:layout_width="wrap_content" android:layout_height="wrap_content">. As you see, you only need to change the class name. Then changed the onCreate() method as:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.cropimage);
bobj = new BaldBooth1();
bm = BaldBooth1.bMap;
d = new BitmapDrawable(bm);
iv = ((ImageView) findViewById(R.id.image));
iv.setImageDrawable(d);
((ImageButton) findViewById(R.id.next)).setOnClickListener(this);
}

Related

Android : Unable to draw line on canvas using a on click function

I am instantiating the canvas variable in the onCreate function and if i draw a line in onCreate function, it is displayed fine. However, if i draw the line in an onClick function of a button, it does not work. What could be the reason.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
imageView = (ImageView) this.findViewById(R.id.imageView);
BitmapDrawable drawable = (BitmapDrawable) imageView.getDrawable();
Bitmap bitmap = drawable.getBitmap();
Bitmap mutableBitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
canvas = new Canvas(mutableBitmap);
imageView.setImageBitmap(mutableBitmap);
paint = new Paint();
paint.setColor(Color.rgb(255, 153, 51));
paint.setStrokeWidth(10);
}
public void displayLine(View view) {
canvas.drawLine(10, 20, 400, 500, paint);
}
Not that I would necessarily do it this way... but have you tried adding an invalidate call? i.e.:
public void displayLine(View view) {
canvas.drawLine(10, 20, 400, 500, paint);
view.invalidate();
}

How to draw on canvas and convert to bitmap?

I'm tring to draw some line and shapes on canvas and then convert it to bitmap on ImageView. I'm usin a custom class that extands "View" and on "OnDraw method i'm drawing the lines. here is my code(this class only draw simple lines) :
public class finalDraw extends View {
public finalDraw(Context context) {
super(context);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setColor(Color.BLUE);
for (int i = 0; i <100; i++) {
canvas.drawLine(xStart * i + 50 , yStart , stopX + 30 , stopY,paint);
}
invalidate();
}
}
How can i get the drawing result and show it on ImageView?
Thanks!
Found this article may help: http://www.informit.com/articles/article.aspx?p=2143148&seqNum=2
draw.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Bitmap imageBitmap = Bitmap.createBitmap(imageView.getWidth(), imageView.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(imageBitmap);
float scale = getResources().getDisplayMetrics().density;
Paint p = new Paint();
p.setColor(Color.BLUE);
p.setTextSize(24*scale);
canvas.drawText("Hello", imageView.getWidth()/2, imageView.getHeight()/2, p);
imageView.setImageBitmap(imageBitmap);
}
});
Create a Canvas with a bitmap, by Canvas(Bitmap bitmap). All draws to that canvas will in that bitmap.

How to clean canvas area by finger

i have two imageviews one is gallery image and one is transparent image drawn throw canvas on second image and i want to clean that transparent image by finger
i trying to do like
Link:https://play.google.com/store/apps/details?id=com.steam.doodle&hl=en
i tryd below code
public class MainActivity extends Activity implements OnTouchListener {
ImageView image,transimage;
Paint paint;
Bitmap bitmap,resultbitmap;
Canvas canvas;
Button clear;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
image=(ImageView)findViewById(R.id.imageView1);
transimage=(ImageView)findViewById(R.id.imageView2);
//Bitmap mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.saibaba);
Bitmap mBitmap2 = BitmapFactory.decodeResource(getResources(), R.drawable.snw);
Bitmap bmOverlay = Bitmap.createBitmap(mBitmap2.getWidth(), mBitmap2.getHeight(), mBitmap2.getConfig());
Canvas canvas = new Canvas();
canvas.setBitmap(bmOverlay);
paint=new Paint();
paint.setAlpha(200);
// canvas.drawBitmap(mBitmap, 0, 0, null);
canvas.drawBitmap(mBitmap2, 0, 0, paint);
transimage.setImageBitmap(bmOverlay);
}
}
How to clean the canvas by finger
You just need to set Color= Transparent on the method onDraw. This is the tested code and is working.
#Override
protected void onDraw(Canvas canvas) {
if(isEraseMode){
paint.setColor(Color.TRANSPARENT);
canvas.drawPath(eraserPath, erasePaint);
//canvas.save();
}else{
canvas.drawPath(path, paint);
canvas.restore();
}
canvas.drawPath(path, paint);
super.dispatchDraw(canvas);
}
Hope this would help you..:)

Draw a bitmap tiled across a Rect android

I am attempting to draw a bitmap along a rectangle, but I am not sure how to go about it. Is there a way to tile a bitmap along a Rect object using a paint property or something? I have looked, but I can't find anything that makes it do what I need it too, most of the tiling options won't tile it for a specific instance, they tile it along the entire screen, so everything using that bitmap ends up having one big bitmap tiling along all of them at the same time, without scrolling or anything.
Any ideas? If you need more info let me know, its kind of a weird question so I know I probably didn't mention something important.
William
There are a couple ways that you can attack this. I'll outline two of them here...
One way:
You can define a BitmapDrawable around the Bitmap. Set its TileMode to repeat. Give it some bounds via setBounds(rect) where rect is your Rect instance.
Here's a brief example using a View onDraw as context:
public class MyView extends View {
Rect rect;
Bitmap mBitmap;
BitmapDrawable mDrawable;
public MyView(Context context) {
super(context);
rect = new Rect(0, 0, 100, 100);
mBitmap = loadBitmap();
mDrawable = new BitmapDrawable(context.getResources(), mBitmap);
mDrawable.setTileModeXY(TileMode.REPEAT, TileMode.REPEAT);
mDrawable.setBounds(rect);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mDrawable.draw(canvas);
}
public Bitmap loadBitmap() {
// included only for example sake
Paint paint = new Paint();
paint.setColor(Color.RED);
Bitmap bm = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bm);
canvas.drawRect(0,0,10,10, paint);
paint.setStyle(Style.STROKE);
paint.setColor(Color.BLUE);
canvas.drawRect(0, 0, 9, 9, paint);
return bm;
}
}
Note:
You can also define a BitmapDrawable in xml instead of doing it in code.
Also, if you know that a drawable you are loading via getResources().getDrawable(resourceId) is indeed just a Bitmap, you can cast it to a BitmapDrawable and set the TileMode there. A la:
public class MyView extends View {
Rect rect;
BitmapDrawable mDrawable;
public MyView(Context context) {
super(context);
rect = new Rect(0, 0, 400, 240);
mDrawable = (BitmapDrawable) context.getResources().getDrawable(R.drawable.ic_launcher);
mDrawable.setTileModeXY(TileMode.REPEAT, TileMode.REPEAT);
mDrawable.setBounds(rect);
this.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.ic_launcher));
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mDrawable.draw(canvas);
}
}
This example shows the background being stretched, and a tiled version being draw over top of it.
Another way:
Loop in the x and y direction and repeatedly draw the bitmap into the rect:
public class MyView extends View {
Rect rect;
Bitmap mBitmap;
public MyView(Context context) {
super(context);
rect = new Rect(0, 0, 100, 100);
mBitmap = loadBitmap();
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
final int bmWidth = mBitmap.getWidth();
final int bmHeight = mBitmap.getHeight();
for (int y = 0, height = rect.height(); y < height; y += bmHeight) {
for (int x = 0, width = rect.width(); x < width; x += bmWidth) {
canvas.drawBitmap(mBitmap, x, y, null);
}
}
}
public Bitmap loadBitmap() {
// included only for example sake
Paint paint = new Paint();
paint.setColor(Color.RED);
Bitmap bm = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bm);
canvas.drawRect(0,0,10,10, paint);
paint.setStyle(Style.STROKE);
paint.setColor(Color.BLUE);
canvas.drawRect(0, 0, 9, 9, paint);
return bm;
}
}
I personally would go for the first (BitmapDrawable) method.
You can do it just like BitmapDrawable does:
Define Paint with bitmap shader and then draw rectangle with that paint:
> Paint paint = new Paint();
> paint.setShader(new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT));
>
> canvas.drawRect(destRect, paint);

Erase bitmap parts using PorterDuff mode

I try to erase parts of a bitmap in my Android application by using Porter-Duff Xfermodes.
I have a green background which is overlayed by a blue bitmap. When I touch the screen a "hole" in the overlaying bitmap is supposed to be created making the green background visible. Instead of a hole my current code produces a black dot.
Below is my code. Any ideas, what I am doing wrong here?
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(new DrawView(this));
}
public class DrawView extends View implements OnTouchListener {
private int x = 0;
private int y = 0;
Bitmap bitmap;
Canvas bitmapCanvas;
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.GREEN);
// Set bitmap
bitmap = Bitmap.createBitmap(320, 480, Bitmap.Config.RGB_565);
bitmapCanvas = new Canvas();
bitmapCanvas.setBitmap(bitmap);
bitmapCanvas.drawColor(Color.BLUE);
// Set eraser paint properties
eraserPaint.setAlpha(0);
eraserPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
eraserPaint.setAntiAlias(true);
}
#Override
public void onDraw(Canvas canvas) {
bitmapCanvas.drawColor(Color.BLUE);
bitmapCanvas.drawCircle(x, y, 10, eraserPaint);
canvas.drawBitmap(bitmap, 0, 0, paint);
}
public boolean onTouch(View view, MotionEvent event) {
x = (int) event.getX();
y = (int) event.getY();
invalidate();
return true;
}
}
Here is working code... may help somebody
public class ImageDemo extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new Panel(this));
}
class Panel extends View {
private Bitmap mBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint mPaint;
Bitmap bitmap;
Canvas pcanvas;
int x = 0;
int y =0;
int r =0;
public Panel(Context context) {
super(context);
Log.v("Panel", ">>>>>>");
setFocusable(true);
setBackgroundColor(Color.GREEN);
// setting paint
mPaint = new Paint();
mPaint.setAlpha(0);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
mPaint.setAntiAlias(true);
// getting image from resources
Resources r = this.getContext().getResources();
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.mickey);
// converting image bitmap into mutable bitmap
bitmap = bm.createBitmap(295, 260, Config.ARGB_8888);
pcanvas = new Canvas();
pcanvas.setBitmap(bitmap); // drawXY will result on that Bitmap
pcanvas.drawBitmap(bm, 0, 0, null);
}
#Override
protected void onDraw(Canvas canvas) {
// draw a circle that is erasing bitmap
pcanvas.drawCircle(x, y, r, mPaint);
canvas.drawBitmap(bitmap, 0, 0,null);
super.onDraw(canvas);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
// set parameter to draw circle on touch event
x = (int) event.getX();
y = (int) event.getY();
r =20;
// At last invalidate canvas
invalidate();
return true;
}
}
}
First thought, I'm not sure if setting alpha to 0 on your erase paint object is a good idea. That might make the whole thing ineffective.
Also, you should always use Bitmap.Config.ARGB_8888 if you're dealing with alphas.
If you're having trouble with the PorterDuff stuff, though, I would suggest simplifying your approach to ONLY do that (temporarily). That will help you narrow down the part which isn't working. Comment out everything to do with touch and view updates.
Then you can single out what part of the drawing isn't working right. Set up your constructor like this:
DrawView()
{
/* Create the background green bitmap */
...
/* Create foreground transparent bitmap */
...
/* Draw a blue circle on the foreground bitmap */
...
/* Apply the foreground to the background bitmap
using a PorterDuff method */
...
}
onDraw()
{
/* Simply draw the background bitmap */
...
}
If you set things up like that, you should be able to tell how your PD method is affecting the green bitmap, and change things accordingly.
Here is another advancement for your solution ... See 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;
}
}
}
read more

Categories

Resources