BAD quality when drawing a bitmap on a Canvas - android

I am trying to draw a avatar bitmap using this code. But the bitmap is pixelated. Here is my Code. Currently I use createScaledBitmap to resize the avatar image. Also the Text are a little smaller on some devices with a high resolution
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inMutable = true;
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.card_nodpi, opt) ;
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
paint.setColor(Color.BLACK);
paint.setTextSize(40);
paint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD));
canvas.drawText("The quick brown fox", x, y, paint);
Paint paint2 = new Paint();
paint2.setColor(Color.BLACK);
paint2.setTextSize(30);
canvas.drawText("The quick brown fox", x, y + (40), paint2);
canvas.drawText("The quick brown fox", x, y + ((40 * 2)), paint2);
if (avatar != null) {
Bitmap img = Bitmap.createScaledBitmap(avatar, 250, 250, false);
canvas.drawBitmap(img, bitmap.getWidth() - img.getWidth() - x, y - 40, new Paint(Paint.FILTER_BITMAP_FLAG));
}
imageView.setImageBitmap(bitmap);

createScaledBitmap can produce some funky/bad quality images.
Try out this solution here:
https://stackoverflow.com/a/7468636/4557530
Let me know if that does anything for you!
Alternatively,
try this, I used this code before thanks to some blog, which I don't remember anymore
Bitmap newBM = Bitmap.createBitmap(newWidth, newHeight, Config.ARGB_8888);
float scaleX = newWidth / (float) origBM.getWidth();
float scaleY = newHeight / (float) origBM.getHeight();
float pivX = 0;
float pivY = 0;
Matrix scaleMatrix = new Matrix();
scaleMatrix.setScale(scaleX, scaleY, pivotX, pivotY);
Canvas canvas = new Canvas(newBM);
canvas.setMatrix(scaleMatrix);
canvas.drawBitmap(origBM, 0, 0, new Paint(Paint.FILTER_BITMAP_FLAG));

Related

canvas text looks blurry on images in android

When drawing the text though, it gets blurred and not that crisp like when using below code. The only code I've used for the text painting on image can some one help me to solve this issue
code
public static Bitmap drawMultilineTextToBitmap(Context gContext, Bitmap bitmap, String gText) {
// prepare canvas
Resources resources = gContext.getResources();
float scale = resources.getDisplayMetrics().density;
//Bitmap bitmap = BitmapFactory.decodeResource(resources, gResId);
android.graphics.Bitmap.Config bitmapConfig = bitmap.getConfig();
// set default bitmap config if none
if (bitmapConfig == null) {
bitmapConfig = android.graphics.Bitmap.Config.ARGB_8888;
}
// so we need to convert it to mutable one
bitmap = bitmap.copy(bitmapConfig, true);
Canvas canvas = new Canvas(bitmap);
TextPaint paint = new TextPaint(Paint.LINEAR_TEXT_FLAG|Paint.ANTI_ALIAS_FLAG);
paint.setStyle(Paint.Style.FILL);
paint.setAntiAlias(true);
paint.setColor(Color.rgb(0, 0, 0));
paint.setFakeBoldText(true);
paint.setTextSize(10);
int textWidth = canvas.getWidth() - (int) (16 * scale);
// init StaticLayout for text
StaticLayout textLayout = new StaticLayout(gText, paint,
canvas.getWidth(), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f,
false);
// get height of multiline text
int textHeight = textLayout.getHeight();
// get position of text's top left corner
float x = (bitmap.getWidth() - textWidth);
float y = (bitmap.getHeight() - textHeight);
// draw text to the Canvas Left
canvas.save();
//canvas.translate(x, y);
canvas.translate((canvas.getWidth() / 2) - (textLayout.getWidth() / 2), y);
textLayout.draw(canvas);
canvas.restore();
return bitmap;
}
image
I guess here:
paint.setAntiAlias(true);
should be false. And two more methods which may relate to this issue:
paint.setAntiAlias(false);
paint.setFilterBitmap(false);
paint.setDither(true);

Make a hole by canvas.drawcircle on image that uses matrix

