একটি অঙ্কনযোগ্য হিউ সংশোধন করতে কালারম্যাট্রিক্স এবং কালারম্যাট্রিক্স কালার ফিল্টার ব্যবহার বোঝা


114

আমি একটি অ্যাপ্লিকেশনের জন্য একটি ইউআইতে কাজ করছি এবং আমি গ্রেস্কেল আইকনগুলি ব্যবহার করার চেষ্টা করছি এবং ব্যবহারকারীর থিমটি তাদের পছন্দের রঙে পরিবর্তিত করার অনুমতি দিচ্ছি। এটি করার জন্য, আমি অঙ্কনযোগ্য শীর্ষে একটি রঙ ওভারলে করতে কেবল কোনও সাজানোর রঙিন ফিল্টার প্রয়োগ করার চেষ্টা করছি। আমি পোর্টারডাফ.মোড.অনেকটি ব্যবহার করার চেষ্টা করেছি এবং এটি আমার প্রয়োজন মতো প্রায় কাজ করে, বাদে এই সাদাগুলি রঙের সাথেও আবৃত হয়। আমি আদর্শভাবে যা খুঁজছি তা হল ফটোশপের "রঙ" মিশ্রণ মোডের মতো, যেখানে গ্রাফিক তার স্বচ্ছতা এবং আলোকিতত্ব বজায় রাখে এবং কেবল চিত্রটির রঙ পরিবর্তন করে। যেমন:

বিকল্প পাঠহয়ে যায়বিকল্প পাঠ

কিছু গবেষণা করার পরে, মনে হয় যে কালারম্যাট্রিক্স কালার ফিল্টার ক্লাসটি আমার যা প্রয়োজন তা করতে পারে তবে আমি ম্যাট্রিক্স কীভাবে ব্যবহার করা হচ্ছে তার নির্দেশ করে কোনও সংস্থান খুঁজে পাচ্ছি না। এটি একটি 4x5 ম্যাট্রিক্স, তবে আমার যা জানতে হবে তা হল আমি কীভাবে ম্যাট্রিক্স ডিজাইনিং করতে যাই। কোন ধারনা?

সম্পাদনা: সুতরাং ঠিক আছে, আমি এ পর্যন্ত যা পেয়েছি তা নীচে:

1 0 0 0 0 //red
0 1 0 0 0 //green
0 0 1 0 0 //blue
0 0 0 1 0 //alpha

যেখানে এই ম্যাট্রিক্সটি পরিচয় ম্যাট্রিক্স (যখন প্রয়োগ করা হয় তখন কোনও পরিবর্তন হয় না), এবং সংখ্যাগুলি 0 থেকে 1 (ভাসমান) পর্যন্ত হয়। এই ম্যাট্রিক্সকে নতুন রঙে রূপান্তর করতে প্রতিটি পিক্সেলের সাথে গুণিত করা হবে। এটি এখান থেকেই এটি আমার কাছে অস্পষ্ট হতে শুরু করে। সুতরাং আমি ভাবব প্রতিটি পিক্সেলটি হবে 1 x 4 ভেক্টরযুক্ত আরগবি মানগুলি (যেমন 0.2, 0.5, 0.8, 1) যা রূপান্তর ম্যাট্রিক্সের সাথে বিন্দুযুক্ত। সুতরাং কোনও চিত্রের লাল তীব্রতা দ্বিগুণ করার জন্য আপনি ম্যাট্রিক্স ব্যবহার করবেন যেমন:

2 0 0 0 0 
0 1 0 0 0 
0 0 1 0 0 
0 0 0 1 0 

যা আপনাকে একটি ভেক্টর (রঙ) দেবে 0.4, 0.5, 0.8, 1। সীমাবদ্ধ পরীক্ষা থেকে, এটি মনে হয় এবং এটি সঠিকভাবে কাজ করে তবে আমি আসলে এখনও একই সমস্যাটি (যেমন সাদাগুলি রঙিন হওয়া) দিয়ে শেষ করি। আরও পড়া আমাকে বলে যে এটি আরজিবি মানগুলিতে রূপান্তর করছে কারণ হিউ শিফটিংয়ের জন্য, মানগুলি প্রথমে এইচএসএল মানগুলিতে রূপান্তর করা উচিত। সুতরাং সম্ভবত আমি এমন একটি ক্লাস লিখতে পারি যা চিত্রটি পড়বে এবং রঙগুলিকে রূপান্তরিত করবে এবং নতুন রঙের সাহায্যে চিত্রটি পুনরায় আঁকবে। এটি স্টেটলিস্টড্রেবেবলগুলির সাথে অন্য কোনও সমস্যা তৈরি করে, কারণ আমি নিশ্চিত নই যে আমি কীভাবে এই কোডগুলিতে প্রতিটি পেয়েছি এবং সেগুলির সমস্তটি সংশোধন করব, এবং এটি কতটা ধীর হবে। : /

