How to fit image on canvas without loosing quality of image - android

I am drawing image on canvas.But image it displaying image on center.But i want to fit the images on entire canvas without scale the image.
#Override
protected void onDraw(Canvas canvas) {
canvas.save();
canvas.drawBitmap(mBitmap,
(BaseActivity.width / 2) - mBitmap.getWidth()/2,
(BaseActivity.height / 2) - mBitmap.getHeight()/2,
mPaint);
canvas.restore();
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.RED);
paint.setTextSize(12.0f);
}
If anyone have idea.Please reply.Thanks in advance.

I hope you are extending View class...
use getWidth() and getHeight() to get corresponding dimensions and draw the Bitmap...
private Bitmap bitmap;
private Paint mPaint;
private Rect imageRect;
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if(imageRect == null) { // I think it is always false as we are intializing it onSizeChanged
imageRect = new Rect(0, 0, getWidth(), getHeight());
}
canvas.drawBitmap(bitmap, null, imageRect, mPaint);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
imageRect = new Rect(0, 0, w, h);
}

Related

Android customview get pixel

I have a custom view and I want to get pixel by a given position on ACTION_UP event.
public class MyView extends View
{
private Bitmap mBitmap;
private Canvas mCanvas;
private Paint mPaint;
public MyView(Context context)
{
super(context);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh)
{
super.onSizeChanged(w, h, oldw, oldh);
setDrawingCacheEnabled(true);
mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
mPaint = new Paint();
mPaint.setColor(Color.RED);
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setStrokeWidth(20f);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
}
#Override
protected void onDraw(Canvas canvas)
{
canvas.drawBitmap(mBitmap, 0, 0, mPaint);
}
#Override
public boolean onTouchEvent(MotionEvent event)
{
switch (event.getAction())
{
case MotionEvent.ACTION_UP:
{
float x = event.getX();
float y = event.getY();
int pixel = mBitmap.getPixel((int) x, (int) y);
Log.i("APP", "Pixel is: " + pixel);
return true;
}
}
return super.onTouchEvent(event);
}
}
I'm getting only 0 when I'm calling mBitmap.getPixel(x, y);
I've marked the ontouch events on the image with black circle
You create a bitmap, and a canvas for that bitmap. But you never draw to it. Since you never draw to it, it will be whatever the default value of a new bitmap is, which is most likely to be either random or 0.
Unless you didn't post the drawing code, in which case we'll need that too.

How do I draw a partial bitmap-arc? Like a circular progress wheel, but with a bitmap that gets more and more displayed.

What I am searching for, is a view that reveals an image in a clockwise circular fashion. When the progress is 25% the first 90 degrees should be revealed and when its 100% the full 360 degrees should be drawn.
It is very close to using the canvas.drawArc(), but this method only works with Paint objects, not bitmaps.
Other answers also only work with full colors:
How To Make Circle Custom Progress Bar in Android
I have found it to be a very hard problem, I hope someone has a solution.
tre this:
public class MyView extends View {
private Bitmap mBitmap;
private Paint mPaint;
private RectF mOval;
private float mAngle = 135;
private Paint mTextPaint;
public MyView(Context context) {
super(context);
// use your bitmap insted of R.drawable.ic_launcher
mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mOval = new RectF();
mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mTextPaint.setTextSize(48);
mTextPaint.setTextAlign(Align.CENTER);
mTextPaint.setColor(0xffffaa00);
mTextPaint.setTypeface(Typeface.DEFAULT_BOLD);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
Matrix m = new Matrix();
RectF src = new RectF(0, 0, mBitmap.getWidth(), mBitmap.getHeight());
RectF dst = new RectF(0, 0, w, h);
m.setRectToRect(src, dst, ScaleToFit.CENTER);
Shader shader = new BitmapShader(mBitmap, TileMode.CLAMP, TileMode.CLAMP);
shader.setLocalMatrix(m);
mPaint.setShader(shader);
m.mapRect(mOval, src);
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(0xff0000aa);
canvas.drawArc(mOval, -90, mAngle, true, mPaint);
canvas.drawText("click me", getWidth() / 2, getHeight() / 2, mTextPaint);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float w2 = getWidth() / 2f;
float h2 = getHeight() / 2f;
mAngle = (float) Math.toDegrees(Math.atan2(event.getY() - h2, event.getX() - w2));
mAngle += 90 + 360;
mAngle %= 360;
invalidate();
return true;
}
}

EditText with custom background using onDraw