Hi everyone, I am new to android dev.
I have an app that will erase part of the bitmap. I am using matrix to scale rotate the image. Without scaling, the transparent eraser is same size with the circle, but when i scale the bitmap the eraser transparent is bigger than the circle size which is fixed. Can someone help me out?.. I am struggling this for 1 week now.
Here's the code I am using:
RectF r = new RectF();
matrix.mapRect(r);
// sol1
float scaledX = (lastX - r.left) + 48; // adjust to the tip of eraser
float scaledY = (lastY - r.top) - 137; // adjust to the tip of eraser
float[] values = new float[9];
matrix.getValues(values);
float scalex = values[Matrix.MSCALE_X];
float skewy = values[Matrix.MSKEW_Y];
float scale = (float) Math.sqrt(scalex * scalex + skewy * skewy);
scaledX /= scale;
scaledY /= scale;
Bitmap bmOverlay = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(),
Bitmap.Config.ARGB_8888);
System.out.println("bitmap.getWidth() " + bitmap.getWidth() +
" bitmap.getHeight() " + bitmap.getHeight());
Canvas c = new Canvas(bmOverlay);
c.drawColor(Color.TRANSPARENT, Mode.CLEAR);
c.drawBitmap(bitmap, 0, 0, null);
c.drawCircle(scaledX, scaledY, 13.0f, mPaint); // punch a hole
bitmap = bmOverlay; // update the main bitmap
Finally I am able to achieved:
I just comment the below lines :).
// cursor
paintCursorRed.setColor(0xffff0000);
paintCursorRed.setStyle(Style.STROKE);
paintCursorBlackdraw.setColor(0xffffff00);
paintCursorBlackdraw.setStyle(Style.STROKE);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mPaint.setStrokeJoin(Paint.Join.BEVEL);
mPaint.setStrokeCap(Paint.Cap.SQUARE);
//mPaint.setStrokeWidth(15);
//mPaint.setTextSize(15);
mPaint.setAlpha(0);
mPaint.setXfermode(new PorterDuffXfermode(Mode.CLEAR));
mPaint.setAntiAlias(true);
// mPaint.setMaskFilter(new BlurMaskFilter(5, Blur.NORMAL));

Rotate text when drawing it on a bitmap

I want to rotate my text by 180 degrees when drawing it on a bitmap. The bitmap itself could also be rotated as there is nothing else drawn on it other than the text. It isn't clear to me though what I should be using in the code below to rotate the text: ImageView, canvas, paint, bitmap???
ImageView ivImage = (ImageView)findViewById(R.id.ivImage);
DisplayMetrics metrics = getResources().getDisplayMetrics();
int width = metrics.widthPixels;
int height = metrics.heightPixels;
Bitmap.Config conf = Bitmap.Config.ARGB_8888;
Bitmap bitmap = Bitmap.createBitmap(width, height, conf);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.RED);
paint.setTextSize((int) (200 * 1));
// draw text to the Canvas center
Rect bounds = new Rect();
paint.setTextAlign(Align.CENTER);
String text = "HELP";
paint.getTextBounds(text, 0, text.length(), bounds);
int x = bitmap.getWidth() / 2; // (bitmap.getWidth() - bounds.width())/2;
int y = bitmap.getHeight() / 2; // (bitmap.getHeight() + bounds.height())/2;
canvas.drawText(text, x * 1, y * 1, paint);
ivImage.setImageBitmap(bitmap);
I hope this could help. This is how i did when creating a clock
// Save canvas in current state
canvas.save();
// Rotate canvas around center and draw
canvas.rotate(degrees, canvasWidth/2, canvasHeigth/2);
canvas.drawText(text, x, y, paint)
// Restore canvas, rotates it back to original
canvas.restore();

I can't draw text in front of bitmap for market in Google map API V2?