হুম, ঠিক আছে, সুতরাং আমি মনে করি আমার আর একটি প্রশ্ন থাকবে যে ম্যাট্রিক্সটি আরবিজি কে অন্য রঙের স্থানটিতে আলোকিত তথ্যের সাথে রূপান্তর করতে ব্যবহার করা যেতে পারে যেমন এল বি বা এইচএসএল? যদি তা হয় তবে আমি সেই কথোপকথনের জন্য ম্যাট্রিক্সকে কেবল গুণতে পারি, তারপরে সেই ম্যাট্রিক্সের সাথে হ্যাস্ট অ্যাডজাস্টমেন্ট করব, তারপরে সেই ম্যাট্রিক্সটিকে কালারফিল্টার হিসাবে প্রয়োগ করুন।


উত্তর:


77

আমি আমার খেলার জন্য এটি ব্যবহার করি। এটি ওয়েবসাইটে বিভিন্ন নিবন্ধে পাওয়া বিভিন্ন অংশের সংকলন। ক্রেডিটগুলি @ লিঙ্কগুলি থেকে মূল লেখকের কাছে যায়। দ্রষ্টব্য যে রঙ ম্যাট্রিক্স দিয়ে আরও অনেক কিছু করা যায়। ইনভার্টিং ইত্যাদি সহ ...

public class ColorFilterGenerator
{
    /**
 * Creates a HUE ajustment ColorFilter
 * @see http://groups.google.com/group/android-developers/browse_thread/thread/9e215c83c3819953
 * @see http://gskinner.com/blog/archives/2007/12/colormatrix_cla.html
 * @param value degrees to shift the hue.
 * @return
 */
public static ColorFilter adjustHue( float value )
{
    ColorMatrix cm = new ColorMatrix();

    adjustHue(cm, value);

    return new ColorMatrixColorFilter(cm);
}

/**
 * @see http://groups.google.com/group/android-developers/browse_thread/thread/9e215c83c3819953
 * @see http://gskinner.com/blog/archives/2007/12/colormatrix_cla.html
 * @param cm
 * @param value
 */
public static void adjustHue(ColorMatrix cm, float value)
{
    value = cleanValue(value, 180f) / 180f * (float) Math.PI;
    if (value == 0)
    {
        return;
    }
    float cosVal = (float) Math.cos(value);
    float sinVal = (float) Math.sin(value);
    float lumR = 0.213f;
    float lumG = 0.715f;
    float lumB = 0.072f;
    float[] mat = new float[]
    { 
            lumR + cosVal * (1 - lumR) + sinVal * (-lumR), lumG + cosVal * (-lumG) + sinVal * (-lumG), lumB + cosVal * (-lumB) + sinVal * (1 - lumB), 0, 0, 
            lumR + cosVal * (-lumR) + sinVal * (0.143f), lumG + cosVal * (1 - lumG) + sinVal * (0.140f), lumB + cosVal * (-lumB) + sinVal * (-0.283f), 0, 0,
            lumR + cosVal * (-lumR) + sinVal * (-(1 - lumR)), lumG + cosVal * (-lumG) + sinVal * (lumG), lumB + cosVal * (1 - lumB) + sinVal * (lumB), 0, 0, 
            0f, 0f, 0f, 1f, 0f, 
            0f, 0f, 0f, 0f, 1f };
    cm.postConcat(new ColorMatrix(mat));
}

protected static float cleanValue(float p_val, float p_limit)
{
    return Math.min(p_limit, Math.max(-p_limit, p_val));
}
}

এটি সম্পূর্ণ করার জন্য আমার একটি উদাহরণ যুক্ত করা উচিত:

ImageView Sun = (ImageView)findViewById(R.id.sun);
Sun.setColorFilter(ColorFilterGenerator.adjustHue(162)); // 162 degree rotation

4
এটি নিশ্চিত করে যে এটি আবদ্ধের বাইরে চলে যায় না এবং কারুশিল্প তৈরি করে।
রিচার্ড ভারসাম্য

1
@ রিচার্ডলালেন্সেট আপনি কী ব্যাখ্যা করতে পারেন যে matআপনার কোডে ম্যাট্রিক্সে 5 টি সারি রয়েছে? এটি কি 4 টি সারি হওয়া উচিত নয় (প্রতিটি আরজিবিএর জন্য একটি)?
ilomambo

1
@ রিচার্ডালেন্সেটের উত্স কোডটি দেখার পরে ColorMatrix, আমি এটি আবার নিয়ে যাচ্ছি। শেষ সারিটি matকখনই ব্যবহার করা হয় না। ColorMatrixকন্সট্রাকটর শুধুমাত্র প্রথম 4 সারি (কপি দেওয়া উৎস ম্যাট্রিক্স প্রথম 20 ভাসে) লাগে।
ইলোমাম্বো

