Как получить Палитру для моего растрового изображения, как только Пикассо загрузит его?

В октябре 2014 года Джейк Уортон написал " Принуждение Пикассо к игре с палитрой". В нем рассматриваются 2 метода:

  1. Используя Преобразование, которое генерирует палитру. Преимущество этого заключается в том, что палитра создается в рабочем потоке Пикассо и готова к загрузке изображения. Недостатком, однако, является то, что я получаю палитры, которые не соответствуют картинке. На данный момент я запускаю только одно из этих преобразований одновременно.

  2. ИспользуяCallback тот onSuccess получает растровое изображение от ImageView и генерирует палитру. Я не могу не сосредоточиться на // Ew! что Джейк ставит в конце этой строки, и я вполне согласен с этим.

Упомянутый выше пост был написан в октябре 2014 года. Теперь, когда прошло уже несколько месяцев после обсуждения, мне интересно, какой метод рекомендуется? Была также дискуссия об ассоциации meta data с растровыми изображениями. Это реализовано? Как бы я использовал это?

мой Transformation код (не окончательный, я только начал изучать это):

public final class PaletteGenerator
  implements Transformation {

    private final int numColors;
    @Getter private Palette palette;

    @Override public Bitmap transform (final Bitmap source) {
        palette = null;
        final Palette palette = numColors > 0
                                ? Palette.generate (source, numColors)
                                : Palette.generate (source);
        return source;
    }

    @Override public String key () {
        return String.format (Locale.ENGLISH, "%s:%d", getClass ().getCanonicalName (), numColors);
    }

    public PaletteGenerator () {
        this (0);
    }

    public PaletteGenerator (final int c) {
        numColors = c;
    }
}

2 ответа

Решение

По словам Джейка Уортона, хорошего пути пока нет

В итоге я решил использовать метод Transformation с уродливым кодом, инкапсулированным и спрятанным на чердаке.

public final class PaletteGeneratorTransformation
  implements Transformation {

    private static final Map<Bitmap, Palette> CACHE = new WeakHashMap<> ();
    private final int    numColors;

    @Override public Bitmap transform (final Bitmap source) {
        if (!CACHE.containsKey (source)) {
            final Palette palette = numColors > 0
                      ? Palette.generate (source, numColors)
                      : Palette.generate (source);
            CACHE.put (source, palette);
        }

        return source;
    }

    @Override public String key () {
        return getClass ().getCanonicalName () + ":" + numColors;
    }

    public PaletteGeneratorTransformation () {
        this (0);
    }

    public PaletteGeneratorTransformation (final int c) {
        numColors = c;
    }

    public static abstract class Callback
      implements com.squareup.picasso.Callback {
        private final ImageView target;

        public Callback (final ImageView t) {
            target = t;
        }

        @Override public void onSuccess () {
            onPalette (CACHE.get (((BitmapDrawable) target.getDrawable ()).getBitmap ()));
        }

        @Override public void onError () {
            onPalette (null);
        }

        public abstract void onPalette (final Palette palette);
    }
}

В своей деятельности я делаю что-то вроде этого:

Picasso.with(context)
    .load (getPhotoUri())
    .transform (new PaletteGeneratorTransformation (DEFAULT_NUM_COLORS))
    .into (photo, new PaletteGeneratorTransformation.Callback (photo) {
                        @Override public void onPalette (final Palette palette) {
                            themeWithPalette (palette);
                        }
                    });

Осталась только одна проблема: я знаю, что на чердаке спрятано безобразие, и пока это должно оставаться моим грязным маленьким секретом.

Target target = new Target() {
        @Override
        public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
            viewHolder.mItemImage.setImageBitmap(bitmap);
            Drawable image = viewHolder.mItemImage.getDrawable();
        }

        @Override
        public void onPrepareLoad(Drawable placeHolderDrawable) {

        }

        @Override
        public void onBitmapFailed(Drawable errorDrawable) {

        }
    };
    Picasso.with(viewHolder.mItemImage.getContext()).load("url").into(viewHolder.mItemImage);
Другие вопросы по тегам