Hi, genious!
What's the problem?
I tried to draw text in front of marker. I'm going to get clear bitmap and draw text but bitmap is still clear - where is the text?
I tried to convert View to bitmap but it's also wasn't good idea.
PS: scale >= 1
mMap.addMarker(new MarkerOptions()
.position(new LatLng(56.83789, 60.5986)) .icon(BitmapDescriptorFactory.fromBitmap(drawTextToBitmap(getApplicationContext(), R.drawable.ic_maps_marker,"19"))));
//here I'm trying to draw text bitmap
public static Bitmap drawTextToBitmap(Context gContext,int gResId,String gText) {
Resources resources = gContext.getResources();
float scale = resources.getDisplayMetrics().density;
Bitmap bitmap =
BitmapFactory.decodeResource(resources, gResId);
android.graphics.Bitmap.Config bitmapConfig =
bitmap.getConfig();
if(bitmapConfig == null) {
bitmapConfig = android.graphics.Bitmap.Config.ARGB_8888;
}
bitmap = bitmap.copy(bitmapConfig, true);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.BLACK);
paint.setTextSize((int) (14 * scale));
paint.setShadowLayer(1f, 0f, 1f, Color.WHITE);
Rect bounds = new Rect();
paint.getTextBounds(gText, 0, gText.length(), bounds);
int x = (bitmap.getWidth() - bounds.width())/2;
int y = (bitmap.getHeight() + bounds.height())/2;
canvas.drawText(gText, x * scale, y * scale, paint);
return bitmap;
}
Density was only necessary to determinate the size of the text. To draw text on canvas should not use scale, because of displacements x and y calculated for particular bitmap.
Try this:
canvas.drawText(gText, x, y, paint);
This work on 4 devices:

Rotating Image on A canvas in android

