【问题标题】:How to replace color with another color in BufferedImage如何在 BufferedImage 中用另一种颜色替换颜色
【发布时间】:2015-02-12 07:01:14
【问题描述】:

所以我有一个图像文件,上面有火山。其他一切都是 0xFFFF00FF(不透明洋红色)。我想用 0(透明)替换包含该颜色的每个像素。到目前为止,我的方法如下所示:

public static BufferedImage replace(BufferedImage image, int target, int preferred) {
    int width = image.getWidth();
    int height = image.getHeight();
    BufferedImage newImage = new BufferedImage(width, height, image.getType());
    int color;

    for (int i = 0; i < width; i++) {
        for (int j = 0; j < height; j++) {
            color = image.getRGB(i, j);
            if (color == target) {
                newImage.setRGB(i, j, preferred);
            }
            else {
                newImage.setRGB(i, j, color);
            }
        }
    }

    return newImage;
}

这工作正常,但似乎很慢。我见过有人以另一种方式这样做,但我不知道发生了什么。如果有人知道更好的方法来做到这一点,我非常想听听。

【问题讨论】:

    标签: java image replace colors bufferedimage


    【解决方案1】:

    虽然我还没有机会对此进行彻底测试,但使用 LookupOp 可能会从加速中受益:

    public class ColorMapper
    extends LookupTable {
    
        private final int[] from;
        private final int[] to;
    
        public ColorMapper(Color from,
                           Color to) {
            super(0, 4);
    
            this.from = new int[] {
                from.getRed(),
                from.getGreen(),
                from.getBlue(),
                from.getAlpha(),
            };
            this.to = new int[] {
                to.getRed(),
                to.getGreen(),
                to.getBlue(),
                to.getAlpha(),
            };
        }
    
        @Override
        public int[] lookupPixel(int[] src,
                                 int[] dest) {
            if (dest == null) {
                dest = new int[src.length];
            }
    
            int[] newColor = (Arrays.equals(src, from) ? to : src);
            System.arraycopy(newColor, 0, dest, 0, newColor.length);
    
            return dest;
        }
    }
    

    使用它就像创建一个 LookupOp 一样简单:

    Color from = Color.decode("#ff00ff");
    Color to = new Color(0, true);
    BufferedImageOp lookup = new LookupOp(new ColorMapper(from, to), null);
    BufferedImage convertedImage = lookup.filter(image, null);
    

    【讨论】:

      【解决方案2】:

      为避免遍历像素,请更改底层ColorModelHere 就是一个例子。下面是作者取原始 BufferedImage 并应用新颜色模型的 sn-p。

       private static BufferedImage createImage() {
          int width = 200;
          int height = 200;
          // Generate the source pixels for our image
          // Lets just keep it to a simple blank image for now
      
          byte[] pixels = new byte[width * height];
          DataBuffer dataBuffer = new DataBufferByte(pixels, width*height, 0);
          SampleModel sampleModel = new SinglePixelPackedSampleModel(
          DataBuffer.TYPE_BYTE, width, height, new int[] {(byte)0xf});
          WritableRaster raster = Raster.createWritableRaster(
          sampleModel, dataBuffer, null);
          return new BufferedImage(createColorModel(0), raster, false, null);
      }
      
      private static ColorModel createColorModel(int n) {
          // Create a simple color model with all values mapping to
          // a single shade of gray
          // nb. this could be improved by reusing the byte arrays
      
          byte[] r = new byte[16];
          byte[] g = new byte[16];
          byte[] b = new byte[16];
          for (int i = 0; i < r.length; i++) {
              r[i] = (byte) n;
              g[i] = (byte) n;
              b[i] = (byte) n;
          }
          return new IndexColorModel(4, 16, r, g, b);
      }
      
      private BufferedImage image = createImage();
      image = new BufferedImage(createColorModel(e.getX()), image.getRaster(), false, null);
      

      【讨论】:

      • 您应该将链接中的相关代码添加到答案中。
      • 该示例只使用了一个 IndexColorModel 将每种颜色映射到灰色。如何使用颜色模型将一种颜色替换为另一种颜色?
      【解决方案3】:

      你可以像这样得到缓冲图像的pixels[]数组

      int[] pixels = ((DataBufferInt) newImg().getDataBuffer()).getData();
      

      然后像这样设置颜色

      for (int i = 0; i < width; i++) {
          for (int j = 0; j < height; j++) {
              color = pixels[y * width + x];
              if (color == target) {
                  pixels[y * width + x] = preferred;
              }
              else {
                  pixels[y * width + x] = color;
              }
          }
      }
      

      这比使用 setRGB() 稍微快了一点

      【讨论】:

        猜你喜欢
        • 2017-10-05
        • 2014-05-07
        • 2019-07-06
        • 2013-06-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-19
        • 1970-01-01
        相关资源
        最近更新 更多