I am trying to have a custom EditText with a custom background which is not possible to draw using drawable XMLs
Here is what I have right now
public class EMEditText extends EditText {
private Bitmap framedBitmap;
public EMEditText(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
#Override
protected void onDraw(Canvas canvas) {
if(framedBitmap == null) {
createDrawable(getWidth(), getHeight());
}
Paint paint = new Paint();
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
// canvas.drawBitmap(framedBitmap, 0, 0, paint);
}
private void createDrawable(int width, int height) {
// create a new bitmap of given size
Bitmap start = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(start);
RectF outerRect = new RectF(0, 0, width, height);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.WHITE);
// paint.setStrokeWidth(1);
// paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT));
canvas.drawRoundRect(outerRect, height / 2, height / 2, paint);
framedBitmap = start;
}
}
What is probably wrong in your code is that you are creating your own Canvas object in createDrawable() method though onDraw() method gives you the right Canvas which you should use for your drawings.
So what you probably want is to change createDrawable(int width, int height) method to createDrawable(int width, int height, Canvas c). Your code should look like this then:
#Override
protected void onDraw(Canvas canvas) {
if(framedBitmap == null) {
createDrawable(getWidth(), getHeight(), canvas);
}
Paint paint = new Paint();
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
// canvas.drawBitmap(framedBitmap, 0, 0, paint);
}
private void createDrawable(int width, int height, Canvas c) {
// create a new bitmap of given size
Bitmap start = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
c.setBitmap(start);
RectF outerRect = new RectF(0, 0, width, height);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.WHITE);
// paint.setStrokeWidth(1);
// paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT));
c.drawRoundRect(outerRect, height / 2, height / 2, paint);
framedBitmap = start;
}
As you can see, I changed also the body of your createDrawable() method so that it uses Canvas from onDraw() and sets it's Bitmap to the one created by you.

How to erase paint with finger on Image?

Can any body tell me to erase the paint on the image , in my application i was prepared the finger painting on image, if i want erase the paint it,s getting black color on image instead of erasing the image. my code is
public class MyView extends View {
int bh = originalBitmap.getHeight();
int bw = originalBitmap.getWidth();
public MyView(Context c) {
super(c);
//mBitmap = Bitmap.createScaledBitmap(originalBitmap,bw,bh,true);
mBitmap = Bitmap.createBitmap(bw,bh,Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
mBitmapPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
}
public MyView (Context c, int color) {
super(c);
mBitmap = Bitmap.createScaledBitmap(originalBitmap,bw,bh,true);
mCanvas = new Canvas(mBitmap);
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
mBitmapPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC)) ;
mCanvas.drawColor(color);
}
#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) {
canvas.drawColor(Color.TRANSPARENT);
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
canvas.drawPath(mPath, mPaint);
}
for paint erase
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
You should draw on a transparent custom view placed over the original bitmap instead of modifying the orignal. That will keep it simple.
For that you can do
<RelativeLayout ....>
<ImageView ......set original bitmap to this/>
<CustomView ...... draw on this, you can erase too./>
</RelativeLayout>
For getting the modified bitmap call the getDrawingCache() method on that RelativeLayout. That will give you the combined bitmap image.
Hope this helps.
define a temporary bitmap and canvas, then draw canvas on that temporary bitmap and pass that bitmap to onDraw your work will be done,

How can I get the canvas size of a custom view outside of the onDraw method?

I need to be able to access the size of the view's canvas to perform some calculations. For some reason, the size of the view passed to onSizeChanged is different than the size of the canvas passed to onDraw. My current workaround uses a boolean flag to determine when I need to do the calculations.
The ideal solution would allow me to do these calculations in the onSizeChanged method, so I'm wondering... is there any way I can get ahold of the Canvas object (or at least it's dimensions) outside of the onDraw method?
My code is below. It is draws the radius of a circle at a given angle. When I use canvas.centerX() to determine the start points and end points for the radius, everything works perfectly. If I use the parameters passed into onSizeChanged, it isn't even remotely close to correct.
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mSizeChanged = true;
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mSizeChanged) {
RectF bounds = new RectF(canvas.getClipBounds());
float centerX = bounds.centerX();
float centerY = bounds.centerY();
float radianAngle = (float) Math.toRadians(mStartAngle);
mRadius[0] = center;
mRadius[1] = center;
mRadius[2] = center + center * FloatMath.cos(radianAngle);
mRadius[3] = center + center * FloatMath.sin(radianAngle);
mSizeChanged = false;
}
mPaint.setColor(0xFF330000);
mPaint.setStrokeWidth(1);
canvas.drawLines(mRadius, mPaint);
}
For drawing purposes, you should not really use the dimensions of the Canvas object.
Just use the dimensions provided to you in the onSizeChanged method. You can either store the dimensions for use in the onDraw method or resize/draw to a backing bitmap that you can draw with later.
Update:
Quickly whipped up some code, it looks like this works:
public class CustomView extends View{
private Paint paint;
private int w;
private int h;
public CustomView(Context context, AttributeSet attr) {
super(context, attr);
paint = new Paint();
paint.setTextAlign(Align.CENTER);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
this.w = w;
this.h = h;
super.onSizeChanged(w, h, oldw, oldh);
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
canvas.drawText("TEST", w/2, h/2, paint);
}
}
Update 2
Following the circle code update.
We can do this:
#Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
float centerX = (float) w/2;
float centerY = (float) h/2;
float radianAngle = (float) Math.toRadians(startAngle);
radius[0] = centerX;
radius[1] = centerY;
radius[2] = centerX + centerX * FloatMath.cos(radianAngle);
radius[3] = centerY + centerY * FloatMath.sin(radianAngle);
paint.setColor(0xFF330000);
paint.setStrokeWidth(1);
canvas.drawLines(radius, paint);
}
You'll see that this now works on any sized view.

Categories

Resources