I want to place a bitmap on top of another bitmap, I have done that with the method below. The bitmap is the current bitmap that will have another bitmap placed on top. Marker bitmap is the bitmap that is to be placed on top of the current bitmap. x and y are the locations of the tap, these are correct to my knowledge because the on tap listener does recognize the location but displays the bitmap in the wrong location.
public Bitmap drawOnToCanvas(Bitmap bitmap){
float centerX = (x - (markerBitmap.getWidth()/2));
float centerY = (y + (markerBitmap.getHeight()/2));
Canvas canvas = new Canvas(bitmap);
canvas.drawBitmap(bitmap, new Matrix(), null);
canvas.drawBitmap(markerBitmap, centerX , centerY, null);
return bitmap;
}
I found the problem when you draw the bitmap for the current bitmap make sure you get the matrix and not just make a new matrix. Example fix is below:
public Bitmap drawOnToCanvas(Bitmap bitmap, Matrix currentMatrix){
float centerX = (x - (markerBitmap.getWidth()/2));
float centerY = (y + (markerBitmap.getHeight()/2));
Canvas canvas = new Canvas(bitmap);
canvas.drawBitmap(bitmap, currentMatrix, null);
canvas.drawBitmap(markerBitmap, centerX , centerY, null);
return bitmap;
}
Related
I have a picture of a tennis racket in my fragment like this.
I will receive X / Y coordinates from the main part of the racket lets say I will get x/y from this image:
I have no idea how can I DRAW (red dots) on the other image with the full racket after i receive the x/y coordinates.
I used the following method to overlay an image at specified x,y cords:
private Bitmap overlay(Bitmap sourceMap,Bitmap locationDrawable,int x, int y) {
Bitmap bmOverlay = Bitmap.createBitmap(sourceMap.getWidth(), sourceMap.getHeight(), sourceMap.getConfig());
Bitmap bmp2small =Bitmap.createScaledBitmap(locationDrawable, (int) Math.round(locationDrawable.getWidth() * .25), (int) Math.round(locationDrawable.getHeight() * .25), true);
int bmp2width = bmp2small.getWidth();
int bmp2height = bmp2small.getHeight();
Canvas canvas = new Canvas(bmOverlay);
canvas.drawBitmap(sourceMap, new Matrix(), null);
canvas.drawBitmap(bmp2small, (float) x - (bmp2width / 2), (float) y - bmp2height, null);
bmp2small.recycle();
return bmOverlay;
}
Does anyone know how to make the radius of the circle be fixed although other stuff in the same canvas be scaled. I don't really know how to get the scale factor of the circle dynamically. Thanks
Canvas c = new Canvas(image);
c.drawColor(Color.TRANSPARENT, Mode.CLEAR);
c.drawBitmap(bm, 0, 0, null);
c.drawCircle(cx, cy, radius, mPaint);
Canvas c = new Canvas(image); // This image has a matrix that every time I scaled on the image the cursor will also change. I want the cursor size to stay as 13.0f.
Code:
public void draw(Canvas canvas, Paint paint) { //This is access from the main onDraw();
paint.setColorFilter(colorFilter);
// scaled bitmap base on the scaling of the bitmap
canvas.drawBitmap(bitmap, matrix, paint);
if(activateCursor == true){
if(isTouched == true && ActivityMainEditor.IS_ERASING == true){
RectF r = new RectF();
matrix.mapRect(r);
// sol1
float scaledX = (lastX - r.left) + 48;
float scaledY = (lastY - r.top) - 137;
float[] values = new float[9];
matrix.getValues(values);
// mScalingFactor shall contain the scale/zoom factor
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;
// cursor adjustment
I have used this lines to make the circle radius will always be the same although scaling the bitmap, but it's not accurate when not scaled yet is okay but when scaled bigger the cursor will got bigger also.
float scaleCursor = (float) Math.sqrt((scalex - 5) * (scalex - 5) + (skewy - 2) * (skewy - 2));
float cursorSize = (13.0f / scaleCursor); // 13.0f fixed circle radius
drawACircle(canvas, bitmap, scaledX, scaledY, cursorSize);
}
}
}
private Bitmap drawACircle(Canvas c, Bitmap bm, float cx, float cy, float radius)
{
Bitmap bmOverlay = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(), Bitmap.Config.ARGB_8888);
Canvas cd = new Canvas(bmOverlay);
cd.drawColor(Color.TRANSPARENT, Mode.CLEAR);
cd.drawBitmap(bm, 0, 0, null);
// the line in which the circle will also get scaled :(
cd.drawCircle(cx, cy, radius, mPaint);
// update the main bitmap
bitmap = bmOverlay;
if(saveNow == true){
imageHistory.add(bitmap);
saveNow = false;
}
return bmOverlay;
}
It's simple:
c.scale(x,y); // scales the whole canvas (preconcat the matrix with the scale factor)
c.save(); // saves this matrix
// Do all your drawing here except the `drawCircle`.
c.restore(); // restores the original matrix
c.drawCircle(cx, cy, radius, mPaint);
Once you call restore(), the matrix is returned to the original one. You can now draw the circle in the normal fashion.
UPDATE:
Make x and y as fields in the CustomView, that way you can modify them outside the onDraw method. So in the onTouch or onTouchEvent, you can modify the x and y and call invalidate(). This will call onDraw and here it will scale. This will get you what you are looking for. In case of global scaling, always go with the canvas.scale() rather than scaling individual draw elements. This will keep things simple.
I am new to android,
I want to rotate a canvas bitmap without cut.
I used the below code, but when I rotate the image it cuts off a portion from the bitmap.
float px = iv_photo.getWidth()/2;
float py = iv_photo.getHeight()/2;
matrix.postTranslate(-canvas.getWidth()/2, -canvas.getHeight()/2);
matrix.postRotate(90);
matrix.postTranslate(px, py);
canvas.drawBitmap(bitmap, matrix, paint);
please help me to draw a text with rounded rectangle as background. I have to draw many texts on a canvas and the text has rounded background. SO what I am trying is to write a function "createTextBitmap" which return a bitmap image so that we can draw image(which return by the function) on a main canvas.
the 'createTextBitmap'function can return a created bitmap, the bitmap image is the one,which contains the text with rounded edge background...
i have tried one, which gives below.
private Bitmap ProcessingBitmap(String text,Paint paint, boolean lastPoint){
Bitmap bm1 = null;
Bitmap newBitmap = null;
Rect bounds = new Rect();
paint.getTextBounds(text, 0, text.length(), bounds);
float width = bounds.width();
float height =bounds.height();
float radius;
if (width > height){
radius = height/4;
}else{
radius = width/4;
}
Paint paint1 = new Paint();
paint1.setColor(Color.GREEN);
paint1.setStrokeWidth(5);
paint1.setStyle(Paint.Style.FILL);
float center_x, center_y;
center_x = width/4;
center_y = height/4;
final RectF rect = new RectF();
rect.set(center_x - radius,
center_y - radius,
center_x + radius,
center_y + radius);
Canvas canvas2 = new Canvas();
canvas2.drawRoundRect(rect, 0, 0, paint);
canvas2.drawText(text, 0, 0, paint);
return newBitmap;
}
and my question is How can we convert this canvas2 to a bitmap image? and image has the size of text bounds,
which look like
to convert your canvas into bitmap please do the following :
public Bitmap convertCanvasToBitmap(int width , int height) {
Bitmap drawnBitmap = null;
try {
drawnBitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
Canvas canvas = new Canvas(drawnBitmap);
// now draw anything you want to the canvas
} catch (Exception e) {
e.printStackTrace();
}
return drawnBitmap;
}
so the idea is just pass the bitmap to the canvas , draw with the canvas it will be drawn into your bitmap .
and please refer to this answer here to see how to deal with the text size in the bitmap .
and please give me some feedback
Hope that helps .
you can create a bitmap, then call draw on that bitmap, something like this:
newBitmap = Bitmap.createBitmap(rect.width, rect.height, Bitmap.Config.ARGB_8888);
Canvas canvas2 = new Canvas(newBitmap);
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: