在 Java 中将灰度转换为颜色渐变?
Convert grayscale to color gradient in Java?
是否有任何通用算法或提供的 class 用于将灰度值 (0-255) 映射到颜色渐变中的值?我在想这样的事情:
public Color mapGrayscaleValue (byte value, Color[] gradientColors);
我希望它能在我提供的灰度云覆盖雷达图像中提供更清晰的亮点。
考虑之后,我简单地创建了一个 255x1 BufferedImage,然后使用 GradientPaint class 为自己创建了一个颜色查找 table。通过这种方法,我什至可以加载手动创建的颜色 table。对于其他人:
// Set up the reference image that will be used as the color map
int width = 255;
int height = 1;
BufferedImage colorGradientImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = (Graphics2D) colorGradientImage.getGraphics();
Paint p = new LinearGradientPaint(
0, 0, width, 0, new float[] { 0.0f, 0.7f, 0.8f },
new Color[] { Color.YELLOW, Color.BLUE, Color.RED }
);
g2.setPaint(p);
g2.fillRect(0, 0, width, height);
g2.dispose();
// Now process the data, using the colour map we created above for the colour values
// pixel data is matrix of values, from 0-255
int[][] pixelData = getSourceValues();
BufferedImage myImage = new BufferedImage(pixelData[0].length, pixelData.length, BufferedImage.TYPE_INT_RGB);
for (int y=0; y<pixelData.length; y++) {
for (int x=0; x<myImage[y].length; x++) {
myImage.setRGB(x,y, colorGradientImage.getRGB(pixelData,0));
}
}
我可能已经将 colorGradientImage 转换为 255 长度的数组,但现在这样做了。
如果有人知道替代或更好的方法,我总是很感兴趣。
如果您正在使用 java.awt.image
,您应该查看 IndexColorModel
。它确实(我认为)正是您要寻找的。
您需要以某种方式为渐变生成 256 个 RGB 值并围绕它们创建模型,然后您可以使用新模型从灰度栅格创建 BufferedImage
。
这里有一个希望简单的例子:
import javax.swing.*;
import java.awt.*;
import java.awt.image.*;
import javax.imageio.*;
import java.net.*;
class ColorModelEx implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new ColorModelEx());
}
@Override
public void run() {
JFrame frame = new JFrame();
JLabel label;
try {
label = new JLabel(new ImageIcon(createImage(
Color.yellow, Color.red, Color.blue)));
} catch (Exception e) {
throw new AssertionError(e);
}
frame.add(label);
frame.pack();
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
static BufferedImage createImage(Color... colors) throws Exception {
if ((256 % (colors.length - 1)) != 0)
throw new IllegalArgumentException();
BufferedImage original =
ImageIO.read(new URL("http://i.stack.imgur.com/7bI1Y.jpg"));
final int w = original.getWidth();
final int h = original.getHeight();
BufferedImage gray =
new BufferedImage(w, h, BufferedImage.TYPE_BYTE_GRAY);
Graphics2D g2 = gray.createGraphics();
g2.drawImage(original, 0, 0, null);
byte[] r = new byte[256];
byte[] g = new byte[256];
byte[] b = new byte[256];
final int fade = (256 / (colors.length - 1));
// (generate all 256 RGB values by
// fading between the colors supplied)
for (int i = 0; i < 256; ++i) {
Color c0 = colors[(i / fade)];
Color c1 = colors[(i / fade) + 1];
float amt = (i % fade) / ((float) fade);
r[i] = getChannel(amt, c0.getRed(), c1.getRed());
g[i] = getChannel(amt, c0.getGreen(), c1.getGreen());
b[i] = getChannel(amt, c0.getBlue(), c1.getBlue());
}
// (remap same pixels to new model)
return new BufferedImage(
new IndexColorModel(8, 256, r, g, b),
gray.getRaster(), false, null);
}
static byte getChannel(float amt, int ch0, int ch1) {
return (byte)
((ch0 * (1 - amt)) + (ch1 * amt));
}
}
(图片来自here。)
其他一些有用的地方:
- Efficiently color cycling an image in Java
- Changing the ColorModel of a BufferedImage
是否有任何通用算法或提供的 class 用于将灰度值 (0-255) 映射到颜色渐变中的值?我在想这样的事情:
public Color mapGrayscaleValue (byte value, Color[] gradientColors);
我希望它能在我提供的灰度云覆盖雷达图像中提供更清晰的亮点。
考虑之后,我简单地创建了一个 255x1 BufferedImage,然后使用 GradientPaint class 为自己创建了一个颜色查找 table。通过这种方法,我什至可以加载手动创建的颜色 table。对于其他人:
// Set up the reference image that will be used as the color map
int width = 255;
int height = 1;
BufferedImage colorGradientImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = (Graphics2D) colorGradientImage.getGraphics();
Paint p = new LinearGradientPaint(
0, 0, width, 0, new float[] { 0.0f, 0.7f, 0.8f },
new Color[] { Color.YELLOW, Color.BLUE, Color.RED }
);
g2.setPaint(p);
g2.fillRect(0, 0, width, height);
g2.dispose();
// Now process the data, using the colour map we created above for the colour values
// pixel data is matrix of values, from 0-255
int[][] pixelData = getSourceValues();
BufferedImage myImage = new BufferedImage(pixelData[0].length, pixelData.length, BufferedImage.TYPE_INT_RGB);
for (int y=0; y<pixelData.length; y++) {
for (int x=0; x<myImage[y].length; x++) {
myImage.setRGB(x,y, colorGradientImage.getRGB(pixelData,0));
}
}
我可能已经将 colorGradientImage 转换为 255 长度的数组,但现在这样做了。
如果有人知道替代或更好的方法,我总是很感兴趣。
如果您正在使用 java.awt.image
,您应该查看 IndexColorModel
。它确实(我认为)正是您要寻找的。
您需要以某种方式为渐变生成 256 个 RGB 值并围绕它们创建模型,然后您可以使用新模型从灰度栅格创建 BufferedImage
。
这里有一个希望简单的例子:
import javax.swing.*;
import java.awt.*;
import java.awt.image.*;
import javax.imageio.*;
import java.net.*;
class ColorModelEx implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new ColorModelEx());
}
@Override
public void run() {
JFrame frame = new JFrame();
JLabel label;
try {
label = new JLabel(new ImageIcon(createImage(
Color.yellow, Color.red, Color.blue)));
} catch (Exception e) {
throw new AssertionError(e);
}
frame.add(label);
frame.pack();
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
static BufferedImage createImage(Color... colors) throws Exception {
if ((256 % (colors.length - 1)) != 0)
throw new IllegalArgumentException();
BufferedImage original =
ImageIO.read(new URL("http://i.stack.imgur.com/7bI1Y.jpg"));
final int w = original.getWidth();
final int h = original.getHeight();
BufferedImage gray =
new BufferedImage(w, h, BufferedImage.TYPE_BYTE_GRAY);
Graphics2D g2 = gray.createGraphics();
g2.drawImage(original, 0, 0, null);
byte[] r = new byte[256];
byte[] g = new byte[256];
byte[] b = new byte[256];
final int fade = (256 / (colors.length - 1));
// (generate all 256 RGB values by
// fading between the colors supplied)
for (int i = 0; i < 256; ++i) {
Color c0 = colors[(i / fade)];
Color c1 = colors[(i / fade) + 1];
float amt = (i % fade) / ((float) fade);
r[i] = getChannel(amt, c0.getRed(), c1.getRed());
g[i] = getChannel(amt, c0.getGreen(), c1.getGreen());
b[i] = getChannel(amt, c0.getBlue(), c1.getBlue());
}
// (remap same pixels to new model)
return new BufferedImage(
new IndexColorModel(8, 256, r, g, b),
gray.getRaster(), false, null);
}
static byte getChannel(float amt, int ch0, int ch1) {
return (byte)
((ch0 * (1 - amt)) + (ch1 * amt));
}
}
(图片来自here。)
其他一些有用的地方:
- Efficiently color cycling an image in Java
- Changing the ColorModel of a BufferedImage