2
আমি কেবল এটি 5 তম সারি ছাড়াই পরীক্ষা করেছি এবং ফলাফলগুলি একই বলে মনে হচ্ছে।
মাইগুয়েল

2
ফ্লোট lumR = 0.213f কি কি; ভাসা lumG = 0.715f; ভাসা lumB = 0.072f; এবং কেন আপনি এই মানগুলি বেছে নিয়েছেন?
সুজয় ইউএন

43

আপনি যদি উজ্জ্বল, বৈসাদৃশ্য, স্যাচুরেশন এবং হিউ সামঞ্জস্য করতে চান তবে এখানে সম্পূর্ণ কোড। উপভোগ করুন! @ রিচার্ডালেন্সেটকে অনেক ধন্যবাদ

public class ColorFilterGenerator {

private static double DELTA_INDEX[] = {
    0,    0.01, 0.02, 0.04, 0.05, 0.06, 0.07, 0.08, 0.1,  0.11,
    0.12, 0.14, 0.15, 0.16, 0.17, 0.18, 0.20, 0.21, 0.22, 0.24,
    0.25, 0.27, 0.28, 0.30, 0.32, 0.34, 0.36, 0.38, 0.40, 0.42,
    0.44, 0.46, 0.48, 0.5,  0.53, 0.56, 0.59, 0.62, 0.65, 0.68, 
    0.71, 0.74, 0.77, 0.80, 0.83, 0.86, 0.89, 0.92, 0.95, 0.98,
    1.0,  1.06, 1.12, 1.18, 1.24, 1.30, 1.36, 1.42, 1.48, 1.54,
    1.60, 1.66, 1.72, 1.78, 1.84, 1.90, 1.96, 2.0,  2.12, 2.25, 
    2.37, 2.50, 2.62, 2.75, 2.87, 3.0,  3.2,  3.4,  3.6,  3.8,
    4.0,  4.3,  4.7,  4.9,  5.0,  5.5,  6.0,  6.5,  6.8,  7.0,
    7.3,  7.5,  7.8,  8.0,  8.4,  8.7,  9.0,  9.4,  9.6,  9.8, 
    10.0
};

/**
 * @see http://groups.google.com/group/android-developers/browse_thread/thread/9e215c83c3819953
 * @see http://gskinner.com/blog/archives/2007/12/colormatrix_cla.html
 * @param cm
 * @param value
 */
public static void adjustHue(ColorMatrix cm, float value)
{
    value = cleanValue(value, 180f) / 180f * (float) Math.PI;
    if (value == 0){
        return;
    }

    float cosVal = (float) Math.cos(value);
    float sinVal = (float) Math.sin(value);
    float lumR = 0.213f;
    float lumG = 0.715f;
    float lumB = 0.072f;
    float[] mat = new float[]
    { 
            lumR + cosVal * (1 - lumR) + sinVal * (-lumR), lumG + cosVal * (-lumG) + sinVal * (-lumG), lumB + cosVal * (-lumB) + sinVal * (1 - lumB), 0, 0, 
            lumR + cosVal * (-lumR) + sinVal * (0.143f), lumG + cosVal * (1 - lumG) + sinVal * (0.140f), lumB + cosVal * (-lumB) + sinVal * (-0.283f), 0, 0,
            lumR + cosVal * (-lumR) + sinVal * (-(1 - lumR)), lumG + cosVal * (-lumG) + sinVal * (lumG), lumB + cosVal * (1 - lumB) + sinVal * (lumB), 0, 0, 
            0f, 0f, 0f, 1f, 0f, 
            0f, 0f, 0f, 0f, 1f };
    cm.postConcat(new ColorMatrix(mat));
}

public static void adjustBrightness(ColorMatrix cm, float value) {
    value = cleanValue(value,100);
    if (value == 0) {
        return;
    }

    float[] mat = new float[]
    { 
        1,0,0,0,value,
        0,1,0,0,value,
        0,0,1,0,value,
        0,0,0,1,0,
        0,0,0,0,1
    };
    cm.postConcat(new ColorMatrix(mat));
}

public static void adjustContrast(ColorMatrix cm, int value) {
    value = (int)cleanValue(value,100);
    if (value == 0) { 
        return; 
    }
    float x;
    if (value < 0) {
        x = 127 + (float) value / 100*127;
    } else {
        x = value % 1;
        if (x == 0) {
            x = (float)DELTA_INDEX[value];
        } else {
            //x = DELTA_INDEX[(p_val<<0)]; // this is how the IDE does it.
            x = (float)DELTA_INDEX[(value<<0)]*(1-x) + (float)DELTA_INDEX[(value<<0)+1] * x; // use linear interpolation for more granularity.
        }
        x = x*127+127;
    }

    float[] mat = new float[]
    { 
            x/127,0,0,0, 0.5f*(127-x),
            0,x/127,0,0, 0.5f*(127-x),
            0,0,x/127,0, 0.5f*(127-x),
            0,0,0,1,0,
            0,0,0,0,1
    };
    cm.postConcat(new ColorMatrix(mat));

}

public static void adjustSaturation(ColorMatrix cm, float value) {
    value = cleanValue(value,100);
    if (value == 0) {
        return;
    }

    float x = 1+((value > 0) ? 3 * value / 100 : value / 100);
    float lumR = 0.3086f;
    float lumG = 0.6094f;
    float lumB = 0.0820f;

    float[] mat = new float[]
    { 
        lumR*(1-x)+x,lumG*(1-x),lumB*(1-x),0,0,
        lumR*(1-x),lumG*(1-x)+x,lumB*(1-x),0,0,
        lumR*(1-x),lumG*(1-x),lumB*(1-x)+x,0,0,
        0,0,0,1,0,
        0,0,0,0,1
    };
    cm.postConcat(new ColorMatrix(mat));
}



protected static float cleanValue(float p_val, float p_limit)
{
    return Math.min(p_limit, Math.max(-p_limit, p_val));
}

public static ColorFilter adjustColor(int brightness, int contrast, int saturation, int hue){
    ColorMatrix cm = new ColorMatrix();
    adjustHue(cm, hue);
    adjustContrast(cm, contrast);
    adjustBrightness(cm, brightness);
    adjustSaturation(cm, saturation);

    return new ColorMatrixColorFilter(cm);
}
}

