Fastest way to create random pixel image I want to create a very big gigantic PNG image. The image pixel are generated randomly, being
How can I improve the below code to create a fast random pixel image in java?
import java.io.File; 
import java.io.IOException; 
import java.awt.image.BufferedImage; 
import javax.imageio.ImageIO; 
public class RandomImage 
{ 
    public static void main(String args[])throws IOException 
    { 
        // Image file dimensions 
        int width = 30000, height = 24000; 

        // Create buffered image object 
        BufferedImage img = null; 
        img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); 

        // file object 
        File f = null; 

        // create random values pixel by pixel 
        for (int y = 0; y &lt; height; y++) 
        { 
            for (int x = 0; x &lt; width; x++) 
            { 
                int a = (int)(Math.random()*256); //generating 
                int r = (int)(Math.random()*256); //values 
                int g = (int)(Math.random()*256); //less than 
                int b = (int)(Math.random()*256); //256 

                int p = (a&lt;&lt;24) | (r&lt;&lt;16) | (g&lt;&lt;8) | b; //pixel 

                img.setRGB(x, y, p); 
            } 
        } 

        // write image 
        try
        { 
            f = new File(&quot;G:\\Out.png&quot;); 
            ImageIO.write(img, &quot;png&quot;, f); 
        } 
        catch(IOException e) 
        { 
        System.out.println(&quot;Error: &quot; + e); 
        } 
    } 
}
You can write arrays of Integers directly on the WritableRaster of the BufferedImage:
public static BufferedImage createRandomImage(final int width, final int height) {
    final BufferedImage result = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);

    final long bytesPerPixel = 4L;

    final int[] pixelData = new SplittableRandom().ints(bytesPerPixel * width * height, 0, 256).toArray();

    result.getRaster().setPixels(0, 0, width, height, pixelData);

    return result;
}

This performs more than three times faster on my machine in a very crude benchmark (3.92S vs 1.26S), with the caveat that for very big images like the one you desire, you have a lot of data duplication, because you basically have to allocate twice the amount of memory, since you're writing the random data to a buffer first.
This can easily be solved by writing arrays of random Integers line by line though, which nets comparable performance:
public static BufferedImage createRandomImage(final int width, final int height) {
    final BufferedImage result = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

    final long bytesPerPixel = 4L;

    for (int y = 0; y &lt; height; y++) {
        final int[] pixelData = new SplittableRandom().ints(bytesPerPixel * width, 0, 256)
                                                      .toArray();

        result.getRaster().setPixels(0, y, width, 1, pixelData);
    }

    return result;
}

BufferedImage.setRGB is very slow, because for every pixel you set, it has to go fetch the corresponding data element:
public void setRGB(int x, int y, int rgb) {
    raster.setDataElements(x, y, colorModel.getDataElements(rgb, null));
}

which is a comparatively heavy operation.

Parallelization
Crude parallelization improves performance slightly, but it does not scale linearly with number of cores. On my 24 thread machine, the following yields a 30-40% improvement compared to the loop WritableRaster variant:
public static BufferedImage createRandomImage(final int width, final int height) {
    final BufferedImage result = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);

    final long bytesPerPixel = 4L;

    IntStream.range(0, height).parallel().forEach(y -&gt; {
        final int[] pixelData = new SplittableRandom().ints(bytesPerPixel * width, 0, 256)
                                                      .toArray();
        result.getRaster().setPixels(0, y, width, 1, pixelData);
    });

    return result;
}