I want to draw a number on an existing drawable. Like the unread count at an email icon. The drawable is the top icon of a button. This is my code:
BitmapDrawable d = (BitmapDrawable) button.getCompoundDrawables()[1];
if(d != null) {
Bitmap src = d.getBitmap();
Bitmap b = Bitmap.createBitmap(src.getWidth(), src.getHeight(), src.getConfig());
Canvas c = new Canvas(b);
Paint p = new Paint();
p.setAntiAlias(true);
p.setStrokeWidth(1);
p.setStyle(Style.FILL_AND_STROKE);
p.setColor(Color.rgb(254, 0, 1));
c.drawBitmap(src, 0, 0, p);
c.drawCircle(b.getWidth()-5, 5, 5, p);
button.setCompoundDrawables(null, new BitmapDrawable(b), null, null);
}
The resulting drawable is emtpy. Is there something wrong with this code?
Thanks in advance.
The new bitmap has to call setBounds(...)
BitmapDrawable dn = new BitmapDrawable(b);
dn.setBounds(d.getBounds());
button.setCompoundDrawables(null, dn, null, null);
I'm not sure about your implementation but another way to go about this is to add your bitmap to a framelayout as an imageview and then add a textview (appropriately styled) with an offset; depending where you want the badge e.g. top right hand corner.
Related
I have a png image which I want to use as a frame for images in ImageView.
Sorry, it's white that's why invisible
Like this but with sides curved
What is the solution?
I've tried by converting png to patch 9, setting background of parent and source of image view, but none worked. Image doesn't fit inside.
I've done it using PorterDuff. Designed an extra image just with curved border and applied PorterDuff.Mode.SRC_OVER inside setImageResource of Custom Image View.
Here is the overriden function
#Override
public void setImageResource(int resId) {
Bitmap rawBmp = BitmapFactory.decodeResource(getContext().getResources(), resId);
Bitmap rawMask = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.image_frame_arc_filled);
Bitmap rawBorderMask = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.image_frame_arc);
Bitmap bmp = Bitmap.createScaledBitmap(rawBmp, rawBmp.getWidth(), rawBmp.getHeight(), true);
Bitmap mask = Bitmap.createScaledBitmap(rawMask, bmp.getWidth(), bmp.getHeight(), true);
Bitmap borderMask = Bitmap.createScaledBitmap(rawBorderMask, mask.getWidth(), mask.getHeight(), true);
Bitmap bitmap = Bitmap.createBitmap(mask.getWidth(), mask.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.drawBitmap(bmp, 0, 0, null);
Paint maskPaint = new Paint();
maskPaint.setXfermode(
new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
canvas.drawBitmap(mask, 0, 0, maskPaint);
maskPaint = new Paint();
maskPaint.setXfermode(
new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER));
canvas.drawBitmap(borderMask, 0, 0, maskPaint);
this.setImageBitmap(bitmap);
}
I want to rotate drawableLeft in a TextView.
I tried this code:
Drawable result = rotate(degree);
setCompoundDrawables(result, null, null, null);
private Drawable rotate(int degree)
{
Bitmap iconBitmap = ((BitmapDrawable)originalDrawable).getBitmap();
Matrix matrix = new Matrix();
matrix.postRotate(degree);
Bitmap targetBitmap = Bitmap.createBitmap(iconBitmap, 0, 0, iconBitmap.getWidth(), iconBitmap.getHeight(), matrix, true);
return new BitmapDrawable(getResources(), targetBitmap);
}
But it gives me a blank space on the left drawable's place.
Actually, even this simplest code gives blank space:
Bitmap iconBitmap = ((BitmapDrawable)originalDrawable).getBitmap();
Drawable result = new BitmapDrawable(getResources(), iconBitmap);
setCompoundDrawables(result, null, null, null);
This one works fine:
setCompoundDrawables(originalDrawable, null, null, null);
According to the docs, if you want to set drawableLeft you should call setCompoundDrawablesWithIntrinsicBounds (int left, int top, int right, int bottom). Calling setCompoundDrawables() only works if setBounds() has been called on the Drawable, which is probably why your originalDrawable works.
So change your code to:
Drawable result = rotate(degree);
setCompoundDrawablesWithIntrinsicBounds(result, null, null, null);
You can't just "cast" a Drawable to a BitmapDrawable
To convert a Drawable to a Bitmap you have to "draw" it, like this:
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
See the post here:
How to convert a Drawable to a Bitmap?
I'm converting an old application from v1 to v2, and I'm having a problem with the color of my Marker icons. I have a basic, white icon, and It needs to be colorized.
In v1, I did it this way :
Drawable d = DrawableUtils.resizeImageToDrawable(
MapViewFragment.mapviewActivity,
Configuration.Display.getDrawableFix(i),
Configuration.MapView.getWaypointIconWidth(),
Configuration.MapView.getWaypointIconHeight());
d.setColorFilter(color, Mode.MULTIPLY);
overlay = new MyFplnFixListItimizedOverlay(d);
Since v2 Markers do not accept Drawables for their icons, I thought about converting the Drawable to a Bitmap, like this :
Drawable d = DrawableUtils.resizeImageToDrawable(
MapViewFragment.mapviewActivity,
Configuration.Display.getDrawableFix(i),
Configuration.MapView.getWaypointIconWidth(),
Configuration.MapView.getWaypointIconHeight());
d.setColorFilter(color, Mode.MULTIPLY);
Bitmap icon = ((BitmapDrawable) d).getBitmap();
Marker marker = MapViewFragment.map.addMarker(new MarkerOptions()
.position(point)
.title(Integer.toString(fplnType))
.visible(true)
.icon(BitmapDescriptorFactory.fromBitmap(icon)));
But for some reason, it's not working. The icons stay white. Anyone knows why ?
Thanks in advance.
OK, here's how I did it at the end of the day :
Drawable d = DrawableUtils.resizeImageToDrawable(
MapViewFragment.mapViewActivity,
Configuration.Display.getDrawableFix(i),
Configuration.MapView.getWaypointIconWidth(),
Configuration.MapView.getWaypointIconHeight());
d.setColorFilter(color, Mode.MULTIPLY);
Bitmap b = ((BitmapDrawable) d).getBitmap();
Canvas myCanvas = new Canvas(b);
int myColor = b.getPixel(0,0);
ColorFilter filter = new LightingColorFilter(myColor, color);
Paint pnt = new Paint();
pnt.setColorFilter(filter);
myCanvas.drawBitmap(b,0,0,pnt);
Marker marker = MapViewFragment.map.addMarker(new MarkerOptions()
.position(point)
.title(Integer.toString(fplnType))
.visible(true)
.icon(BitmapDescriptorFactory.fromBitmap(b)));
If your drawable is not defined in a XML, you can do it with this method:
protected Bitmap fromDrawable(final Drawable drawable, final int height, final int width) {
final int widthDip = (int) TypedValue.applyDimension(1, width, getResources()
.getDisplayMetrics());
final int heightDip = (int) TypedValue.applyDimension(1, width, getResources().getDisplayMetrics());
final Bitmap bitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
final Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
Note that if you need to do it from OUTSIDE an Activity, you'll also need to pass a Context (in order to call context.getResources().getDisplayMetrics()). You also pass the DisplayMetrics object instead.
I'm not sure what this DrawableUtils is doing, but you're casting it to a BitmapDrawable. Is it really a BitmapDrawable?
here's some code to extract a Bitmap out of any type of drawable:
Drawable d = // make sure it's not null
d.setBounds(0, 0, width, height);
Bitmap b = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
d.draw(c);
the idea is that you create a canvas on a mutable bitmap and draw that drawable on the canvas
edit:
I've just seen the #Analizer answer and yeah, my answer is good if you don't have the Drawable as a resource. But if you do, user his answer instead.
I can't manage the following and I hope someone have a hint for me?
I have 2 areas (filled paths) one upon the other. The lower one is filled completely in blue. The upper one I would like the fill in red partly with a specific pattern ( for example with lines ). So at the end I have a filled area with blue and red striped.
In my tries the upper one overlaps the lower one, so blue is not seen.
I tried to do this with bitmapshader but do not succeed.
BitmapShader mShader1 = new BitmapShader(makeBitmap1(),
Shader.TileMode.REPEAT,
Shader.TileMode.REPEAT);
paint.setShader(mShader1);
canvas.drawPath(cpath.path, paint);
private static Bitmap makeBitmap1() {
//Bitmap bm = Bitmap.createBitmap(10, 10, Bitmap.Config.RGB_565);
//Bitmap bm = Bitmap.createBitmap(10, 10, Bitmap.Config.ALPHA_8);
Bitmap bm = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_4444);
//Bitmap bm = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bm);
c.drawColor(Color.RED);
Paint p = new Paint();
p.setColor(0xFF000000);
//p.setColor(Color.BLUE);
c.drawRect(2, 2, 8, 8, p);
return bm;
}
i have two Bitmap[] (for example "BitM1" and BitM2)
Need to cut BitM1[0] from BitM2[0], BitM1[1] from BitM2[1] (using Xfermode mode.xor)... etc
Bitmap[] vk = new Bitmap[25];
int k=0;
for (v=0;v<25;v++)
{
Bitmap bitmap2 = BitM1[v];
Bitmap bitmap1 = BitM2[v];
vk[k]=Bitmap.createBitmap(bitmap2.getWidth(), bitmap2.getHeight(), bitmap2.getConfig());
Canvas canvas = new Canvas(vk[k]);
Paint paint = new Paint();
paint.setFilterBitmap(false);
canvas.drawBitmap(bitmap2, 0, 0, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.XOR));
canvas.drawBitmap(bitmap1, 0, 0, paint);
bitmap2.recycle();
bitmap1.recycle();
}
imgv3.setImageBitmap(vk[5]);
not work... Crashed...
You are never changing the value of K in the code above, so you are always placing the new Bitmap at location vk[0]. Thus when you attempt to get vk[5], it is not defined. BOOM...Crash!