如何将ColorFilter设置为png图像 [英] How to setColorFilter to a png image

查看:37
本文介绍了如何将ColorFilter设置为png图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经在使用 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:

  1. Retrieve the png image as a Bitmap (source Bitmap).
  2. Copy the source Bitmap in a temporary Bitmap (output Bitmap).
  3. 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.
  4. 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:

  1. The void onLoadStarted(@Nullable Drawable placeholder) sets the ImageView placeholder drawable when a load is started.
  2. The void onLoadFailed(@Nullable Drawable errorDrawable) sets the ImageView error drawable when a load fails.
  3. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