添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
map.addMarker(new MarkerOptions()
    .position(latLng)
    .icon(BitmapDescriptorFactory.fromResource(R.drawable.your_vector_asset))
    .title(title);

this doesnot work when dealing with 向量资产s. The main reason to ask the question. The error with the above code:

java.lang.IllegalArgumentException。解码图像失败。提供的图像必须是位图。

5 个评论
@RishabhMahatha 我可以很容易地用png来做,但问题是png是一个很重的文件。要么我必须把它存储在我的apk中,要么必须从服务器上调用它。但我特别需要从矢量资产文件中调用它。
@LucaNicoletti 我必须使用矢量资产(或SVG)文件来实现这个目标,我没有得到任何库或方法来做到这一点。
有人发现了什么吗?
它也可以在这个答案中找到。stackoverflow.com/questions/33696488/...
有一个扩展方法Drawable.toBitmap(),你可以用BitmapDescriptorFactory.fromBitmap()来实现它。
android
google-maps-markers
google-maps-android-api-2
Shuddh
Shuddh
发布于 2017-02-21
9 个回答
Leonid Ustenko
Leonid Ustenko
发布于 2020-03-12
已采纳
0 人赞同

你可以使用这种方法。

private BitmapDescriptor bitmapDescriptorFromVector(Context context, int vectorResId) {
        Drawable vectorDrawable = ContextCompat.getDrawable(context, vectorResId);
        vectorDrawable.setBounds(0, 0, vectorDrawable.getIntrinsicWidth(), vectorDrawable.getIntrinsicHeight());
        Bitmap bitmap = Bitmap.createBitmap(vectorDrawable.getIntrinsicWidth(), vectorDrawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        vectorDrawable.draw(canvas);
        return BitmapDescriptorFactory.fromBitmap(bitmap);

So your code will look like:

map.addMarker(new MarkerOptions()
                .position(latLng)
                .icon(bitmapDescriptorFromVector(getActivity(), R.drawable.your_vector_asset))
                .title(title);

Edit:
在Kotlin中,它可能看起来像。

private fun bitmapDescriptorFromVector(context: Context, vectorResId: Int): BitmapDescriptor? {
        return ContextCompat.getDrawable(context, vectorResId)?.run {
            setBounds(0, 0, intrinsicWidth, intrinsicHeight)
            val bitmap = Bitmap.createBitmap(intrinsicWidth, intrinsicHeight, Bitmap.Config.ARGB_8888)
            draw(Canvas(bitmap))
            BitmapDescriptorFactory.fromBitmap(bitmap)
    
你有没有试过。我已经有一段时间没有看到这个代码了!
Sure, I used it in my project
这仍然能解决我的问题你的方法给我的只是那个汽车图标而不是蓝色的背景。我需要保留那个背景,再加上这个图标。
你的意思是,汽车图标是一个独立的图标,而不是针。
在我的项目中使用了这个,从矢量资产中获得一个标记。
SidMorad
SidMorad
发布于 2020-03-12
0 人赞同

我正在寻找完全相同的要求,看到这个问题让我一开始就很高兴,但和@Shuddh一样,我对给出的答案并不满意。

简而言之,我使用以下代码来满足这一要求。

private BitmapDescriptor bitmapDescriptorFromVector(Context context, @DrawableRes  int vectorDrawableResourceId) {
    Drawable background = ContextCompat.getDrawable(context, R.drawable.ic_map_pin_filled_blue_48dp);
    background.setBounds(0, 0, background.getIntrinsicWidth(), background.getIntrinsicHeight());
    Drawable vectorDrawable = ContextCompat.getDrawable(context, vectorDrawableResourceId);
    vectorDrawable.setBounds(40, 20, vectorDrawable.getIntrinsicWidth() + 40, vectorDrawable.getIntrinsicHeight() + 20);
    Bitmap bitmap = Bitmap.createBitmap(background.getIntrinsicWidth(), background.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    background.draw(canvas);
    vectorDrawable.draw(canvas);
    return BitmapDescriptorFactory.fromBitmap(bitmap);

和一个使用实例。

.icon(bitmapDescriptorFromVector(this, R.drawable.ic_car_white_24dp));

注意:你可能希望为你的矢量使用不同的边界,我的矢量大小为24dp,我使用了一张48dp的png图片(蓝色部分,也可以是矢量)作为背景。

更新:按照要求添加了截图。

我认为这将是一个好办法。我将检查这个问题并标记答案。但如果你有一个截图。请分享。
我添加了一张截图,我希望能澄清最初的要求!;-)"我的意思是在地图引脚内重复使用向量"
我认为内部图像边界的计算应该是不同的(下面的kotlin实现)。 替换代码0【替换代码1【替换代码2
xjcl
他们看起来真的是低分辨率
@xjcl 我确实猜到有人会这么说!:) 这就是为什么我在我的答案中加入了这一部分。"我使用了一张48dp的png图片(蓝色部分。这也可以是一个矢量)作为背景"
Kasun Thilina
Kasun Thilina
发布于 2020-03-12
0 人赞同

Here is the code for kotlin lovers ;)

private fun bitMapFromVector(vectorResID:Int):BitmapDescriptor {
    val vectorDrawable=ContextCompat.getDrawable(context!!,vectorResID)
    vectorDrawable!!.setBounds(0,0,vectorDrawable!!.intrinsicWidth,vectorDrawable.intrinsicHeight)
    val bitmap=Bitmap.createBitmap(vectorDrawable.intrinsicWidth,vectorDrawable.intrinsicHeight,Bitmap.Config.ARGB_8888)
    val canvas=Canvas(bitmap)
    vectorDrawable.draw(canvas)
    return BitmapDescriptorFactory.fromBitmap(bitmap)
    
ravi
你对这个片段有什么问题吗?特别是setBounds部分?
prerak
prerak
发布于 2020-03-12
0 人赞同

可能有点晚了,但这与谷歌地图V2版配合得很好。

public static BitmapDescriptor getBitmapFromVector(@NonNull Context context,
                                                   @DrawableRes int vectorResourceId,
                                                   @ColorInt int tintColor) {
    Drawable vectorDrawable = ResourcesCompat.getDrawable(
            context.getResources(), vectorResourceId, null);
    if (vectorDrawable == null) {
        Log.e(TAG, "Requested vector resource was not found");
        return BitmapDescriptorFactory.defaultMarker();
    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());
    DrawableCompat.setTint(vectorDrawable, tintColor);
    vectorDrawable.draw(canvas);
    return BitmapDescriptorFactory.fromBitmap(bitmap);

初始化为。

locationMarkerIcon = LayoutUtils.getBitmapFromVector(ctx, R.drawable.ic_location_marker,
                ContextCompat.getColor(ctx, R.color.marker_color));

使用方法。

googleMap.addMarker(MarkerOptions().icon(getMarkerIcon()).position(latLng));

注意。getMarkerIcon()只是返回初始化的非空locationMarkerIcon成员变量。

Screenshot:

这不是问题所要求的。如果你能看到正确答案处附上的截图。
@Shuddh基本上我的矢量资产在我的截图中有点不同(基于我的项目),但就我看来,你最初的问题问的是如何使用矢量资产作为标记图标,这就是静态方法的作用(同时也为它动态地添加颜色)。
它不是动态地添加颜色。这基本上是内部图标的变化。如果你能看到所选答案中的屏幕截图
很好!在我的案例中,我去掉了着色剂的颜色,它很有效!此外,我建议修改标记的锚,如下所示(如果你的是一个经典的针)。【替换代码0
Shihab Uddin
Shihab Uddin
发布于 2020-03-12
0 人赞同

在Kotlin中:我使用下面的代码在Marker上显示SVG图片。这里,我没有使用背景色/SVG。

fun getBitmapDescriptorFromVector(context: Context, @DrawableRes vectorDrawableResourceId: Int): BitmapDescriptor? {
    val vectorDrawable = ContextCompat.getDrawable(context, vectorDrawableResourceId)
    val bitmap = Bitmap.createBitmap(vectorDrawable!!.intrinsicWidth, vectorDrawable.intrinsicHeight, Bitmap.Config.ARGB_8888)
    val canvas = Canvas(bitmap)
    vectorDrawable.setBounds(0, 0, canvas.width, canvas.height)
    vectorDrawable.draw(canvas)
    return BitmapDescriptorFactory.fromBitmap(bitmap)

像这样使用。

googleMap?.addMarker(MarkerOptions().position(LatLng(it.latitude!!, it.longitude!!))
            .title(it.airLineDetails))?.setIcon(
            getBitmapDescriptorFromVector(requireContext(), R.drawable.ic_flight_blue))

Screen Shot:

M.Yogeshwaran
M.Yogeshwaran
发布于 2020-03-12
0 人赞同

If someone who is looking for in kotlin here is the method for you :

  private fun  bitmapDescriptorFromVector(vectorResId:Int):BitmapDescriptor {
            var vectorDrawable = ContextCompat.getDrawable(requireContext(), vectorResId);
            vectorDrawable!!.setBounds(0, 0, vectorDrawable.getIntrinsicWidth(), vectorDrawable.getIntrinsicHeight());
            var bitmap = Bitmap.createBitmap(vectorDrawable.getIntrinsicWidth(), vectorDrawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
            var canvas =  Canvas(bitmap);
            vectorDrawable.draw(canvas);
            return BitmapDescriptorFactory.fromBitmap(bitmap);

上述方法将把你的矢量图标转换为位图。

map.addMarker(new MarkerOptions()
                .position(latLng)
                .icon(bitmapDescriptorFromVector(getActivity(), R.drawable.your_vector_asset))
                .title(title)

这个是为你的地图设置标记的,感谢Leo Droidcoder,从他的回答中,我已经把它转换成了kotlin。

Shahab Saalami
Shahab Saalami
发布于 2020-03-12
0 人赞同

将矢量资源转换为位图对象并使用BitmapDescriptorFactory.fromBitmap(bitmap)

   Bitmap bitmap = getBitmapFromVectorDrawable(getContext(),R.drawable.ic_pin);
   BitmapDescriptor descriptor =BitmapDescriptorFactory.fromBitmap(bitmap);
   MarkerOptions markerOptions = new MarkerOptions();
   markerOptions.icon(descriptor);

位图转换器。

 public static Bitmap getBitmapFromVectorDrawable(Context context, int drawableId) {
        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;
    
是的,我正在寻找这个答案,它以位图格式返回。)
Eswar
Eswar
发布于 2020-03-12
0 人赞同

Try this

MarkerOptions op = new MarkerOptions();
op.position(src_latlng);
Marker origin_marker = googleMap.addMarker(op);
Bitmap bitmap = getBitmap(this,R.drawable.ic_map_marker);
origin_marker.setIcon(BitmapDescriptorFactory.fromBitmap(bitmap));

读取比特图

public 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");

ic_map_marker.xml

<vector android:height="32dp" android:viewportHeight="512.0"
    android:viewportWidth="512.0" android:width="32dp" xmlns:android="http://schemas.android.com/apk/res/android">
    <path android:fillColor="#f32f00" android:pathData="M288,284.8V480l-64,32V284.8c10.3,2.1 21,3.3 32,3.3S277.7,286.9 288,284.8zM384,128c0,70.7 -57.3,128 -128,128c-70.7,0 -128,-57.3 -128,-128S185.3,0 256,0C326.7,0 384,57.3 384,128zM256,64c0,-17.7 -14.3,-32 -32,-32s-32,14.3 -32,32s14.3,32 32,32S256,81.7 256,64z"/>
</vector>
    
你能解释一下vectorDrawable的返回语句吗?你所使用的getBitmap方法是什么。
另外,我不认为这也会给我带来我想要的标记。因为图片中显示的标记是包含矢量资产的默认标记。但这段代码会根据矢量资产生成图标,但不包括标记(蓝色部分)。
@Shuddh 你所寻找的图标必须是定制的。矢量资产应该定义蓝色和白色的汽车部分。然后你将该矢量添加为图标。
@PradumnKumarMahanta 所以我必须为图标的背景创建另一个矢量。对吗?但是如何设置一个矢量作为标记?
@Shuddh 不,你可以为完整的东西创建一个矢量。标记+图像。然后用Eswar所说的方法或Hiristo Stoyanov和我建议的方法将该矢量添加为标记,这两种方法对我都有效。
Kaushik Kumar
Kaushik Kumar
发布于 2020-03-12
0 人赞同

对于Kotlin用户来说,请查看下面的代码,正如我在Fragment类中所做的那样。

class MapPinFragment : Fragment() {
    private lateinit var googleMap1: GoogleMap
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.fragment_map_pin, container, false)
    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        mapView.onCreate(savedInstanceState)
        mapView.onResume()
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        mapView.getMapAsync { googleMap ->
            googleMap1 = googleMap as GoogleMap
            addCustomMarker()
    private fun addCustomMarker() {
        Log.d("addCustomMarker", "addCustomMarker()")
        if (googleMap1 == null) {
            return
        // adding a marker on map with image from  drawable
        googleMap1.addMarker(
            MarkerOptions()
                .position(LatLng(23.0225 , 72.5714))
                .icon(BitmapDescriptorFactory.fromBitmap(getMarkerBitmapFromView()))
    override fun onDestroy() {
        super.onDestroy()
        if (mapView != null)
            mapView.onDestroy()
    override fun onLowMemory() {
        super.onLowMemory()
        mapView.onLowMemory()
    private fun getMarkerBitmapFromView(): Bitmap? {
        val customMarkerView: View? = layoutInflater.inflate(R.layout.view_custom_marker, null)
//        val markerImageView: ImageView =
//            customMarkerView.findViewById<View>(R.id.profile_image) as ImageView
        customMarkerView?.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED );
        customMarkerView?.layout(0, 0, customMarkerView.measuredWidth, customMarkerView.measuredHeight);
        customMarkerView?.buildDrawingCache();
        val returnedBitmap = Bitmap.createBitmap(
            customMarkerView!!.measuredWidth, customMarkerView.measuredHeight,
            Bitmap.Config.ARGB_8888
        val canvas = Canvas(returnedBitmap)
        canvas.drawColor(Color.WHITE, PorterDuff.Mode.SRC_IN)
        val drawable = customMarkerView.background
        drawable?.draw(canvas);
        customMarkerView.draw(canvas);
        return returnedBitmap;