Swing IOC

I wrote simple project to demonstrate how to create (desktop) UI with IOC. The structure of JForm is defined by special Spring configuration, which contains beans, named by convention. Dedicated service takes configuration, creates child context and set up window according to it. Having child context both isolates it’s beans from overall application beans and also can help to simulate web scopes if each such context will be associated with JFrame.

Also I tried to use RxSwing to bing list to an image.

SwingIOC_Example

https://github.com/dims12/SwingIOC

 

Fastest way to generate random BufferedImage (in Java)

Today I decided to generate random image for an image stub, like this:

fillrandom01

All RGB values are uniformly random here.

How to generate such image in Java?

I wrote a simple program to test:

package com.inthemoon.snippets.swing;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.awt.image.VolatileImage;
import java.io.File;
import java.io.IOException;
import java.util.Locale;
import java.util.Random;

/**
 * Created by Dims on 28.02.2017.
 */
public class FastRandomImageGenerator {

   private final static int width = 1024;
   private final static int height = 768;
   private final static int count = 1000;

   private final static Random rnd = new Random();

   private static int[] array;


   public static void main(String[] args) throws IOException {

      long start, end;
      double elapsed;
      long fps;

      BufferedImage image;
      image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
      array = new int[image.getWidth() * image.getHeight() * image.getRaster().getNumBands()];


      start = System.currentTimeMillis();
      for(int i=0; i<count; ++i) {
         fillRandom00(image);
      }
      end = System.currentTimeMillis();

      elapsed = (double)(end - start) / count;
      fps = Math.round(1000. / elapsed);

      System.out.println(String.format(Locale.US, "Elapsed: %.2f milliseconds per one fillRandom00, expected fps is %d", elapsed, fps));
      //ImageIO.write(image, "PNG", new File("fillRandom01.png"));




      start = System.currentTimeMillis();
      for(int i=0; i<count; ++i) {
         fillRandom01(image);
      }
      end = System.currentTimeMillis();

      elapsed = (double)(end - start) / count;
      fps = Math.round(1000. / elapsed);

      System.out.println(String.format(Locale.US, "Elapsed: %.2f milliseconds per one fillRandom01, expected fps is %d", elapsed, fps));
      ImageIO.write(image, "PNG", new File("fillRandom01.png"));



      start = System.currentTimeMillis();
      for(int i=0; i<count; ++i) {
         fillRandom02(image);
      }
      end = System.currentTimeMillis();

      elapsed = (double)(end - start) / count;
      fps = Math.round(1000. / elapsed);

      System.out.println(String.format(Locale.US, "Elapsed: %.2f milliseconds per one fillRandom02, expected fps is %d", elapsed, fps));
      ImageIO.write(image, "PNG", new File("fillRandom02.png"));




      start = System.currentTimeMillis();
      for(int i=0; i<count; ++i) {
         fillRandom03(image);
      }
      end = System.currentTimeMillis();

      elapsed = (double)(end - start) / count;
      fps = Math.round(1000. / elapsed);

      System.out.println(String.format(Locale.US, "Elapsed: %.2f milliseconds per one fillRandom03, expected fps is %d", elapsed, fps));
      ImageIO.write(image, "PNG", new File("fillRandom03.png"));


   }


   public static void fillRandom00(BufferedImage image) {
      for(int x=0; x<image.getWidth(); ++x) {
         for(int y=0; y<image.getHeight(); ++y) {
            rnd.nextInt(0xFFFFFF);
         }
      }
   }


   public static void fillRandom01(BufferedImage image) {
      for(int x=0; x<image.getWidth(); ++x) {
         for(int y=0; y<image.getHeight(); ++y) {
            image.setRGB(x, y, rnd.nextInt(0xFFFFFF));
         }
      }
   }


   public static void fillRandom02(BufferedImage image) {
      for(int i=0; i<array.length; ++i) {
         array[i] = rnd.nextInt(0xFF);
      }
      image.getRaster().setPixels(0, 0, image.getWidth(), image.getHeight(), array);
   }


   public static void fillRandom03(BufferedImage image) {
      int[] array = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
      for(int i=0; i<array.length; ++i) {
         array[i] = rnd.nextInt(0xFFFFFF);
      }
   }

}

“fillRandom00” method is just generating WxH number of random values.

“fillRandom01” is using straightforward method utilizing BufferedImage#setRGB()

“fillRandom02” is trying to prepare array of ints separately and bitblt them onto BufferedImage.

And the latest method “fillRandom03” is using direct access to BuffereImage data.

Output of the program is following:

Elapsed: 7.97 milliseconds per one fillRandom00, expected fps is 125
Elapsed: 32.01 milliseconds per one fillRandom01, expected fps is 31
Elapsed: 28.75 milliseconds per one fillRandom02, expected fps is 35
Elapsed: 7.90 milliseconds per one fillRandom03, expected fps is 127

As it can be expected, the latest method appeared as fastest. But surprise is that it appeared even faster, than just generating numbers. Probably, this is effect of nested loop?