Search code examples
javagraphics2d

Modifying image with Graphics2d outputs blank image


I am trying to use the Graphics2D library to add noise to a given image. For example, this: enter image description here. The issue currently is that the output file is blank. Here is my code:

BufferedImage image = ImageIO.read(new File("src/digit.png"));
BufferedImage output = new BufferedImage(28, 28, BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics2D = output.createGraphics();
Random random = new Random();
for (int i = 0; i < output.getHeight(); i++) {
  for (int j = 0; j < output.getWidth(); j++) {
    Color color = new Color(image.getRGB(j, i));
    int choice = random.nextInt(2);
    int r = color.getRed();
    int g = color.getGreen();
    int b = color.getBlue();

    int rand = random.nextInt(10);
    if (choice == 0) {
      r += rand;
      g += rand;
      b += rand;
    } else {
      r -= rand;
      g -= rand;
      b -= rand;
    }

    if (r < 0) {
      r = 0;
    }
    if (g < 0) {
      g = 0;
    }
    if (b < 0) {
      b = 0;
    }
    if (r > 255) {
      r = 255;
    }
    if (g > 255) {
      g = 255;
    }
    if (b > 255) {
      b = 255;
    }
    graphics2D.setColor(new Color(r, g, b));
    graphics2D.fillRect(j, i, 1, 1);
  }
}
File outFile = new File("output.png");
ImageIO.write(output, "png", outFile);

What is the prevailing issue with it?


Solution

  • First of all, I would like to thank @user16320675 for helping debug issues with the code and giving suggestions to make it more efficient. The problem, in the end, was that the image had transparent pixels which by default (when used to create color) was black. I instead wrote a utility function based on this post to identify transparent pixels and make them white.

    The resulting image now is: enter image description here

    Code:

    import javax.imageio.ImageIO;
    import java.awt.*;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    import java.util.Random;
    
    public class NoiseImage {
      public static void main(String[] args) throws IOException {
        BufferedImage image = ImageIO.read(new File("src/digit.png"));
        BufferedImage output = new BufferedImage(28, 28, BufferedImage.TYPE_INT_ARGB);
        Random random = new Random();
        for (int i = 0; i < output.getHeight(); i++) {
          for (int j = 0; j < output.getWidth(); j++) {
            Color color = new Color(image.getRGB(j, i), true);
            if (isTransparent(image.getRGB(j, i))) {
              color = new Color(255, 255, 255);
            }
            int choice = random.nextInt(2);
            int r = color.getRed();
            int g = color.getGreen();
            int b = color.getBlue();
            int a = color.getAlpha();
    
            int rand = random.nextInt(20);
            if (choice == 0) {
              r += rand;
              g += rand;
              b += rand;
              a += rand;
            } else {
              r -= rand;
              g -= rand;
              b -= rand;
              a -= rand;
            }
    
            r = isOutOfBounds(r);
            g = isOutOfBounds(g);
            b = isOutOfBounds(b);
            a = isOutOfBounds(a);
            output.setRGB(j, i, new Color(r, g, b, a).getRGB());
          }
        }
        File outFile = new File("output.png");
        ImageIO.write(output, "png", outFile);
      }
    
      private static int isOutOfBounds(int val) {
        if (val > 255) {
          return 255;
        }
        return Math.max(val, 0);
      }
    
      private static boolean isTransparent(int val) {
        return val >> 24 == 0x00;
      }
    }