Android — Glide 4.0.0-RC0: как установить цвет оттенка для ImageView после успешной загрузки SVG

Я следовал этому примеру: https://github.com/bumptech/glide/tree/master/samples/svg/src/main/java/com/bumptech/glide/samples/svg

После успешной загрузки файла SVG с помощью Glide 4.0.0-RC0 я хочу установить цвет оттенка для ImageView, но setColorFilter НЕ РАБОТАЕТ

Мой источник:

package com.example.quangson.glidesvg;

import static com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions.withCrossFade;

import android.content.ContentResolver;
import android.graphics.PorterDuff;
import android.graphics.drawable.PictureDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.ImageView;
import com.bumptech.glide.RequestBuilder;
import com.example.quangson.glidesvg.glide.GlideApp;
import com.example.quangson.glidesvg.glide.SvgSoftwareLayerSetter;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "SVGActivity";
    private ImageView imageViewSVG;
    private ImageView imageViewPNG;
    private RequestBuilder<PictureDrawable> requestBuilder;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        imageViewSVG = (ImageView) findViewById(R.id.svg_image_view1);
        imageViewPNG = (ImageView) findViewById(R.id.svg_image_view2);

        imageViewPNG.setImageResource(R.drawable.image_mylogo);

        requestBuilder = GlideApp.with(this)
                .as(PictureDrawable.class)
                .error(R.drawable.image_error)
                .transition(withCrossFade())
                .listener(new SvgSoftwareLayerSetter());
        Uri uri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + getPackageName() + "/"  + R.raw.android_toy_h);
        requestBuilder.load(uri).into(imageViewSVG);

        imageViewSVG.setColorFilter(getResources().getColor(R.color.colorAccent), PorterDuff.Mode.SRC_IN);
        imageViewPNG.setColorFilter(getResources().getColor(R.color.colorAccent), PorterDuff.Mode.SRC_IN);
    }
}

В моем источнике:

Я загрузил изображение PNG (из res/drawable) в imageViewPNG и установил ColorFilter для imageViewPNG ⇒ РАБОТАЕТ

Я загрузил изображение SVG (из res/raw) в imageViewSVG и установил ColorFilter для imageViewSVG ⇒ НЕ РАБОТАЕТ (файл SVG успешно загружен, но не может установить ColorFilter)

Пожалуйста, помогите мне установить цвет оттенка для imageViewSVG.


Я попытался отредактировать приведенный ниже код, чтобы создать SvgDrawableTranscoder, который генерирует BitmapDrawable (и после этого устанавливает ColorFilter), но он не работает, помогите мне?

package com.sonzero.chibiz.glide;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Picture;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.PictureDrawable;

import com.bumptech.glide.load.engine.Resource;
import com.bumptech.glide.load.resource.SimpleResource;
import com.bumptech.glide.load.resource.transcode.ResourceTranscoder;
import com.caverock.androidsvg.SVG;

/**
 * Convert the {@link SVG}'s internal representation to an Android-compatible one
 * ({@link Picture}).
 */
public class SvgDrawableTranscoder implements ResourceTranscoder<SVG, BitmapDrawable> {
    @Override
    public Resource<BitmapDrawable> transcode(Resource<SVG> toTranscode) {
        SVG svg = toTranscode.get();
        Picture picture = svg.renderToPicture();
        PictureDrawable drawable = new PictureDrawable(picture);
        Bitmap bitmap = asBitmap(drawable);
        BitmapDrawable mDrawable = new BitmapDrawable(bitmap);
        return new SimpleResource<BitmapDrawable>(mDrawable);
    }

