我已经在使用 setColorFilter() 为这些线条添加颜色。这条线的原始颜色是黄色。我使用红色或绿色取决于某些陈述。
这是我到目前为止所拥有的: 有人帮我做到了这一点: How to set filter property in ImageView Android studio
但现在我需要在线下添加颜色......就像这样:
sparkline.setColorFilter(Color.RED, PorterDuff.Mode.MULTIPLY);
sparkline.setImageResource(R.drawable.btc_spike);
<androidx.constraintlayout.utils.widget.ImageFilterView
android:layout_width="80dp"
android:layout_height="50dp"
android:id="@+id/sparkline"
android:layout_marginRight="2dp"
app:saturation="80"
app:brightness="0.85"
app:crossfade="0.0"
app:warmth="10"
android:src="@drawable/btc_spike" />
我也找到了这个页面,但不确定它是否要我在这个页面上添加另一个图像或其他东西......
https://developer.android.com/reference/android/graphics/PorterDuff.Mode#MULTIPLY
最佳答案
要使用 png 图像在线条下添加颜色,您可以执行如下操作:
- 以位图形式检索 png 图像(源位图)。
- 将源位图复制到临时位图(输出位图)中。
- 迭代输出位图的每个 x,y 像素并找到线像素(非透明像素)。其余透明像素将其区分为线条区域上方和线条区域下方的透明像素。
- 最后将红色/绿色设置为线条像素,将红色/绿色灯光颜色设置为线条下方的透明像素。
这是一个执行上述步骤的辅助函数:
public static Bitmap getShadowLineBitmap(@NonNull Bitmap srcBitmap, @ColorInt int lineColor, @ColorInt int shadowUnderLineColor){
//copy the srcBitmap to the outBitmap
Bitmap outBitmap = srcBitmap.copy(srcBitmap.getConfig(), true);
try
{
//iterate each x,y pixel
for (int x = 0; x < outBitmap.getWidth(); x++) {
boolean foundLinePx = false;
for (int y = 0; y < outBitmap.getHeight(); y++) {
//get the current RGBA x,y pixel
int rgba = outBitmap.getPixel(x, y);
//if its a Transparent pixel it means that is a pixel above or below the line
//so draw the pixels above the line to Transparent and draw the pixels below the line to a red/green light color
if (rgba == Color.TRANSPARENT) {
if(foundLinePx)
outBitmap.setPixel(x, y, shadowUnderLineColor);
else
outBitmap.setPixel(x, y, rgba);
}
//if its a Non-Transparent pixel it means that is a line pixel so draw each line pixel to red/green
else {
outBitmap.setPixel(x, y, lineColor);
foundLinePx = true;
}
}
}
}catch (Exception e){
}
return outBitmap;
}
可以像下面这样使用:
//get the src Bitmap from Resources (Bitmap can be retrieved also from Glide/Picasso)
Bitmap srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.sparkline);
//Draw the Bitmap with Green Line Color and Green Shadow Light Color
imageView.setImageBitmap(getShadowLineBitmap(srcBitmap, Color.argb(255, 25, 189, 119), Color.argb(255, 231, 250, 243)));
//Draw the Bitmap with Red Line Color and Red Shadow Light Color
imageView.setImageBitmap(getShadowLineBitmap(srcBitmap, Color.argb(255, 228, 112, 117), Color.argb(255, 252, 227, 228)));
结果:
在 RecyclerView 中使用 Glide 加载位图
我已经使用 RecyclerView 测试了来自您的域的一些图形图像链接(例如: https://s3.coinmarketcap.com/generated/sparklines/web/7d/usd/1.png ),即使我向上/向下滚动单元格,它也能按预期工作。
在 void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position)
添加以下代码行以使用 Glide 加载位图(Glide 版本:com.github.bumptech.glide:glide:4.12.0):
Glide.with(itemView.getContext().getApplicationContext())
.asBitmap()
.placeholder(R.drawable.placeholer)
.error(R.drawable.error)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.override(164, 48) //we know the web image size (164x48)
.load(url)
.into(new CustomTarget<Bitmap>(164, 48)
{
@Override
public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
//set resource to ImageBitmap
imageView.setImageBitmap(resource);
//set Green Color filter to line and Green Shadow line colour in AsyncTask
if(isGreen) {
imageView.setColorFilter(Color.argb(255, 25, 189, 119), PorterDuff.Mode.MULTIPLY);
new DrawBitmapShadowAsyncTask(imageView,
Color.argb(255, 25, 189, 119),
Color.argb(255, 231, 250, 243))
.execute(resource);
}
//set Red Color filter to line and Red Shadow line colour in AsyncTask
else{
imageView.setColorFilter(Color.argb(255, 228, 112, 117), PorterDuff.Mode.MULTIPLY);
new DrawBitmapShadowAsyncTask(imageView,
Color.argb(255, 228, 112, 117),
Color.argb(255, 252, 227, 228))
.execute(resource);
}
}
@Override
public void onLoadStarted(@Nullable Drawable placeholder) {
if(placeholder!=null){
imageView.setImageDrawable(placeholder);
}
else {
imageView.setImageBitmap(BitmapFactory.decodeResource(itemView.getResources(), R.drawable.placeholer));
}
}
@Override
public void onLoadFailed(@Nullable Drawable errorDrawable) {
if(errorDrawable!=null){
imageView.setImageDrawable(errorDrawable);
}
else {
imageView.setImageBitmap(BitmapFactory.decodeResource(itemView.getResources(), R.drawable.error));
}
}
@Override
public void onLoadCleared(@Nullable Drawable placeholder) {
}
});
从上面:
void onLoadStarted(@Nullable Drawable placeholder)
设置加载开始时可绘制的 ImageView 占位符。void onLoadFailed(@Nullable Drawable errorDrawable)
设置加载失败时 ImageView 错误可绘制。void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition)
当资源加载完成并且位图可供使用时调用。在此回调中,我们使用 AsyncTask 中之前的辅助函数在图形线下方使用浅色进行绘制。
下面是DrawBitmapShadowAsyncTask
RecyclerView Adapter 中使用的 AsyncTask 私有(private)静态类 Glide onResourceReady
在背景线程中的线条下方绘制阴影颜色:
/**
* Draws Shadow Color under the Graph line asynchronously
*/
private static class DrawBitmapShadowAsyncTask extends AsyncTask<Bitmap, Void, Bitmap> {
private WeakReference<ImageView> imageView = null;
private @ColorInt int lineColor;
private @ColorInt int shadowUnderLineColor;
private DrawBitmapShadowAsyncTask(ImageView imageView, @ColorInt int lineColor, @ColorInt int shadowUnderLineColor){
this.imageView = new WeakReference<>(imageView);
this.lineColor = lineColor;
this.shadowUnderLineColor = shadowUnderLineColor;
}
/**
* Colorize the srcBitmap below the graph line in a Background Thread
* @param bitmaps bitmaps[0] (srcBitmap)
* @return the output bitmap
*/
@Override
protected Bitmap doInBackground(Bitmap... bitmaps) {
return getShadowLineBitmap(bitmaps[0], lineColor, shadowUnderLineColor);
}
/**
* Set the output Bitmap to imageView in Main Thread
* @param bitmap the output bitmap
*/
@Override
protected void onPostExecute(Bitmap bitmap) {
if(imageView!=null && imageView.get()!=null){
imageView.get().clearColorFilter();
imageView.get().setImageBitmap(bitmap);
}
}
/**
* Helper method to draw shadow color under the line
* @param srcBitmap The source Bitmap
* @param lineColor The color line
* @param shadowUnderLineColor The shadow color under the line
* @return Bitmap The output Bitmap
*/
private Bitmap getShadowLineBitmap(@NonNull Bitmap srcBitmap, @ColorInt int lineColor, @ColorInt int shadowUnderLineColor){
//copy the srcBitmap to the outBitmap
Bitmap outBitmap = srcBitmap.copy(srcBitmap.getConfig(), true);
try
{
//iterate each x,y pixel
for (int x = 0; x < outBitmap.getWidth(); x++) {
boolean foundLinePx = false;
for (int y = 0; y < outBitmap.getHeight(); y++) {
//get the current RGBA x,y pixel
int rgba = outBitmap.getPixel(x, y);
//if its a Transparent pixel it means that is a pixel above or below the line
//so draw the pixels above the line to Transparent and draw the pixels below the line to a red/green light color
if (rgba == Color.TRANSPARENT) {
if(foundLinePx)
outBitmap.setPixel(x, y, shadowUnderLineColor);
else
outBitmap.setPixel(x, y, rgba);
}
//if its a Non-Transparent pixel it means that is a line pixel so draw each line pixel to red/green
else {
outBitmap.setPixel(x, y, lineColor);
foundLinePx = true;
}
}
}
}catch (Exception e){
}
return outBitmap;
}
}
Recycler查看结果:
关于java - 如何为 png 图像设置ColorFilter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68881601/