কেবলমাত্র এক রঙের (নীল) জন্য স্যাচুরেশন পরিবর্তন করার জন্য এটি উপলব্ধ?
ফিলিপস্ট

"মান << 0" "মান" এর সমান
আমির উভাল

একটি মূল্যবান কোডের জন্য ধন্যবাদ। আপনার adjustContrastপদ্ধতি সম্পর্কে দুটি মন্তব্য : (1) অভিব্যক্তিটি value<<0অপ্রয়োজনীয় বলে মনে হয়, কারণ এটি সর্বদা (ন্যায়সঙ্গত) এর সমান হবে value(2)value একটি পূর্ণসংখ্যা হিসাবে , value % 1সর্বদা 0 এর সমান হয় না ?
সুখের

উজ্জ্বলতার জন্য সম্ভাব্য মান সীমাটি ভুল। এটি -255 এবং 255 এর মধ্যে হওয়া বা পরে রূপান্তরিত হওয়া উচিত।
উড়ুই

12

যে কেউ কলারম্যাট্রিক্স কালার ফিল্টার ব্যবহার করতে আগ্রহী তার জন্য। আমি এখানে যে নমুনাটি ব্যবহার করেছি, আমি ক্যানভাসে বিটম্যাপ আঁকলে প্রতিটি পিক্সেলকে লাল রূপান্তরিত করি।

শ্রেণিতে মন্তব্যটি হ'ল: http://developer.android.com/references/android/ographicics/CororMatrix.html এটি আপনাকে কীভাবে কাজ করছে তার কিছুটা অন্তর্দৃষ্টি দেয়

@Override
protected void onDraw(Canvas canvas) {

    // The matrix is stored in a single array, and its treated as follows: [ a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t ]
    // When applied to a color [r, g, b, a], the resulting color is computed as (after clamping) ;
    //   R' = a*R + b*G + c*B + d*A + e; 
    //   G' = f*R + g*G + h*B + i*A + j; 
    //   B' = k*R + l*G + m*B + n*A + o; 
    //   A' = p*R + q*G + r*B + s*A + t; 

    Paint paint = new Paint();
    float[] matrix = { 
        1, 1, 1, 1, 1, //red
        0, 0, 0, 0, 0, //green
        0, 0, 0, 0, 0, //blue
        1, 1, 1, 1, 1 //alpha
    };
    paint.setColorFilter(new ColorMatrixColorFilter(matrix));

    Rect source = new Rect(0, 0, 100, 100);
    Rect dest = new Rect(0, 0, 100, 100);

    Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.sampleimage);
    canvas.drawBitmap(bitmap , source, dest, paint);
}

আপনার কোডটি আমার ক্ষেত্রে পুরোপুরি কাজ করেছে, যেখানে আমাকে কিছু পিএনজি রঙ করার দরকার ছিল: gist.github.com/puelocesar/9710910 - আপনাকে ধন্যবাদ!
পাওলো সিজার

9

নীচের শ্রেণিটি ইতিমধ্যে পোস্ট করা উত্তরগুলির উন্নতি is এটি একটি ColorFilterথেকে পড়া এবং তৈরি করা সহজ করে Bitmap

