javaimageopencvswt

Display IplImage (JavaCV) on an SWT canvas


I'm using JavaCV for a university project. It is essentially a motion detector.

I use the OpenCVFrameGrabber class to get the frames from a webcam and I want to display the grabbed frames on my GUI.

I'm using SWT and I thought it would be good to display the frames into a Canvas component. I have a problem because the OpenCVFrameGrabber provides images as instances of the IplImage class and SWT uses org.eclipse.swt.graphics.Image image class.

So I should convert the image someway from IplImage to SWT Image. What is the best way to do this?


Solution

  • I recently converted BufferedImages (AWT) to SWT Image Objects. I made use of the following snippet: java2s.com

    Maybe the code gets you started. Or someone already converted IplImages to BufferedImages, and you could "pipe" these two conversion methods.

    /*
     * example snippet: convert between SWT Image and AWT BufferedImage
     *
     * For a list of all SWT example snippets see
     * http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/platform-swt-home/dev.html#snippets
     */
    import java.awt.Frame;
    import java.awt.Graphics;
    import java.awt.Insets;
    import java.awt.image.BufferedImage;
    import java.awt.image.ColorModel;
    import java.awt.image.DirectColorModel;
    import java.awt.image.IndexColorModel;
    import java.awt.image.WritableRaster;
    
    import org.eclipse.swt.SWT;
    import org.eclipse.swt.graphics.GC;
    import org.eclipse.swt.graphics.Image;
    import org.eclipse.swt.graphics.ImageData;
    import org.eclipse.swt.graphics.PaletteData;
    import org.eclipse.swt.graphics.Point;
    import org.eclipse.swt.graphics.RGB;
    import org.eclipse.swt.graphics.Rectangle;
    import org.eclipse.swt.widgets.Display;
    import org.eclipse.swt.widgets.Event;
    import org.eclipse.swt.widgets.Listener;
    import org.eclipse.swt.widgets.Shell;
    
    public class Snippet156 {
    
      static BufferedImage convertToAWT(ImageData data) {
        ColorModel colorModel = null;
        PaletteData palette = data.palette;
        if (palette.isDirect) {
          colorModel = new DirectColorModel(data.depth, palette.redMask,
              palette.greenMask, palette.blueMask);
          BufferedImage bufferedImage = new BufferedImage(colorModel,
              colorModel.createCompatibleWritableRaster(data.width,
                  data.height), false, null);
          WritableRaster raster = bufferedImage.getRaster();
          int[] pixelArray = new int[3];
          for (int y = 0; y < data.height; y++) {
            for (int x = 0; x < data.width; x++) {
              int pixel = data.getPixel(x, y);
              RGB rgb = palette.getRGB(pixel);
              pixelArray[0] = rgb.red;
              pixelArray[1] = rgb.green;
              pixelArray[2] = rgb.blue;
              raster.setPixels(x, y, 1, 1, pixelArray);
            }
          }
          return bufferedImage;
        } else {
          RGB[] rgbs = palette.getRGBs();
          byte[] red = new byte[rgbs.length];
          byte[] green = new byte[rgbs.length];
          byte[] blue = new byte[rgbs.length];
          for (int i = 0; i < rgbs.length; i++) {
            RGB rgb = rgbs[i];
            red[i] = (byte) rgb.red;
            green[i] = (byte) rgb.green;
            blue[i] = (byte) rgb.blue;
          }
          if (data.transparentPixel != -1) {
            colorModel = new IndexColorModel(data.depth, rgbs.length, red,
                green, blue, data.transparentPixel);
          } else {
            colorModel = new IndexColorModel(data.depth, rgbs.length, red,
                green, blue);
          }
          BufferedImage bufferedImage = new BufferedImage(colorModel,
              colorModel.createCompatibleWritableRaster(data.width,
                  data.height), false, null);
          WritableRaster raster = bufferedImage.getRaster();
          int[] pixelArray = new int[1];
          for (int y = 0; y < data.height; y++) {
            for (int x = 0; x < data.width; x++) {
              int pixel = data.getPixel(x, y);
              pixelArray[0] = pixel;
              raster.setPixel(x, y, pixelArray);
            }
          }
          return bufferedImage;
        }
      }
    
      static ImageData convertToSWT(BufferedImage bufferedImage) {
        if (bufferedImage.getColorModel() instanceof DirectColorModel) {
          DirectColorModel colorModel = (DirectColorModel) bufferedImage
              .getColorModel();
          PaletteData palette = new PaletteData(colorModel.getRedMask(),
              colorModel.getGreenMask(), colorModel.getBlueMask());
          ImageData data = new ImageData(bufferedImage.getWidth(),
              bufferedImage.getHeight(), colorModel.getPixelSize(),
              palette);
          WritableRaster raster = bufferedImage.getRaster();
          int[] pixelArray = new int[3];
          for (int y = 0; y < data.height; y++) {
            for (int x = 0; x < data.width; x++) {
              raster.getPixel(x, y, pixelArray);
              int pixel = palette.getPixel(new RGB(pixelArray[0],
                  pixelArray[1], pixelArray[2]));
              data.setPixel(x, y, pixel);
            }
          }
          return data;
        } else if (bufferedImage.getColorModel() instanceof IndexColorModel) {
          IndexColorModel colorModel = (IndexColorModel) bufferedImage
              .getColorModel();
          int size = colorModel.getMapSize();
          byte[] reds = new byte[size];
          byte[] greens = new byte[size];
          byte[] blues = new byte[size];
          colorModel.getReds(reds);
          colorModel.getGreens(greens);
          colorModel.getBlues(blues);
          RGB[] rgbs = new RGB[size];
          for (int i = 0; i < rgbs.length; i++) {
            rgbs[i] = new RGB(reds[i] & 0xFF, greens[i] & 0xFF,
                blues[i] & 0xFF);
          }
          PaletteData palette = new PaletteData(rgbs);
          ImageData data = new ImageData(bufferedImage.getWidth(),
              bufferedImage.getHeight(), colorModel.getPixelSize(),
              palette);
          data.transparentPixel = colorModel.getTransparentPixel();
          WritableRaster raster = bufferedImage.getRaster();
          int[] pixelArray = new int[1];
          for (int y = 0; y < data.height; y++) {
            for (int x = 0; x < data.width; x++) {
              raster.getPixel(x, y, pixelArray);
              data.setPixel(x, y, pixelArray[0]);
            }
          }
          return data;
        }
        return null;
      }
    
      static ImageData createSampleImage(Display display) {
        Image image = new Image(display, 100, 100);
        Rectangle bounds = image.getBounds();
        GC gc = new GC(image);
        gc.setBackground(display.getSystemColor(SWT.COLOR_BLUE));
        gc.fillRectangle(bounds);
        gc.setBackground(display.getSystemColor(SWT.COLOR_GREEN));
        gc.fillOval(0, 0, bounds.width, bounds.height);
        gc.setForeground(display.getSystemColor(SWT.COLOR_RED));
        gc.drawLine(0, 0, bounds.width, bounds.height);
        gc.drawLine(bounds.width, 0, 0, bounds.height);
        gc.dispose();
        ImageData data = image.getImageData();
        image.dispose();
        return data;
      }
    
      public static void main(String[] args) {
        Display display = new Display();
        Shell shell = new Shell(display);
        shell.setText("SWT Image");
        ImageData data;
        if (args.length > 0) {
          String fileName = args[0];
          data = new ImageData(fileName);
        } else {
          data = createSampleImage(display);
        }
        final Image swtImage = new Image(display, data);
        final BufferedImage awtImage = convertToAWT(data);
        final Image swtImage2 = new Image(display, convertToSWT(awtImage));
        shell.addListener(SWT.Paint, new Listener() {
          public void handleEvent(Event e) {
            int y = 10;
            if (swtImage != null) {
              e.gc.drawImage(swtImage, 10, y);
              y += swtImage.getBounds().height + 10;
            }
            if (swtImage2 != null) {
              e.gc.drawImage(swtImage2, 10, y);
            }
          }
        });
        Frame frame = new Frame() {
          public void paint(Graphics g) {
            Insets insets = getInsets();
            if (awtImage != null) {
              g.drawImage(awtImage, 10 + insets.left, 10 + insets.top,
                  null);
            }
          }
        };
        frame.setTitle("AWT Image");
        shell.setLocation(50, 50);
        Rectangle bounds = swtImage.getBounds();
        shell.setSize(bounds.width + 50, bounds.height * 2 + 100);
        Point size = shell.getSize();
        Point location = shell.getLocation();
        Insets insets = frame.getInsets();
        frame.setLocation(location.x + size.x + 10, location.y);
        frame.setSize(size.x - (insets.left + insets.right), size.y
            - (insets.top + insets.bottom));
        frame.setVisible(true);
        shell.open();
        while (!shell.isDisposed()) {
          if (!display.readAndDispatch())
            display.sleep();
        }
        if (swtImage != null)
          swtImage.dispose();
        if (swtImage2 != null)
          swtImage.dispose();
        frame.dispose();
        System.exit(0);
      }
    }