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 < 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.