I have a png image inside my Drawable folder. The same image I use it in many markers but in different sizes. Instead of creating many images with different sizes, I wanted to create XMLs inside the Drawable folder reusing the orignial image.
I tried solutions on this answers: Scale a drawable resource in XML (Android) but they are not working in my cases. When I reach
BitmapDescriptor scaledIcon = BitmapDescriptorFactory.fromResource(R.drawable.scaled_marker_image); //scaled_marker_image is the XML that resize the original image
mMap.addMarker(new MarkerOptions().position(new LatLng(location.getLatitude(), location.getLongitude())).title("Marker").icon(scaledIcon));
Basically in the MarjerOptions().icon(scaledIcon) I get nullPointerException
Any ideas how to achieve this?
XML would look like this (as shown in Scale a drawable resource in XML (Android) answer)
<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="#drawable/marker_image"
android:insetTop="30dp"
android:insetLeft="10dp"
android:insetRight="10dp"
android:insetBottom="0dp"
/>
We define a method to transform a Drawable to Bitmap
public static Bitmap drawableToBitmap (Drawable drawable) {
Bitmap bitmap = null;
if (drawable instanceof BitmapDrawable) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
if(bitmapDrawable.getBitmap() != null) {
return bitmapDrawable.getBitmap();
}
}
if(drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) {
bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); // Single color bitmap will be created of 1x1 pixel
} else {
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;
}
And then, to set the drawable to the marker:
Drawable drawable = getResources().getDrawable(getResources().getDrawable(R.drawable.mi_posicion_marker2));
BitmapDescriptor scaledIcon = BitmapDescriptorFactory.fromBitmap(drawableToBitmap(drawable));
mMap.addMarker(new MarkerOptions().position(new LatLng(location.getLatitude(), location.getLongitude())).title("Marker").icon(scaledIcon));
Related
I am developing custom view for android. For that I want give a user ability to select and image using just like when using ImageView
In attr.xml I added bellow code.
<declare-styleable name="DiagonalCut">
<attr name="altitude" format="dimension"/>
<attr name="background_image" format="reference"/>
</declare-styleable>
In custom view I get this value as a Drawable which was provided in xml as app:background_image="#drawable/image"
TypedArray typedArray = getContext().obtainStyledAttributes(arr, R.styleable.DiagonalCut);
altitude = typedArray.getDimensionPixelSize(R.styleable.DiagonalCut_altitude,10);
sourceImage = typedArray.getDrawable(R.styleable.DiagonalCut_background_image);
I want to create a Bitmap using this sourceImage which is a Drawable object.
If the way I'm going wrong please provide an alternative.
You can convert your Drawable to Bitmap like this (for resource):
Bitmap icon = BitmapFactory.decodeResource(context.getResources(),
R.drawable.drawable_source);
OR
If you've it stored in a variable, you can use this :
public static Bitmap drawableToBitmap (Drawable drawable) {
Bitmap bitmap = null;
if (drawable instanceof BitmapDrawable) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
if(bitmapDrawable.getBitmap() != null) {
return bitmapDrawable.getBitmap();
}
}
if(drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) {
bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); // Single color bitmap will be created of 1x1 pixel
} else {
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;
}
More details
I need to change the default cross-icon in ChromeCustomTab Android, I am changing it with back-icon using the code below:
Bitmap icon = BitmapFactory.decodeResource(context.getResources(),R.drawable.ic_arrow_back_white_24dp);
It is working fine with PNGs but not with SVGs.
As per this documentation, we have to maintain size of image according to this documentation.
https://developer.android.com/reference/android/support/customtabs/CustomTabsIntent.html#KEY_ICON
I think it is not working because they are not following the dimensions given in Documentation.
You need to return a valid Bitmap. For a VectorDrawable it is necessary to do something more. You can use these methods:
private static Bitmap bitmapFromDrawable(Context context, int drawableId) {
Drawable drawable = ContextCompat.getDrawable(context, drawableId);
if (drawable instanceof VectorDrawable) {
return bitmapFromVectorDrawable((VectorDrawable) drawable);
}
return ((BitmapDrawable) drawable).getBitmap();
}
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
private static Bitmap bitmapFromVectorDrawable(VectorDrawable vectorDrawable) {
Bitmap bitmap = Bitmap.createBitmap(vectorDrawable.getIntrinsicWidth(), vectorDrawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
vectorDrawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
vectorDrawable.draw(canvas);
return bitmap;
}
Then you can use it like:
builder.setCloseButtonIcon(bitmapFromDrawable(this, R.drawable. ic_arrow_back_white_24dp));
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
}
I'm trying to add support to tablets in my app and run into IllegalArgumentException thrown by this line of code:
marker.setIcon(BitmapDescriptorFactory.fromResource(R.drawable.arrow_green_10by19))
The method .fromResource works fine with the R.drawable.arrow_green_10by19 from an image file (png) but when the png is replaced with the vector file arrow_green_10by19.xml (which renders fine in the Android Studio IDE) it generates a runtime as mentioned.
Does anybody knows how to implement a vector resource in the BitmapDescriptorFactory and could help me out?
Thanks.
I had the same problem but I realized that on my device with API 16 it works fine but with API 21 it crashes. Finally it works in both devices using this solution. Here the code:
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
private static Bitmap getBitmap(VectorDrawable vectorDrawable) {
Bitmap bitmap = Bitmap.createBitmap(vectorDrawable.getIntrinsicWidth(),
vectorDrawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
vectorDrawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
vectorDrawable.draw(canvas);
return bitmap;
}
and this:
private static Bitmap getBitmap(Context context, int drawableId) {
Drawable drawable = ContextCompat.getDrawable(context, drawableId);
if (drawable instanceof BitmapDrawable) {
return BitmapFactory.decodeResource(context.getResources(), drawableId);
} else if (drawable instanceof VectorDrawable) {
return getBitmap((VectorDrawable) drawable);
} else {
throw new IllegalArgumentException("unsupported drawable type");
}
}
So I combined those 2 functions in this way:
private Marker addMark(LatLng latLng, String title) {
Bitmap bitmap = getBitmap(getContext(), R.drawable.ic_place_24dp);
Marker marker = googleMap.addMarker(new MarkerOptions().position(latLng)
.title(title)
.icon(BitmapDescriptorFactory.fromBitmap(bitmap))
.draggable(true));
return marker;
}
Where R.drawable.ic_place_24dp is a vector asset (.xml), not a .png
I am trying to add a color filer in a drawable and then convert it in Bitmap. The problem is when convert the drawable into bitmap it loses it's color filter.I used drawable in imageview and its have the color filter but using bitmap in imageview doesn't have any color effect. Why this happen ? Thanks in advance.
Use a canvas to blit the Drawable back onto a bitmap:
Canvas canvas;
Drawable drawable = <yourDrawable created from wherever>;
Bitmap bmp = <your Bitmap which is the same width/height as the drawable>
// blit the drawable onto the bitmap using a Canvas
canvas = new Canvas(bmp);
drawable.draw(canvas);
http://developer.android.com/guide/topics/graphics/2d-graphics.html
I had the same problem and I figured it out finally!
We need to do following thing to get the bitmap with color filter applied on it.
image_view.setDrawingCacheEnabled(true);
Bitmap bitmap = Bitmap.createBitmap(image_view.getDrawingCache());
I've faced the same issue and finally found a solution.
Drawable can have multiple states thus you might be drawing wrong state.
You should switch it to proper mode before drawing:
Drawable drawable = icon.loadDrawable(getContext());
if (drawable == null) {
return;
}
drawable.setState(new int[] {android.R.attr.state_enabled});
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);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);