ব্যবহারের উদাহরণ:

ImageView imageView = ...;
Drawable drawable = imageView.getDrawable();
ColorFilter colorFilter = ColorFilterGenerator.from(drawable).to(Color.RED);
imageView.setColorFilter(colorFilter);

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.PictureDrawable;
import android.widget.ImageView;

/**
 * Creates a {@link ColorMatrixColorFilter} to adjust the hue, saturation, brightness, or
 * contrast of an {@link Bitmap}, {@link Drawable}, or {@link ImageView}.
 * <p/>
 * Example usage:
 * <br/>
 * {@code imageView.setColorFilter(ColorFilterGenerator.from(Color.BLUE).to(Color.RED));}
 *
 * @author Jared Rummler <jared.rummler@gmail.com>
 */
public class ColorFilterGenerator {

  // Based off answer from StackOverflow
  // See: http://stackoverflow.com/a/15119089/1048340

  private ColorFilterGenerator() {
    throw new AssertionError();
  }

  public static From from(Drawable drawable) {
    return new From(drawableToBitmap(drawable));
  }

  public static From from(Bitmap bitmap) {
    return new From(bitmap);
  }

  public static From from(int color) {
    return new From(color);
  }

  // --------------------------------------------------------------------------------------------

  private static final double DELTA_INDEX[] = {
      0, 0.01, 0.02, 0.04, 0.05, 0.06, 0.07, 0.08, 0.1, 0.11, 0.12, 0.14, 0.15, 0.16, 0.17, 0.18,
      0.20, 0.21, 0.22, 0.24, 0.25, 0.27, 0.28, 0.30, 0.32, 0.34, 0.36, 0.38, 0.40, 0.42, 0.44,
      0.46, 0.48, 0.5, 0.53, 0.56, 0.59, 0.62, 0.65, 0.68, 0.71, 0.74, 0.77, 0.80, 0.83, 0.86, 0.89,
      0.92, 0.95, 0.98, 1.0, 1.06, 1.12, 1.18, 1.24, 1.30, 1.36, 1.42, 1.48, 1.54, 1.60, 1.66, 1.72,
      1.78, 1.84, 1.90, 1.96, 2.0, 2.12, 2.25, 2.37, 2.50, 2.62, 2.75, 2.87, 3.0, 3.2, 3.4, 3.6,
      3.8, 4.0, 4.3, 4.7, 4.9, 5.0, 5.5, 6.0, 6.5, 6.8, 7.0, 7.3, 7.5, 7.8, 8.0, 8.4, 8.7, 9.0, 9.4,
      9.6, 9.8, 10.0
  };

  public static void adjustHue(ColorMatrix cm, float value) {
    value = cleanValue(value, 180f) / 180f * (float) Math.PI;
    if (value == 0) {
      return;
    }

    float cosVal = (float) Math.cos(value);
    float sinVal = (float) Math.sin(value);
    float lumR = 0.213f;
    float lumG = 0.715f;
    float lumB = 0.072f;
    float[] mat = new float[]{
        lumR + cosVal * (1 - lumR) + sinVal * (-lumR),
        lumG + cosVal * (-lumG) + sinVal * (-lumG),
        lumB + cosVal * (-lumB) + sinVal * (1 - lumB), 0, 0,
        lumR + cosVal * (-lumR) + sinVal * (0.143f),
        lumG + cosVal * (1 - lumG) + sinVal * (0.140f),
        lumB + cosVal * (-lumB) + sinVal * (-0.283f), 0, 0,
        lumR + cosVal * (-lumR) + sinVal * (-(1 - lumR)),
        lumG + cosVal * (-lumG) + sinVal * (lumG),
        lumB + cosVal * (1 - lumB) + sinVal * (lumB), 0, 0, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 0f,
        0f, 1f
    };
    cm.postConcat(new ColorMatrix(mat));
  }

  public static void adjustBrightness(ColorMatrix cm, float value) {
    value = cleanValue(value, 100);
    if (value == 0) {
      return;
    }

    float[] mat = new float[]{
        1, 0, 0, 0, value, 0, 1, 0, 0, value, 0, 0, 1, 0, value, 0, 0, 0, 1, 0, 0, 0, 0, 0,
        1
    };
    cm.postConcat(new ColorMatrix(mat));
  }

  public static void adjustContrast(ColorMatrix cm, int value) {
    value = (int) cleanValue(value, 100);
    if (value == 0) {
      return;
    }
    float x;
    if (value < 0) {
      x = 127 + value / 100 * 127;
    } else {
      x = value % 1;
      if (x == 0) {
        x = (float) DELTA_INDEX[value];
      } else {
        x = (float) DELTA_INDEX[(value << 0)] * (1 - x)
            + (float) DELTA_INDEX[(value << 0) + 1] * x;
      }
      x = x * 127 + 127;
    }

    float[] mat = new float[]{
        x / 127, 0, 0, 0, 0.5f * (127 - x), 0, x / 127, 0, 0, 0.5f * (127 - x), 0, 0,
        x / 127, 0, 0.5f * (127 - x), 0, 0, 0, 1, 0, 0, 0, 0, 0, 1
    };
    cm.postConcat(new ColorMatrix(mat));

  }