    public Bitmap asBitmap(PictureDrawable pd) {
        Bitmap bitmap = Bitmap.createBitmap(pd.getIntrinsicWidth(),pd.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        canvas.drawPicture(pd.getPicture());
        return bitmap;
    }
}

person Sonzero    schedule 23.05.2017    source источник
comment
похоже, что его не реализовано на гитхабе.   -  person Robert Longson    schedule 23.05.2017
comment
Он просто поддерживает Drawable или GifDrawable, а не SVG. пожалуйста помоги   -  person Sonzero    schedule 23.05.2017
comment
Помогите как? Вам нужен кто-то, чтобы реализовать это, если вы хотите продолжать использовать эту библиотеку. Скорее всего, вам придется сделать это самостоятельно или заплатить кому-то за это.   -  person Robert Longson    schedule 23.05.2017
comment
Знаете ли вы какое-либо другое решение, которое может решить эту проблему?   -  person Sonzero    schedule 23.05.2017


Ответы (2)


Загрузчик Glide SVG создает файл PictureDrawable. Последнее, что я проверял, PictureDrawables не поддерживает метод setColorFilter().

Что вы можете попробовать, так это создать свою собственную версию SvgDrawableTranscoder, которая вместо этого генерирует BitmapDrawable и использует метод AndroidSVG renderToCanvas().

Обновить

AndroidSVG 1.4+ теперь поддерживает передачу дополнительного CSS во время рендеринга. Создайте объект RenderOptions и укажите некоторые правила CSS, используя .css(). Затем вы можете передать этот объект RenderOptions renderToPicture() в файле SvgDrawableTranscoder.

RenderOptions  renderOptions = RenderOptions.create().css("path { fill: red; }");
Picture picture = svg.renderToPicture(renderOptions);
...etc...

документация RenderOptions

person Paul LeBeau    schedule 23.05.2017
comment
Я попытался отредактировать код, как показано ниже, но он не работает, вы можете мне помочь? - person Sonzero; 23.05.2017
comment
открытый класс SvgDrawableTranscoder реализует ResourceTranscoder‹SVG, BitmapDrawable› { @Override public Resource‹BitmapDrawable› transcode(Resource‹SVG› toTranscode) { SVG svg = toTranscode.get(); Картинка картинка = svg.renderToPicture(); PictureDrawable drawable = новый PictureDrawable(изображение); Растровое изображение = asBitmap(drawable); BitmapDrawable mDrawable = новый BitmapDrawable (растровое изображение); вернуть новый SimpleResource‹BitmapDrawable›(mDrawable); } } - person Sonzero; 23.05.2017
comment
общественное растровое изображение asBitmap (PictureDrawable pd) { растровое изображение = Bitmap.createBitmap (pd.getIntrinsicWidth(), pd.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); Холст холст = новый холст (растровое изображение); холст.drawPicture(pd.getPicture()); вернуть растровое изображение; } - person Sonzero; 23.05.2017
comment
Я не могу прочитать этот код. Добавьте к своему вопросу раздел «Обновление» или задайте новый вопрос. - person Paul LeBeau; 23.05.2017
comment
Можешь объяснить, что ты имеешь в виду под словом "не работает"? Вы получаете какие-либо ошибки? - person Paul LeBeau; 23.05.2017
comment
после того, как я попытался изменить SvgDrawableTranscoder, я не могу загрузить файл SVG в ImageView - person Sonzero; 23.05.2017

Здесь мой подход работает нормально

Шаг 1 установите для svg значение imageView с помощью glide (в моем случае it.menuItemIcon — это объект ImageView)

  Glide.with(it.context).`as`(PictureDrawable::class.java).load(itemData.imageURL)
                .addListener(object: RequestListener<PictureDrawable> {
                    override fun onLoadFailed(
                        e: GlideException?,
                        model: Any?,
                        target: Target<PictureDrawable>?,
                        isFirstResource: Boolean
                    ): Boolean {
                        it.menuItemIcon.visibility = View.INVISIBLE
                        return false
                    }

                    override fun onResourceReady(
                        resource: PictureDrawable?,
                        model: Any?,
                        target: Target<PictureDrawable>?,
                        dataSource: DataSource?,
                        isFirstResource: Boolean
                    ): Boolean {
                        it.menuItemIcon.visibility = View.VISIBLE
                        return false
                    }

                })
                .addListener(SvgSoftwareLayerListener()).into(it.menuItemIcon)

Шаг 2. Теперь при нажатии кнопки вызовите эти два метода.

if(it.menuItemIcon.drawable!=null){
                          val bitmap = getBitMap(it.menuItemIcon)
                          setBitmapAndTint(bitmap,holder.itemView.context,it.menuItemIcon,itemData.isSelected)
                      }

Шаг 3 реализовать getBitMap() для получения Bitmap из объекта ImageView

 private fun getBitMap(view: AppCompatImageView): Bitmap {
    val returnedBitmap = Bitmap.createBitmap(view.width, view.height, Bitmap.Config.ARGB_8888)
    val canvas = Canvas(returnedBitmap)
    val bgDrawable: Drawable = view.drawable
    bgDrawable.draw(canvas)
    view.draw(canvas)
    return returnedBitmap
}

Шаг 4 Теперь реализуйте setBitmapAndTint() для установки растрового изображения и colorFilter(Tint) в imageView.

 private fun setBitmapAndTint(bitmap: Bitmap, context: Context, menuItemIcon: AppCompatImageView, selected: Boolean) {
    menuItemIcon.setImageBitmap(bitmap)
    menuItemIcon.setColorFilter(ContextCompat.getColor(context,R.color.ColorBlack))
}
person Mahesh Kumar Prajapati    schedule 12.02.2021