【问题标题】:Android Palette returning transparent color for some imagesAndroid Palette 为某些图像返回透明颜色
【发布时间】:2017-08-29 11:19:18
【问题描述】:

我有一个 AsyncTask 从 url 加载位图并使用 Palette 更改浮动操作按钮的背景。对于大多数图像,它可以正常工作,但在某些图像上,它会使按钮透明。屏幕截图 1 显示按钮颜色与图像中的蓝色一起使用,但在屏幕截图 2 中,按钮的颜色是透明的(即使图像不包含任何透明像素,因为它是 jpeg)。

    public class ColoredFabTask extends AsyncTask<String , String , String> {
    Context mContext;
    View view;
    private View rootView;
    URL myFileUrl;
    Bitmap imageBitmap = null;

    public ColoredFabTask(Context context, View view) {
        this.mContext = context;
        this.view = view;
    }

    @Override
    protected void onPreExecute() {
    }

    @Override
    protected String doInBackground(String... args) {
        try {
            myFileUrl = new URL(args[0]);
            HttpURLConnection conn = (HttpURLConnection) 
            myFileUrl.openConnection();
            conn.setDoInput(true);
            conn.connect();
            InputStream is = conn.getInputStream();
            imageBitmap = BitmapFactory.decodeStream(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(String args) {
        Palette palette  = Palette.from(imageBitmap).generate();
        int vibrant = palette.getVibrantColor(0);
        FloatingActionButton applyButton = (FloatingActionButton) view.findViewById(R.id.applyButton);
        applyButton.setBackgroundTintList(ColorStateList.valueOf(vibrant));
        applyButton.setVisibility(View.VISIBLE);
    }
}

截图:

【问题讨论】:

    标签: android android-asynctask palette


    【解决方案1】:

    如果有人想知道如何解决问题,请自行解决。只需检查样本是否为空。

            Palette palette = Palette.from(imageBitmap).generate();
            int fallbackColor = palette.getDominantColor(0);
            Palette.Swatch vibrantColorSwatch = palette.getVibrantSwatch();
            if (vibrantColorSwatch != null) {
                int vibrantColor = vibrantColorSwatch.getRgb();
                FloatingActionButton applyButton = (FloatingActionButton) view.findViewById(R.id.applyButton);
                applyButton.setBackgroundTintList(ColorStateList.valueOf(vibrantColor));
    
            }
            else {
                FloatingActionButton applyButton = (FloatingActionButton) view.findViewById(R.id.applyButton);
                applyButton.setBackgroundTintList(ColorStateList.valueOf(fallbackColor));
            }
    

    【讨论】:

    • 你可以使用palette.getVibrantColor(fallbackColor);
    【解决方案2】:

    Paletter 默认忽略其中的一些颜色。这是 Palette 来源的实现:

    static final Palette.Filter DEFAULT_FILTER = new Palette.Filter() {
        private static final float BLACK_MAX_LIGHTNESS = 0.05F;
        private static final float WHITE_MIN_LIGHTNESS = 0.95F;
    
        public boolean isAllowed(int rgb, float[] hsl) {
            return !this.isWhite(hsl) && !this.isBlack(hsl) && !this.isNearRedILine(hsl);
        }
    
        private boolean isBlack(float[] hslColor) {
            return hslColor[2] <= 0.05F;
        }
    
        private boolean isWhite(float[] hslColor) {
            return hslColor[2] >= 0.95F;
        }
    
        private boolean isNearRedILine(float[] hslColor) {
            return hslColor[0] >= 10.0F && hslColor[0] <= 37.0F && hslColor[1] <= 0.82F;
        }
    };
    

    如您所见,它强制 Palette 忽略某些颜色。 因此,您需要尝试设置自定义过滤器以允许处理所有颜色

    【讨论】:

    • 你能告诉我在kotlin中调用palette api listener之前如何添加这个过滤器吗?
    猜你喜欢
    • 2013-01-09
    • 1970-01-01
    • 2016-06-20
    • 2012-07-21
    • 2013-01-15
    • 2011-07-06
    • 1970-01-01
    • 2012-05-07
    • 2012-10-21
    相关资源
    最近更新 更多