  public static void adjustSaturation(ColorMatrix cm, float value) {
    value = cleanValue(value, 100);
    if (value == 0) {
      return;
    }

    float x = 1 + ((value > 0) ? 3 * value / 100 : value / 100);
    float lumR = 0.3086f;
    float lumG = 0.6094f;
    float lumB = 0.0820f;

    float[] mat = new float[]{
        lumR * (1 - x) + x, lumG * (1 - x), lumB * (1 - x), 0, 0, lumR * (1 - x),
        lumG * (1 - x) + x, lumB * (1 - x), 0, 0, lumR * (1 - x), lumG * (1 - x),
        lumB * (1 - x) + x, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1
    };
    cm.postConcat(new ColorMatrix(mat));
  }

  // --------------------------------------------------------------------------------------------

  private static float cleanValue(float p_val, float p_limit) {
    return Math.min(p_limit, Math.max(-p_limit, p_val));
  }

  private static float[] getHsv(int color) {
    float[] hsv = new float[3];
    Color.RGBToHSV(Color.red(color), Color.green(color), Color.blue(color), hsv);
    return hsv;
  }

  /**
   * Converts a {@link Drawable} to a {@link Bitmap}
   *
   * @param drawable
   *     The {@link Drawable} to convert
   * @return The converted {@link Bitmap}.
   */
  private static Bitmap drawableToBitmap(Drawable drawable) {
    if (drawable instanceof BitmapDrawable) {
      return ((BitmapDrawable) drawable).getBitmap();
    } else if (drawable instanceof PictureDrawable) {
      PictureDrawable pictureDrawable = (PictureDrawable) drawable;
      Bitmap bitmap = Bitmap.createBitmap(pictureDrawable.getIntrinsicWidth(),
          pictureDrawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
      Canvas canvas = new Canvas(bitmap);
      canvas.drawPicture(pictureDrawable.getPicture());
      return bitmap;
    }
    int width = drawable.getIntrinsicWidth();
    width = width > 0 ? width : 1;
    int height = drawable.getIntrinsicHeight();
    height = height > 0 ? height : 1;
    Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
    drawable.draw(canvas);
    return bitmap;
  }

  /**
   * Calculate the average red, green, blue color values of a bitmap
   *
   * @param bitmap
   *     a {@link Bitmap}
   * @return
   */
  private static int[] getAverageColorRGB(Bitmap bitmap) {
    int width = bitmap.getWidth();
    int height = bitmap.getHeight();
    int size = width * height;
    int[] pixels = new int[size];
    int r, g, b;
    r = g = b = 0;
    bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
    for (int i = 0; i < size; i++) {
      int pixelColor = pixels[i];
      if (pixelColor == Color.TRANSPARENT) {
        size--;
        continue;
      }
      r += Color.red(pixelColor);
      g += Color.green(pixelColor);
      b += Color.blue(pixelColor);
    }
    r /= size;
    g /= size;
    b /= size;
    return new int[]{
        r, g, b
    };
  }

  /**
   * Calculate the average color value of a bitmap
   *
   * @param bitmap
   *     a {@link Bitmap}
   * @return
   */
  private static int getAverageColor(Bitmap bitmap) {
    int[] rgb = getAverageColorRGB(bitmap);
    return Color.argb(255, rgb[0], rgb[1], rgb[2]);
  }

  // Builder
  // --------------------------------------------------------------------------------------------

  public static final class Builder {

    int hue;

    int contrast;

    int brightness;

    int saturation;

    public Builder setHue(int hue) {
      this.hue = hue;
      return this;
    }

    public Builder setContrast(int contrast) {
      this.contrast = contrast;
      return this;
    }

    public Builder setBrightness(int brightness) {
      this.brightness = brightness;
      return this;
    }

    public Builder setSaturation(int saturation) {
      this.saturation = saturation;
      return this;
    }

    public ColorFilter build() {
      ColorMatrix cm = new ColorMatrix();
      adjustHue(cm, hue);
      adjustContrast(cm, contrast);
      adjustBrightness(cm, brightness);
      adjustSaturation(cm, saturation);
      return new ColorMatrixColorFilter(cm);
    }
  }

  public static final class From {

    final int oldColor;

    private From(Bitmap bitmap) {
      oldColor = getAverageColor(bitmap);
    }

    private From(int oldColor) {
      this.oldColor = oldColor;
    }

    public ColorFilter to(int newColor) {
      float[] hsv1 = getHsv(oldColor);
      float[] hsv2 = getHsv(newColor);
      int hue = (int) (hsv2[0] - hsv1[0]);
      int saturation = (int) (hsv2[1] - hsv1[1]);
      int brightness = (int) (hsv2[2] - hsv1[2]);
      return new ColorFilterGenerator.Builder()
          .setHue(hue)
          .setSaturation(saturation)
          .setBrightness(brightness)
          .build();
    }
  }

}

8

হিউ এবং আরজিবির মধ্যে কোনও রৈখিক সম্পর্ক নেই। হিউ 60 ° অংশে ( http://en.wikedia.org/wiki/HSL_color_space# জেনারাল_অ্যাপ্রোচ ) বিভক্ত হিসাবে সংজ্ঞায়িত করা হয়েছে , এবং এইচএসভি এবং আরজিবি-র মধ্যে কোনও সাধারণ ম্যাট্রিক্স রূপান্তর নেই। কোনও চিত্রের রঙ পরিবর্তন করতে, আপনি নিম্নলিখিত পদ্ধতিটি ব্যবহার করতে পারেন:

public Bitmap changeHue( Bitmap source, double hue ) {
    Bitmap result = Bitmap.createBitmap( source.getWidth(), source.getHeight(), source.getConfig() );

    float[] hsv = new float[3];
    for( int x = 0; x < source.getWidth(); x++ ) {
        for( int y = 0; y < source.getHeight(); y++ ) {
            int c = source.getPixel( x, y );
            Color.colorToHSV( c, hsv );
            hsv[0] = (float) ((hsv[0] + 360 * hue) % 360);
            c = (Color.HSVToColor( hsv ) & 0x00ffffff) | (c & 0xff000000);
            result.setPixel( x, y, c );
        }
    }

    return result;
}

7

আমি মনে করি এই পদ্ধতিটি আপনাকে যা দেবে তা দেবে:

http://android.okhelp.cz/hue-color-colored-filter-bitmap-image-android-example/

bitmapOrg.setColorFilter(Color.RED, PorterDuff.Mode.MULTIPLY);

1
দ্রষ্টব্য, এই পদ্ধতিটি উপরে বর্ণিত কালারফিল্টার জেনারেটর পদ্ধতিগুলির মতো হিউ পরিবর্তন করবে না। ফটোশপ বা জিআইএমপিতে এটি কীভাবে আপনার বিটম্যাপটি খুলতে পারে তা দেখতে। চিত্রের উপরে একটি স্তর তৈরি করুন এবং এটি আপনার পছন্দসই রঙ দিয়ে পূর্ণ করুন। তারপরে ওভারলেয়ের স্তর মোডটি গুণতে করুন। কালারফিল্টার জেনারেটর পদ্ধতিগুলি কী করবে তা প্রাকদর্শন করতে লেয়ার মোডটি দেখুন।
কেভিন মার্ক

6

অন্যান্য উত্তরের মতো এই আচরণটি বাস্তবায়নের জন্য আমি একটি রঙের ম্যাট্রিক্স ব্যবহার করেছি তবে আপনি একটি নিয়মিত অ্যান্ড্রয়েড রঙের সংস্থানতে যেতে পারেন। ম্যাট্রিক্স, রঙটির চিত্র মান এবং সাদা এর মধ্যে একটি সীমার মধ্যে মানচিত্র দেয়।

/**
 * Color everything that isn't white, the tint color
 * @param tintColor the color to tint the icon
 */
public void setInverseMultiplyFilter(Drawable imgCopy, @ColorInt int tintColor) {

    Drawable imgCopy = imageView.getDrawable().getConstantState().newDrawable();

    float colorRed = Color.red(tintColor) / 255f;
    float colorGreen = Color.green(tintColor) / 255f;
    float colorBlue = Color.blue(tintColor) / 255f;

    imgCopy.setColorFilter(new ColorMatrixColorFilter(new ColorMatrix(new float[]{
            1 - colorRed, 0,              0,             0,     colorRed * 255,
            0,            1 - colorGreen, 0,             0,     colorGreen * 255,
            0,            0,              1 - colorBlue, 0,     colorBlue * 255,
            0,            0,              0,             Color.alpha(tintColor) / 255f, 0,
    })));

    imageView.setImageDrawable(imgCopy);
    imageView.invalidate();
}

হ্যালো বেঞ্জামিন, উপরের ম্যাট্রিক্স ব্যবহার করে আমরা কি সবুজ বাদে সব কিছু ছড়াতে পারি? এবং এছাড়াও আমরা সংরক্ষণ করার জন্য একাধিক রঙ একত্রিত করতে পারি? উদাহরণস্বরূপ সাদা এবং সবুজ সংরক্ষণ করুন, রঙিন বিশ্রাম। দয়া করে আপনার উত্তরটি আমাকে সহায়তা করবে
ব্যবহারকারী 954299

2

আমি নীচের স্নিপেটের উপর ভিত্তি করে একটি সামান্য কালারম্যাট্রিক্স ফিল্টার পরীক্ষক তৈরি করেছি:

private Bitmap setColorFilter(Bitmap drawable) {                
            Bitmap grayscale  = Bitmap.createBitmap(drawable.getWidth(), drawable.getHeight(), drawable.getConfig());
            //if(isRenderMode) bOriginal.recycle();
            Canvas c = new Canvas(grayscale );
            Paint p = new Paint();

            final ColorMatrix matrixA = new ColorMatrix();
            matrixA.setSaturation(sauturationValue/2);


            float[] mx = {
                    r1Value,  r2Value,  r3Value,  r4Value,  r5Value,
                    g1Value,  g2Value,  g3Value,  g4Value,  g5Value,
                    b1Value,  b2Value,  b3Value,  b4Value,  b5Value,
                    a1Value,  a2Value,  a3Value,  a4Value,  a5Value
                    };
                    final ColorMatrix matrixB = new ColorMatrix(mx);

            matrixA.setConcat(matrixB, matrixA);

            final ColorMatrixColorFilter filter = new ColorMatrixColorFilter(matrixA);
            p.setColorFilter(filter);
            c.drawBitmap(drawable, 0, 0, p);
            return grayscale;               
        } 

আপনি এটি এখানে পরীক্ষা করতে পারেন: https://play.google.com/store/apps/details?id=org.vaelostudio.colormatrixtester


1

যদিও দরকারী প্রভাব অনেকটা ব্যবহার করে অর্জন করা সম্ভব ColorMatrixআমি ব্যক্তিগতভাবে একটি ব্যবহারের বিষয়ে বিবেচনা করবে ColorMap[]বরাবর ImageAttributes। এটি করার মাধ্যমে আমরা সংজ্ঞা দিতে পারি যে কোন রঙগুলির সাথে কোন রঙগুলি প্রতিস্থাপন করা উচিত।


কি ColorMap? আমি মনে করি স্ট্যান্ডার্ড জাভা / অ্যান্ড্রয়েড লিবসে এরকম কোনও শ্রেণি নেই।
ǝlǝ

1

আমি যেভাবে সমাধান করেছি তা হল ধূসর স্কেল চিত্রের সাথে শুরু করা।

আসল ---> গ্রে আইমেজ

আপনি ফটোশপে এটি সহজেই করতে পারেন, বা কোডটি কোড করার দরকার হলে আপনি নীচের পদ্ধতিটি ব্যবহার করতে পারেন।

private fun changeImageToGreyScale() {
   val matrix = ColorMatrix()
   matrix.setSaturation(0f)

   val originalBitmap = BitmapFactory.decodeResource(resources, originalImageID)
   val bitmapCopy = Bitmap.createBitmap(originalBitmap.width, 
   originalBitmap.height, Bitmap.Config.ARGB_8888)
   val canvas = Canvas(bitmapCopy)

   val paint = Paint()
   val colorFilter = ColorMatrixColorFilter(matrix)
   paint.colorFilter = colorFilter
   canvas.drawBitmap(originalBitmap, 0f, 0f, paint)
   grayScaleImage = bitmapCopy
}

আপনার ধূসর স্কেল চিত্রটি পরে আপনি পছন্দসই রঙ যুক্ত করতে পোর্টারডাফ ওভারলে মোড ব্যবহার করতে পারেন।

private fun applyFilterToImage() {

    val bitmapCopy = Bitmap.createBitmap(grayScaleImage.width, grayScaleImage.height, Bitmap.Config.ARGB_8888)
    val canvas = Canvas(bitmapCopy)

    val rnd = java.util.Random()
    val randomColor = Color.rgb(rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256))

    val paint = Paint()
    val porterDuffMode = PorterDuff.Mode.OVERLAY
    paint.colorFilter = PorterDuffColorFilter(randomColor, porterDuffMode)

    val maskPaint = Paint()
    maskPaint. xfermode = PorterDuffXfermode(PorterDuff.Mode.DST_ATOP)

    canvas.drawBitmap(grayScaleImage, 0f, 0f, paint) 

    /**
    Note OVERLAY will disregard the alpha channel and will turn transparent 
    pixels into the randomColor. To resolve this I clip out that transparent area by 
    drawing the image again with the DST_ATOP XferMode
    **/
    canvas.drawBitmap(grayScaleImage, 0f, 0f, maskPaint)

    imageView.setImageBitmap(bitmapCopy)
}

উপরোক্ত ফলাফলটি নীচে র্যান্ডম কালারজিফ হিসাবে রয়েছে

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.