Android 调色板为某些图像返回透明颜色
Android Palette returning transparent color for some images
我有一个 AsyncTask,它从 url 加载位图并使用调色板更改我的浮动操作按钮的背景。对于大多数图像,它工作正常,但在某些图像上它会使按钮透明。屏幕截图 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);
}
}
截图:
调色板默认忽略其中的一些颜色。这是 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 忽略某些颜色。
因此,您需要尝试设置自定义过滤器以允许处理所有颜色
我自己解决了这个问题,如果有人想知道如何解决的话。只需检查样本是否为空。
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));
}
我有一个 AsyncTask,它从 url 加载位图并使用调色板更改我的浮动操作按钮的背景。对于大多数图像,它工作正常,但在某些图像上它会使按钮透明。屏幕截图 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);
}
}
截图:
调色板默认忽略其中的一些颜色。这是 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 忽略某些颜色。 因此,您需要尝试设置自定义过滤器以允许处理所有颜色
我自己解决了这个问题,如果有人想知道如何解决的话。只需检查样本是否为空。
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));
}