I want to Rotate Image according to a specific angle in android ,some thing like a compass...
I have this code...it works on drawPath()
but i want to replace the path and the Drawing thing with image..
I tried to create a bitmap image ,DrawBitmapImage , but the image does not Rotate like the path..Any Help PLease?
public void draw(Canvas canvas) {
double angle = calculateAngle(currentLongitude, currentLatitude, targetLongitude, targetLatitude);
//Correction;
angle-=90;
//Correction for azimuth
angle-=azimuth;
if((getContext() instanceof Activity) && ((Activity)getContext()).getWindowManager().getDefaultDisplay().getOrientation()==Configuration.ORIENTATION_PORTRAIT)angle-=90;
while(angle<0)angle=angle+360;
Rect rect = canvas.getClipBounds();
int height = rect.bottom-rect.top;
int width = rect.right-rect.left;
int left = rect.left;
int top = rect.top;
if(height>width){
top+=(height-width)/2;
height=width;
}
if(width>height){
left+=(width-height)/2;
width=height;
}
float centerwidth = width/2f;
float centerheight = height/2f;
Paint p = new Paint();
p.setColor(color);
p.setStyle(Paint.Style.FILL);
p.setAntiAlias(true);
float startX = left+(float)(centerwidth+Math.cos(deg2rad(angle))*width/3.0);
float startY = top+(float)(centerheight+Math.sin(deg2rad(angle))*height/3.0);
Path path = new Path();
path.moveTo(
startX,
startY);
path.lineTo(
left+(float)(centerwidth+Math.cos(deg2rad(angle+140))*width/4.0),
top+(float)(centerheight+Math.sin(deg2rad(angle+140))*height/4.0));
path.lineTo(
left+(float)centerwidth,
top+(float)centerheight
);
path.lineTo(
left+(float)(centerwidth+Math.cos(deg2rad(angle+220))*width/4.0),
top+(float)(centerheight+Math.sin(deg2rad(angle+220))*height/4.0)
);
path.lineTo(
startX,
startY
);
canvas.drawPath(path, p);
}
You can either rotate your bitmap when you draw it by using a matrix:
Matrix matrix = new Matrix();
matrix.setRotate(angle, imageCenterX, imageCenterY);
yourCanvas.drawBitmap(yourBitmap, matrix, null);
You can also do it by rotating the canvas before drawing:
yourCanvas.save(Canvas.MATRIX_SAVE_FLAG); //Saving the canvas and later restoring it so only this image will be rotated.
yourCanvas.rotate(-angle);
yourCanvas.drawBitmap(yourBitmap, left, top, null);
yourCanvas.restore();
Pick the one that suits you the best.
You have to rotate the canvas first and then draw whatever you want. Then the object drawn will be appeared as rotated on screen.
canvas.rotate(45); // degrees to rotate
try this its good way.
Check this tutorial you will get information about how to draw bitmap and how to rotate canvas
Check complete tutorial
This is the only one that worked for me with no problem.
private Bitmap rotateBitmap(Bitmap bitmap, int rotationAngleDegree){
int w = bitmap.getWidth();
int h = bitmap.getHeight();
int
newW=w, newH=h;
if (rotationAngleDegree==90 || rotationAngleDegree==270){
newW = h;
newH = w;
}
Bitmap rotatedBitmap = Bitmap.createBitmap(newW,newH, bitmap.getConfig());
Canvas canvas = new Canvas(rotatedBitmap);
Rect rect = new Rect(0,0,newW, newH);
Matrix matrix = new Matrix();
float px = rect.exactCenterX();
float py = rect.exactCenterY();
matrix.postTranslate(-bitmap.getWidth()/2, -bitmap.getHeight()/2);
matrix.postRotate(rotationAngleDegree);
matrix.postTranslate(px, py);
canvas.drawBitmap(bitmap, matrix, new Paint( Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG | Paint.FILTER_BITMAP_FLAG ));
matrix.reset();
return rotatedBitmap;
}
Based on #Sakthi 's code, but add scaling :)
Rect rect = new Rect(0,0,canvas.getWidth(), canvas.getHeight());
Matrix matrix = new Matrix();
matrix.postTranslate(-bitmap.getWidth()/2, -bitmap.getHeight()/2);
matrix.postScale(
((float)rect.width()) / bitmap.getWidth(),
((float)rect.height()) / bitmap.getHeight());
matrix.postRotate(180);
matrix.postTranslate(rect.exactCenterX(), rect.exactCenterY());
canvas.drawBitmap(bitmap, matrix, null);
#Reham: Look at this example code below,
public class bitmaptest extends Activity {
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
LinearLayout linLayout = new LinearLayout(this);
// load the origial BitMap (500 x 500 px)
Bitmap bitmapOrg = BitmapFactory.decodeResource(getResources(),
R.drawable.android);
int width = bitmapOrg.width();
int height = bitmapOrg.height();
int newWidth = 200;
int newHeight = 200;
// calculate the scale - in this case = 0.4f
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// createa matrix for the manipulation
Matrix matrix = new Matrix();
// resize the bit map
matrix.postScale(scaleWidth, scaleHeight);
// rotate the Bitmap
matrix.postRotate(45);
// recreate the new Bitmap
Bitmap resizedBitmap = Bitmap.createBitmap(bitmapOrg, 0, 0,
width, height, matrix, true);
// make a Drawable from Bitmap to allow to set the BitMap
// to the ImageView, ImageButton or what ever
BitmapDrawable bmd = new BitmapDrawable(resizedBitmap);
ImageView imageView = new ImageView(this);
// set the Drawable on the ImageView
imageView.setImageDrawable(bmd);
// center the Image
imageView.setScaleType(ScaleType.CENTER);
// add ImageView to the Layout
linLayout.addView(imageView,
new LinearLayout.LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT
)
);
// set LinearLayout as ContentView
setContentView(linLayout);
}
}
you have to use the matrix to rotate image look the lines
matrix.postRotate(45); -
this will rotate the image to 45 degrees
Hope this help you ...thx
Use following code. it worked for me
float rotation = 30.0f;
Bitmap bitmap = your bitmap
Rect rect = new Rect(100,100,bitmap.width, bitmap.height);
Matrix matrix = new Matrix();
float px = rect.exactCenterX();
float py = rect.exactCenterY();
matrix.postTranslate(-bitmap.getWidth()/2, -bitmap.getHeight()/2);
matrix.postRotate(rotation);
matrix.postTranslate(px, py);
canvas.drawBitmap(bitmap, matrix, null);
matrix.reset();
invalidate();

Categories

Resources