如何将ColorFilter设置为png图像 [英] How to setColorFilter to a png image
问题描述
我已经在使用 setColorFilter() 为这些线条添加颜色.这条线的原始颜色是黄色.我使用红色或绿色取决于某些声明.
这是我目前所拥有的:有人帮我做到了这一点:
但现在我需要在线下添加颜色...像这样:
sparkline.setColorFilter(Color.RED, PorterDuff.Mode.MULTIPLY);sparkline.setImageResource(R.drawable.btc_spike);
在 RecyclerView 中使用 Glide 加载位图
我已经测试了您域中的一些图形图像链接(例如:
I am already using setColorFilter() to add color to these lines. The original color for this line is yellow. I use red or green depend on some statement.
This is what I have so far:
Someone helped me to do this:
How to set filter property in ImageView Android studio
But now I need to add color under the line...like this:
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" />
I also found this page but not sure if it wants me to add another image on top of this or something else...
https://developer.android.com/reference/android/graphics/PorterDuff.Mode#MULTIPLY
解决方案 To add a color under the line using the png image you can do something like below:
- Retrieve the png image as a Bitmap (source Bitmap).
- Copy the source Bitmap in a temporary Bitmap (output Bitmap).
- Iterate each x,y pixel of the output Bitmap and find the Line pixels (Non-Transparent pixels). The remaining Transparent pixels distinguish them to Transparent pixels above the line area and below the line area.
- Finally set the Red/Green color to the line pixels and the Red/Green light color to the Transparent pixels below the line.
Here is a helper function which does the above steps:
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;
}
And can be used like below:
//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)));
Result:
Load Bitmaps using Glide in RecyclerView
I have tested some graph image links from your domain (eg: https://s3.coinmarketcap.com/generated/sparklines/web/7d/usd/1.png) with a RecyclerView and it works as expected even if i scrolled the cells up/down.
In on void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position)
add the below lines of code to load the bitmap using Glide (Glide Version: 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) {
}
});
From above:
- The
void onLoadStarted(@Nullable Drawable placeholder)
sets the ImageView placeholder drawable when a load is started.
- The
void onLoadFailed(@Nullable Drawable errorDrawable)
sets the ImageView error drawable when a load fails.
- The
void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition)
called when the resource load has finished and the Bitmap is ready to be used. In this callback we use the previous helper function in AsyncTask to draw with light color under the graph line.
Below is the DrawBitmapShadowAsyncTask
AsyncTask private static class inside RecyclerView Adapter used from Glide onResourceReady
to draw the shadow color under the line in the Background Thread:
/**
* 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;
}
}
RecyclerView Results:
这篇关于如何将ColorFilter设置为png图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!