I have a imported an SVG into my project as Vector Drawable.
I have my custom view
I know how to display a vector drawable using an ImageView by code (http://www.androidhive.info/2017/02/android-working-svg-vector-drawables/)
, which is described in several articles, but:
How can I draw my vectors using my custom view and by code with canvas ?
Is this possible to do. And if so, can someone give me a hint.
To do this you need to convert the vector to a bitmap as follows:
private fun getVectorBitmap(context: Context, drawableId: Int): Bitmap? {
var bitmap: Bitmap? = null
when (val drawable = ContextCompat.getDrawable(context, drawableId)) {
is BitmapDrawable -> {
bitmap = drawable.bitmap
}
is VectorDrawable -> {
bitmap = Bitmap.createBitmap(
drawable.intrinsicWidth,
drawable.intrinsicHeight, Bitmap.Config.ARGB_8888
)
val canvas = Canvas(bitmap)
drawable.setBounds(0, 0, canvas.width, canvas.height)
drawable.draw(canvas)
}
}
return bitmap
}
Then you can use the vector as a bitmap normally with your canvas:
canvas?.drawBitmap(getVectorBitmap(context, R.drawable.ic_icon), 500f, 500f, canvasPaint)
I'm going to turn #pskink's comment into an answer as I'm not so advanced in android as to quickly realize what he meant. I had to read #Krishna's answer to understand. So credits to both of them.
Here it goes:
A vector drawable inherits Drawable that can be drawn directly into a canvas. First, get the drawable from the resources using an android context:
val drawable = yourContext.getDrawable(drawableId)
Then simply draw into the canvas with it. The next line tells the drawable to draw on the top left corner, with a size of 32x32 pixels:
drawable.setBounds(0, 0, 32, 32)
Finally draw it into the canvas:
drawable.draw(canvas)
Related
I have a imported an SVG into my project as Vector Drawable.
I have my custom view
I know how to display a vector drawable using an ImageView by code (http://www.androidhive.info/2017/02/android-working-svg-vector-drawables/)
, which is described in several articles, but:
How can I draw my vectors using my custom view and by code with canvas ?
Is this possible to do. And if so, can someone give me a hint.
To do this you need to convert the vector to a bitmap as follows:
private fun getVectorBitmap(context: Context, drawableId: Int): Bitmap? {
var bitmap: Bitmap? = null
when (val drawable = ContextCompat.getDrawable(context, drawableId)) {
is BitmapDrawable -> {
bitmap = drawable.bitmap
}
is VectorDrawable -> {
bitmap = Bitmap.createBitmap(
drawable.intrinsicWidth,
drawable.intrinsicHeight, Bitmap.Config.ARGB_8888
)
val canvas = Canvas(bitmap)
drawable.setBounds(0, 0, canvas.width, canvas.height)
drawable.draw(canvas)
}
}
return bitmap
}
Then you can use the vector as a bitmap normally with your canvas:
canvas?.drawBitmap(getVectorBitmap(context, R.drawable.ic_icon), 500f, 500f, canvasPaint)
I'm going to turn #pskink's comment into an answer as I'm not so advanced in android as to quickly realize what he meant. I had to read #Krishna's answer to understand. So credits to both of them.
Here it goes:
A vector drawable inherits Drawable that can be drawn directly into a canvas. First, get the drawable from the resources using an android context:
val drawable = yourContext.getDrawable(drawableId)
Then simply draw into the canvas with it. The next line tells the drawable to draw on the top left corner, with a size of 32x32 pixels:
drawable.setBounds(0, 0, 32, 32)
Finally draw it into the canvas:
drawable.draw(canvas)
I am reading this blog post about VectorDrawable. It is mentioned that one of the trade-offs of using vector images is that it is more expensive to render. The blog also states:
For static vectors, the drawing stage only needs to be performed once and can then be cached to a Bitmap.
But the blog did not explain how to do the caching. How to do it?
Here are some ways to do it:
public static Bitmap getBitmapFromVectorDrawable(Context context, int drawableId) {
Drawable drawable = ContextCompat.getDrawable(context, drawableId);
// depending on the support lib version you may have to use
// Drawable drawable = AppCompatResources.getDrawable(context, drawableId);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
drawable = (DrawableCompat.wrap(drawable)).mutate();
}
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
With Android KTX
val bitmap = AppCompatResources.getDrawable(context, drawableId).toBitmap()
Hope it helps
How can i convert a state list Drawable to bitmap drawable in android.
I want to convert a statelist drawable into bitmap drawable.
I found a work around if i find any icon whose type is other then bitmap drawable then use this code
here searchResult.getIcon() is my icon value
Bitmap bitmap = Bitmap.createBitmap(searchResult.getIcon().getIntrinsicWidth(),searchResult.getIcon().getIntrinsicHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
searchResult.getIcon().setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
searchResult.getIcon().draw(canvas);
itemIconBitmap = bitmap;
e.printStackTrace();
You can use toBitmap or casting the current drawable
(stateListDrawable as? StateListDrawable)?.let { drawable ->
(drawable.current as BitmapDrawable).bitmap
}
How I can insert text inside Osmdroid marker? Suppose i need place several markers on map, and each marker should have number inside it. How I can make it? I try #setTitle() method, but it place text in balloon.
Update:
for(int i = 0; i < orders.size(); i++) {
mOrderPoint = orders.get(i).getStart();
final Order order = orders.get(i);
Marker orderMarker = new Marker(mMap);
orderMarker.setIcon(ContextCompat.getDrawable(mContext,R.drawable.order_pin));
orderMarker.setPosition(mOrderPoint);
}
This method takes a drawable from your resources, draws some text on top of it and returns the new drawable. All you need to do is give it the resource id of your bubble, and the text you want on top. Then you can pass the returned drawable wherever you want it.
public BitmapDrawable writeOnDrawable(int drawableId, String text){
Bitmap bm = BitmapFactory.decodeResource(getResources(), drawableId).copy(Bitmap.Config.ARGB_8888, true);
Paint paint = new Paint();
paint.setStyle(Style.FILL);
paint.setColor(Color.BLACK);
paint.setTextSize(20);
Canvas canvas = new Canvas(bm);
canvas.drawText(text, 0, bm.getHeight()/2, paint);
return new BitmapDrawable(bm);
}
Note:
To preserve density you need this constructor
BitmapDrawable (Resources res, Bitmap bitmap)
So, keeping your context, last return should be something like
return new BitmapDrawable(context.getResources(), bm);
This prevent an undesired resized drawable.
You want to look at osmdroid bonus pack.
Website: https://github.com/MKergall/osmbonuspack
There are many examples of stylized bubbles with text in it.
The answer by Blue_Alien does not work with vector drawables in Kotlin. The reason is due to BitmapFactory: it returns an error.
If you are programming in kotlin, there is a significantly simpler solution than using BitmapFactory.
Firstly, get the drawable:
val drawable = ContextCompat.getDrawable(context, R.drawable.order_pin)!!
Then simply use the toBitmap() function:
val bitmap = drawable.toBitmap()
And then the rest of the solution is effectively the same.
Final code:
val drawable = ContextCompat.getDrawable(context, R.drawable.order_pin)!!
val bitmap = drawable.toBitmap()
val paint = Paint();
paint.style = Style.FILL
paint.color = Color.BLACK
paint.textSize = 20
val canvas = Canvas(bitmap)
// Note, this code places the text in the center of the Bitmap (both vertically and horizontally)
// https://stackoverflow.com/a/11121873
canvas.drawText(text, bm.width / 2f,
bm.height / 2f - (paint.descent() + paint.ascent() / 2), paint)
val iconWithText = BitmapDrawable(context.resources, bitmap)
// Marker has to be initialised somewhere in your code
marker.icon = iconWithText
Of course, this code if for one time use. If you want to move it to a function, the parameter could either be the drawable or drawableID, and it would return the icon:
return BitmapDrawable(context.resources, bitmap)
I have 1 circular imageview and I want to place bitmap inside the imageview.
but when I set the compressed bitmap image it is always rectangle.
Please help me to set bitmap in circular imageview.
Thanks
I am curious about how you created a circular ImageView. Can you share that secret ??
As far as creating a circular Bitmap is concerned, create a BitmapShader from the bitmap you want to show. Then create a ShapeDrawable (Oval) and assign the bitmap shader to it. Draw the drawable. Bam! circular image!
Bitmap bitmap = getthebitmapyouwanttoshowinacirclefromsomewhere;
Bitmap circleBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
BitmapShader shader = new BitmapShader (bitmap, TileMode.CLAMP, TileMode.CLAMP);
Paint paint = new Paint();
paint.setShader(shader);
paint.setAntiAlias(true);
Canvas c = new Canvas(circleBitmap);
c.drawCircle(bitmap.getWidth()/2, bitmap.getHeight()/2, bitmap.getWidth()/2, paint);
myImageView.setImageBitmap(circleBitmap);
Androidx released native support for this.
add to your build.gradle:
dependencies {
...
implementation "androidx.core:core-ktx:1.7.0"
}
usage (kotlin is shown here, java is also supported):
import androidx.core.graphics.drawable.RoundedBitmapDrawable;
import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory;
val bitmap: Bitmap = ... // get from somewhere
val roundedBitmapWrapper: RoundedBitmapDrawable =
RoundedBitmapDrawableFactory.create(Resources.getSystem(), bitmap)
roundedBitmapWrapper.setCircular(true) // important! if you don't call this, the wrapper will just show the original rectangle bitmap
// and then you can display the roundedBitmap on an ImageView like this:
val imageView: ImageView = ... // get from somewhere
imageView.setImageDrawable(roundedBitmapWrapper)
P.S., the class RoundedBitmapDrawable has a lot of other cool stuff, for example if you don't want the bitmap to be completely circle, but instead just give some rounded-corners effect for the original rectangle bitmap, this can also be supported. check out the official doc at https://developer.android.com/reference/androidx/core/graphics/drawable/RoundedBitmapDrawable