【问题标题】:Convert grayscale to color gradient in Java?在Java中将灰度转换为颜色渐变?
【发布时间】:2015-07-21 08:21:12
【问题描述】:

是否有任何通用算法或提供的类用于将灰度值 (0-255) 映射到颜色渐变中的值?我在想一些事情:

   public Color mapGrayscaleValue (byte value, Color[] gradientColors);

我希望这能够在我提供的灰度云覆盖雷达图像中提供更清晰的亮点。

【问题讨论】:

    标签: java image colors mapping grayscale


    【解决方案1】:

    如果您使用的是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。)

    其他一些有用的地方:

    【讨论】:

      【解决方案2】:

      想了想,我简单地创建了一个 255x1 的 BufferedImage,然后使用 GradientPaint 类为自己创建了一个颜色查找表。使用这种方法,我什至可以加载手动创建的颜色表。对于其他人:

      // 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 长度的数组,但现在这可以完成。

      如果有人知道替代或更好的方法,我总是很感兴趣。

      【讨论】:

        猜你喜欢
        • 2011-02-16
        • 2021-11-27
        • 2014-08-08
        • 1970-01-01
        • 2014-11-24
        • 2021-01-20
        • 2014-01-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多