在java中分配4位整数(RGBA)的32位浮点数

时间:2015-08-20 14:11:20

标签: java image image-processing

1。考虑(0.0f .. 1.0f)中的32位java float sample和(0 ... 255)中的4个32位java整数r, g, b, a一个名为RGBA的向量。

2. sample变量包含我希望以热图的形式呈现在ImageIcon中的标准化测量数据。最终RGBA值的目标是一个整数向量,稍后将其作为像素数据传递给java BufferdImage

3。约束是指sample==0.0f然后RGBA==[0,0,0,255]具有统一分布,以便sample==1.0f代表RGBA==[255,0,0,255]和{{1} }由sample==0.5f表示。 alpha通道始终为255。

4. 到目前为止,我已经使用静态方法将颜色划分为三个独立的部分R G B,而A保持静态为255.如此

RGBA==[255,255,255,255]

5. 我的问题:A)是否有合适的java api /库可以帮助我这样做? B)如果没有,那么我会向解决方案寻求建议。

6。想法:由于R,G,B,A中的每一个都在(0 ... 255)中,我假设我可以使用字节而不是整数,然后可能将这些字节转换成一个变量然后以那种方式提取浮点数。虽然到目前为止我还没有用这种方法取得任何成功。

7. 编辑:添加示例热图

Example heat map

解决:所以,像软件开发中的许多其他事情一样,这个问题也不止一个答案。在我的情况下,我想要最直接的路线与额外的工作量最少。因此,我决定采用@haraldK给出的答案。虽然如此,如果您正在寻找具有更多控制,精确性和灵活性的正式解决方案,@ SashaSalauyou提供的答案是更正确的答案。

3 个答案:

答案 0 :(得分:2)

详细说明我的评论。这并没有给出完全上面地图中的颜色,但它非常接近,非常简单:

float sample = ...; // [0...1]
float hue = (1 - sample) * .75f; // limit hue to [0...0.75] to avoid color "loop"
int rgb = Color.getHSBColor(hue, 1, 1).getRGB(); 

如果您想要在比例的“边缘”中使用较暗的色调,则可以使用正弦函数来计算亮度,例如:

float hue = (1 - sample) * .75f;
float brightness = .5f + (float) Math.sin(Math.PI * sample) / 2;
int rgb = Color.getHSBColor(hue, 1, brightness).getRGB();

答案 1 :(得分:1)

我建议在路径中进行某种插值,从0到1的值在3D颜色空间中执行:

// black: c = 0.0
// blue:  c = 0.3 
// white: c = 0.5
// red:   c = 1.0
// add more color mappings if needed, keeping c[] sorted

static float[] c = {0.0, 0.3, 0.5, 1.0};
static int[] r =   {  0,   0, 255, 255}; // red components
static int[] g =   {  0,   0, 255,   0}; // green components
static int[] b =   {  0, 255, 255,   0}; // blue components

public int[] getColor(float f) {
    int i = 0;
    while (c[i] < f) 
       i++;
    if (i == 0) 
       return new int[] {r[0], g[0], b[0]};

    // interpolate
    float k = (f - c[i-1]) / (c[i] - c[i-1]);
    return new int[] {
         Math.round((r[i] - r[i-1]) * k + r[i-1]),
         Math.round((g[i] - g[i-1]) * k + g[i-1]),
         Math.round((b[i] - b[i-1]) * k + b[i-1])
         }
    }

}

答案 2 :(得分:0)

Lerp应该这样做:

public static void main(String[] args) {
    float value = 0.5f;

    float[] red = new float[] {1.0f, 0, 0};
    float[] white = new float[] {1.0f, 1.0f, 1.0f};
    float[] black = new float[] {0, 0, 0};

    if (value <= 0.5f) {
        float gradientValue = value * 2;
        int[] color = new int[] {(int) (lerp(white[0], black[0], gradientValue) * 255), (int) (lerp(white[1], black[1], gradientValue) * 255), 
                (int) (lerp(white[2], black[2], gradientValue) * 255), 255};
    } else if (value > 0.5f) {
        float gradientValue = (value + 1) / 2.0f;
        int[] color = new int[] {(int) (lerp(white[0], red[0], gradientValue) * 255), (int) (lerp(white[1], red[1], gradientValue) * 255), 
                (int) (lerp(white[2], red[2], gradientValue) * 255), 255};
    }
}

public static float lerp(float v0, float v1, float t) {
      return (1-t)*v0 + t*v1;
}

(lerp参数的顺序可能不同,我还没有测试过)