Как программно получить список цветов из градиента на Android - PullRequest
7 голосов
/ 15 октября 2011

в Android Я хотел бы нарисовать круговую диаграмму с динамическим числом пирогов.Каждый пирог должен иметь цвет, отличный от градиента.

Например, я хотел бы иметь градиент от светло-коричневого до темно-коричневого.Если мне нужно нарисовать пять пирогов, мне нужно пять волов от начала до конца этого градиента.

Как я могу сделать это в Java с платформой Android?

Я обнаружил, чтоЯ могу создать LinearGradient для линии, например:

LinearGradient lg = new LinearGradient(1, 1, 5, 5, toRGB("lightbrown"), toRGB("darkbrown"), TileMode.REPEAT);

Но я не нашел ни одной функции для получения цвета из этой линии, например:

// for the five needed RGB colors from the gradient line
lg.getRGBColor(1, 1);
lg.getRGBColor(2, 2);
lg.getRGBColor(3, 3);
lg.getRGBColor(4, 4);
lg.getRGBColor(5, 5);

Есть ли у вас какие-либоидеи, как я могу получить это?

Спасибо!

Ответы [ 3 ]

17 голосов
/ 15 октября 2011

Вы не можете получить эти значения непосредственно из LinearGradient. Градиент не содержит фактического рисунка. Чтобы получить эти значения, вы можете нарисовать их на холсте и вытянуть цвета из холста, или я бы посоветовал рассчитать значения самостоятельно.

Это повторяющийся линейный градиент за пять шагов, и у вас есть значения RGB для первого и последнего цвета. Остальное просто математика. Вот псевдокод:

int r1 = startColor.red;
int g1 = startColor.green;
int b1 = startColor.blue;

int r2 = endColor.red;
int g2 = endColor.green;
int b2 = endColor.blue;

int redStep = r2 - r1 / 4;
int greenStep = g2 - g1 / 4;
int blueStep = b2 - b1 / 4;

firstColor = new Color(r1, g1, b1);
secondColor = new Color(r1 + redStep, g1 + greenStep, b1 + blueStep);
thirdColor = new Color(r1 + redStep * 2, g1 + greenStep * 2, b1 + blueStep * 2);
fourthColor = new Color(r1 + redStep * 3, g1 + greenStep * 3, b1 + blueStep * 3);
fifthColor = new Color(r1 + redStep * 4, g1 + greenStep * 4, b1 + blueStep * 4);
5 голосов
/ 15 января 2017

Еще один подход, который можно использовать несколько раз (кажется, я сталкиваюсь с этой проблемой все время). Это немного больше кода. Вот использование:

    int[] colors = {toRGB("lightbrown"), toRGB("darkbrown")};//assuming toRGB : String -> Int
    float[] positions = {1, 5};
    getColorFromGradient( colors, positions, 1 )
    //...
    getColorFromGradient( colors, positions, 5 )

Вспомогательные функции

public static int getColorFromGradient(int[] colors, float[] positions, float v ){

    if( colors.length == 0 || colors.length != positions.length ){
        throw new IllegalArgumentException();
    }

    if( colors.length == 1 ){
        return colors[0];
    }

    if( v <= positions[0]) {
        return colors[0];
    }

    if( v >= positions[positions.length-1]) {
        return colors[positions.length-1];
    }

    for( int i = 1; i < positions.length; ++i ){
        if( v <= positions[i] ){
            float t = (v - positions[i-1]) / (positions[i] - positions[i-1]);
            return lerpColor(colors[i-1], colors[i], t);
        }
    }

    //should never make it here
    throw new RuntimeException();
}

public static int lerpColor( int colorA, int colorB, float t){
    int alpha = (int)Math.floor(Color.alpha(colorA) * ( 1 - t ) + Color.alpha(colorB) * t);
    int red   = (int)Math.floor(Color.red(colorA)   * ( 1 - t ) + Color.red(colorB)   * t);
    int green = (int)Math.floor(Color.green(colorA) * ( 1 - t ) + Color.green(colorB) * t);
    int blue  = (int)Math.floor(Color.blue(colorA)  * ( 1 - t ) + Color.blue(colorB)  * t);

    return Color.argb(alpha, red, green, blue);
}
0 голосов
/ 24 февраля 2019

Я написал класс util для вычисления градиента цветов.

через очень, очень простой код Котлина:

    val pink = Colar(245, 9, 253)
    val lime = Colar(0, 253, 32)

    lp_1.colors = (pink toColor lime).run {
        gradient { 0 upTo 3 }
    }

    lp_2.colors = (pink toColor lime).run {
        gradient { 0 upTo 9 }
    }

    lp_3.colors = (pink toColor lime).run {
        gradient { 3 upTo 9}
    }

enter image description here

Вспомогательный класс утилит

 class StepGradientUtil(private var colar1: Colar?, private var colar2: Colar?) {

    private var mSteps: Int = 0

    infix fun StepGradientUtil.gradient(f: () -> IntRange): IntArray {
        val result = f.invoke().map {
            it.colorStep()
        }.toIntArray()
        recycler()
        return result
    }

    infix fun Int.upTo(steps: Int): IntRange {
        mSteps = steps
        return (this until steps)
    }

    private fun recycler() {
        mSteps = 0
        colar1 = null
        colar2 = null
    }

    private fun Int.colorStep() = Color.rgb(
        (colar1!!.r * (mSteps - this) + colar2!!.r * this) / mSteps,
        (colar1!!.g * (mSteps - this) + colar2!!.g * this) / mSteps,
        (colar1!!.b * (mSteps - this) + colar2!!.b * this) / mSteps
    )
}

data class Colar(
    val r: Int,
    val g: Int,
    val b: Int
)

infix fun Colar.toColor(colar: Colar) = StepGradientUtil(colar1 = this, colar2 = colar)

См. полный пример исходного кода при репо

...