package ie.dcu.segment.painters; import ie.dcu.segment.*; import ie.dcu.swt.ObservableImage; import org.eclipse.swt.graphics.*; import org.eclipse.swt.widgets.*; /** * Shows an an overlay of foreground border on the image * * @author Kevin McGuinness */ public class OutlineOverlayPainter implements SegmentationPainter { private ImageData maskData; private Image maskImage; public String getName() { return "Outline Overlaid"; } public String getDescription() { return "Shows an an overlay of foreground border on the image"; } public ImageData getMaskData(SegmentationContext ctx) { return maskData; } public void paint(SegmentationContext ctx, ObservableImage im) { GC gc = im.beginPaint(); // Paint image gc.drawImage(ctx.getImage(), 0, 0); // Paint mask /* if(ctx.getMasks().size() != 0) { // For drawing all the previous masks. for(SegmentationMask mask : ctx.getMasks()) { createVisibleMask(mask); gc.drawImage(maskImage, 0, 0); } }*/ // Drawing the current mask createVisibleMask(ctx.getMask()); gc.drawImage(maskImage, 0, 0); // Commit changes im.endPaint(); } private void createVisibleMask(SegmentationMask mask) { dispose(); if (isNewMaskDataRequired(mask.getBounds())) { maskData = createMaskData(mask.getBounds()); } // Set pixels byte[] buff = new byte[maskData.width]; for (int y = 0, i = 0; y < mask.height-1; y++) { for (int x = 0; x < mask.width-1; x++) { // Make transparent buff[x] = 0; // Current pixel byte pix1 = mask.values[i]; // Neighbor to right & neighbor below byte pix2 = mask.values[i+1]; byte pix3 = mask.values[i+mask.width]; // Set pixel if either neighbor is different if (pix1 != pix2 || pix1 != pix3) { buff[x] = 1; } // Next pixel i++; } if (mask.width != 0) { // Last pixel in row byte pix1 = mask.values[i]; byte pix2 = mask.values[i+mask.width]; buff[mask.width-1] = (pix1 != pix2) ? (byte) 1 : 0; // Next row i++; } // Blit pixels maskData.setPixels(0, y, buff.length, buff, 0); } // Last row if (mask.height != 0) { int yoff = (mask.height - 1) * mask.width; for (int x = 0; x < mask.width-1; x++) { byte pix1 = mask.values[x+yoff]; byte pix2 = mask.values[x+yoff+1]; buff[x] = (pix1 != pix2) ? (byte) 1 : 0; } // Blit maskData.setPixels(0, mask.height-1, buff.length, buff, 0); } // Create new mask maskImage = new Image(Display.getCurrent(), maskData); } private boolean isNewMaskDataRequired(Rectangle bounds) { if (maskData == null) { return true; } else { return maskData.width != bounds.width || maskData.height != bounds.height; } } private static ImageData createMaskData(Rectangle bounds) { RGB[] colors = new RGB[] { new RGB(255,255,255), new RGB(0,255,0) }; // Create binary indexed palette PaletteData palette = new PaletteData(colors); // Create 1 bit indexed image ImageData data = new ImageData( bounds.width, bounds.height, 1, palette); // Set transparent pixel data.transparentPixel = 0; // Create and return the image return data; } public void dispose() { // Dispose mask if (maskImage != null) { if (!maskImage.isDisposed()) { maskImage.dispose(); } maskImage = null; } } }