title: How replace a color by another in a BufferedImage?
body: <p>What I want to do is very simple : I have an image which is basically a single color image with alpha.</p>
  
  <p><strong>EDIT :</strong> since my post has been light speed tagged as duplicate, here are the main differences with the other post :</p>
  
  <ol>
  <li>The other topic's image has several colors, mine has only one</li>
  <li>The owner accepted answer is the one I implemented... and I'm saying I have an issue with it because it's too slow</li>
  </ol>
  
  <p>It means that all pixels are either :</p>
  
  <ul>
  <li>White (255;255;255) and Transparent (0 alpha)</li>
  <li>or Black (0;0;0) and Opaque (alpha between 0 and 255)</li>
  </ul>
  
  <p>Alpha is not always the same, I have different shades of black.</p>
  
  <p>My image is produced with Photoshop with the following settings :</p>
  
  <ul>
  <li>Mode : RGB color, 8 Bits/Channel</li>
  <li>Format : PNG</li>
  <li>Compression : Smallest / Slow</li>
  <li>Interlace : None</li>
  </ul>
  
  <p>Considering it has only one color I suppose I could use other modes (such as Grayscale maybe ?) so tell me if you have suggestions about that.</p>
  
  <p>What I want to do is <strong>REPLACE</strong> the Black color by another color in my java application.</p>
  
  <p>Reading the other topics it seems that changing the ColorModel is the good thing to do, but I'm honestly totally lost on how to do it correctly.</p>
  
  <p>Here is what I did :</p>
  
  <pre><code>public Test() {
      BufferedImage image, newImage;
      IndexColorModel newModel;
  
      try {
        image = ImageIO.read(new File("E:\\MyImage.png"));
      } 
      catch (IOException e) {e.printStackTrace();}
  
      newModel = createColorModel();
      newRaster = newModel.createCompatibleWritableRaster(image.getWidth(), image.getHeight());
  
      newImage = new BufferedImage(newModel, newRaster, false, null);
      newImage.getGraphics().drawImage(image, 0, 0, null);
  }
  
  private IndexColorModel createColorModel() {
      int size = 256;
  
      byte[] r = new byte[size];
      byte[] g = new byte[size];
      byte[] b = new byte[size];
      byte[] a = new byte[size];
  
      for (int i = 0; i &lt; size; i++) {
          r[i] = (byte) 21;
          g[i] = (byte) 0;
          b[i] = (byte) 149;
          a[i] = (byte) i;
      }
  
      return new IndexColorModel(16, size, r, g, b, a);
  }
  </code></pre>
  
  <p>This produces the expected result.</p>
  
  <p>newImage is the same than image with the new color (21;0;149).</p>
  
  <p>But there is a flaw : the following line is too slow :</p>
  
  <pre><code>newImage.getGraphics().drawImage(image, 0, 0, null);
  </code></pre>
  
  <p>Doing this on a big image can take up to a few seconds, while I need this to be instantaneous.</p>
  
  <p>I'm pretty sure I'm not doing this the good way.</p>
  
  <p>Could you tell me how achieve this goal efficiently ?</p>
  
  <p>Please consider that my image will always be single color with alpha, so suggestions about image format are welcomed.</p>