Commit 9271e949 by Tobias

Improve Start screen

1 parent 34098f6c
package org.stegosuite.image.embedding.gif;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
......@@ -10,6 +13,8 @@ import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import javax.imageio.ImageIO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.stegosuite.image.embedding.EmbeddingMethod;
......@@ -24,6 +29,7 @@ import org.stegosuite.model.payload.PayloadEmbedder;
import org.stegosuite.model.payload.PayloadExtractor;
import org.stegosuite.util.ByteUtils;
import org.stegosuite.util.ColorDistance;
import org.stegosuite.util.ColorUtils;
import org.stegosuite.util.CryptoUtils;
/**
......@@ -39,7 +45,7 @@ public class GIFShuffle
super(image, pointFilter);
}
private static final ColorDistance DISTANCE = ColorDistance.RGB_EUCLID;
private static final ColorDistance DISTANCE = ColorDistance.CIEDE_2000;
/**
* Capacity in bits: sum(log2(n)) for n=2..colorTable.size()
......@@ -59,10 +65,16 @@ public class GIFShuffle
List<Color> originalTable = image.getColorTable();
List<Color> newTable = new ArrayList<>(originalTable);
List<Color> randomTable = image.getSortedColorTable(DISTANCE);
LOG.debug("Array: {}",Arrays.toString(originalTable.toArray()));
LOG.debug("Array: {}",Arrays.toString(randomTable.toArray()));
Collections.shuffle(randomTable, CryptoUtils.seededRandom(payload.getSteganoPassword()));
// LOG.debug("Array: {}",Arrays.toString(randomTable.toArray()));
LOG.debug("origtable size: {}",originalTable.size());
LOG.debug("sortedtable size: {}",randomTable.size());
LOG.debug("randomtable size: {}",randomTable.size());
// Prepend 1 to the payload so that leading 0 bytes are not cut off
PayloadEmbedder embedder = new PayloadEmbedder(payload, this.capacity());
......@@ -90,8 +102,16 @@ public class GIFShuffle
throws SteganoExtractException {
List<Color> table = image.getColorTable();
List<Color> randomTable = image.getSortedColorTable(DISTANCE);
LOG.debug("Array: {}",Arrays.toString(randomTable.toArray()));
Collections.shuffle(randomTable, CryptoUtils.seededRandom(payload.getSteganoPassword()));
// LOG.debug("Array: {}",Arrays.toString(randomTable.toArray()));
Map<Color, Integer> positions = IntStream.range(0, table.size()).boxed()
.collect(Collectors.toMap(i -> table.get(i), i -> i));
......
package org.stegosuite.ui.gui;
import java.util.ResourceBundle;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.*;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DropTarget;
import org.eclipse.swt.dnd.DropTargetAdapter;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.FileTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Shell;
import org.stegosuite.image.format.ImageFormat;
import org.stegosuite.model.exception.SteganoImageException;
import java.util.ResourceBundle;
import ch.qos.logback.core.net.SyslogOutputStream;
/**
* Base class for the GUI. Contains global GUI-elements and global listeners.
......@@ -28,13 +44,16 @@ public class Gui {
private static Label statusBar;
private final ResourceBundle L = ResourceBundle.getBundle("Messages");
private int borderAlpha = 50;
private String imagePath = null;
public Gui(String path) {
display = new Display();
guiComponents = new GuiComponents();
shell = guiComponents.createShell(display);
statusBar = guiComponents.createStatusBar(shell);
shell.addListener(SWT.Paint, event -> drawBorder(event, borderAlpha));
menuBar = guiComponents.createMenuBar(shell);
if (path != null) {
......@@ -43,12 +62,8 @@ public class Gui {
showStartScreen();
}
final String[] FILTER_NAMES = { "All supported files (*.bmp/*.gif/*.jpg/*.png)", "BMP-Files (*.bmp)",
"GIF-Files (*.gif)", "JPG-Files (*.jpg)", "PNG-Files (*.png)" };
final String[] FILTER_EXTS = { "*.bmp;*.gif;*.jpg;*.png", "*.bmp", "*.gif", "*.jpg", "*.png" };
// Drag and drop files into the window to load them
final DropTarget dropTarget = new DropTarget(shell, DND.DROP_MOVE);
final DropTarget dropTarget = new DropTarget(shell, DND.DROP_MOVE);
dropTarget.setTransfer(new Transfer[] { FileTransfer.getInstance() });
dropTarget.addDropListener(new DropTargetAdapter() {
......@@ -57,19 +72,36 @@ public class Gui {
final String[] filenames = (String[]) event.data;
loadImages(filenames[0]);
}
public void dragEnter(final DropTargetEvent event) {
borderAlpha = 250;
shell.redraw();
}
public void dragLeave(final DropTargetEvent event) {
borderAlpha = 50;
shell.redraw();
}
});
// when user clicks in menubar on "Load file", open a file dialog
menuBar.getItem(0).getMenu().getItem(0).addListener(SWT.Selection, event -> {
FileDialog dlg = new FileDialog(shell, SWT.OPEN);
dlg.setFilterNames(FILTER_NAMES);
dlg.setFilterExtensions(FILTER_EXTS);
loadImages(dlg.open());
openFileDialog();
});
shell.setMenuBar(menuBar);
startEventLoop();
}
private void openFileDialog() {
final String[] FILTER_NAMES = { "All supported files (*.bmp/*.gif/*.jpg/*.png)", "BMP-Files (*.bmp)",
"GIF-Files (*.gif)", "JPG-Files (*.jpg)", "PNG-Files (*.png)" };
final String[] FILTER_EXTS = { "*.bmp;*.gif;*.jpg;*.png", "*.bmp", "*.gif", "*.jpg", "*.png" };
FileDialog dlg = new FileDialog(shell, SWT.OPEN);
dlg.setFilterNames(FILTER_NAMES);
dlg.setFilterExtensions(FILTER_EXTS);
loadImages(dlg.open());
}
private void startEventLoop() {
// Display Window in the middle of screen
final Rectangle bds = display.getBounds();
......@@ -93,6 +125,20 @@ public class Gui {
display.dispose();
}
private void drawBorder(Event event, int alpha) {
GC gc = event.gc;
// gc.setForeground(event.display.getSystemColor(SWT.COLOR_GRAY));
gc.setAntialias(SWT.ON);
gc.setAlpha(alpha);
gc.setLineWidth(2);
gc.setLineStyle(SWT.LINE_CUSTOM);
gc.setLineDash(new int[] { 10, 5 });
gc.drawRoundRectangle(12, 12, shell.getClientArea().width - 24, shell.getClientArea().height - 24, 12, 12);
gc.dispose();
}
/**
* Loads a gif- or bmp-image and displays it.
*
......@@ -101,7 +147,7 @@ public class Gui {
private void loadImages(String path) {
try {
ImageFormat image = ImageFormat.getImageFormat(path);
if (image != null) {
if (image != null) {
initializeEmbedUi();
guiComponents.embedUi.loadImage(image);
}
......@@ -112,15 +158,15 @@ public class Gui {
private void initializeEmbedUi() {
if (composite == null) {
removeStartScreen();
startLayout();
}
removeStartScreen();
startLayout();
}
}
private void removeStartScreen() {
if (shell.getChildren().length > 1) {
shell.getChildren()[1].dispose();
}
if (shell.getChildren().length >= 1) {
shell.getChildren()[0].dispose();
}
}
/**
......@@ -133,27 +179,56 @@ public class Gui {
}
private void showStartScreen() {
final Label label = new Label(shell, SWT.SHADOW_NONE);
final Composite composite = new Composite(shell, SWT.NONE);
composite.setLayout(new FormLayout());
final Label label = new Label(composite, SWT.SHADOW_NONE);
final Label label2 = new Label(composite, SWT.SHADOW_NONE);
final Button browseButton = new Button(composite, SWT.PUSH);
label.setText(L.getString("start_text"));
label2.setText(L.getString("or"));
browseButton.setText(L.getString("browse_files"));
// increase font size
final FontData[] fontData = label.getFont().getFontData();
for (FontData element : fontData) {
element.setHeight(20);
element.setStyle(SWT.BOLD);
}
label.setFont(new Font(display, fontData));
// place label in the middle of the window
shell.layout(true, true);
final int offset = label.getBounds().width / 2;
final FormData labelData = new FormData();
labelData.left = new FormAttachment(50, -offset);
labelData.bottom = new FormAttachment(50);
label.setLayoutData(labelData);
FormData formData = new FormData();
int offset = label2.getBounds().width / 2;
formData.left = new FormAttachment(50, -offset);
formData.top = new FormAttachment(label, 24);
label2.setLayoutData(formData);
formData = new FormData();
offset = browseButton.getBounds().width / 2;
formData.left = new FormAttachment(50, -offset);
formData.top = new FormAttachment(label2, 24);
browseButton.setLayoutData(formData);
browseButton.addListener(SWT.Selection, event -> {
openFileDialog();
});
shell.layout(true, true);
formData = new FormData();
offset = composite.getBounds().width / 2;
formData.left = new FormAttachment(50, -offset);
offset = composite.getBounds().height / 2;
formData.top = new FormAttachment(50, -offset);
composite.setLayoutData(formData);
shell.layout(true, true);
}
private void startLayout() {
statusBar = guiComponents.createStatusBar(shell);
composite = guiComponents.createLayout(shell, statusBar);
shell.layout(true, true);
}
......
......@@ -28,7 +28,7 @@ public class ColorUtils {
if (colors.size() < 2) {
return colors;
}
//TODO: Do not remove dublicated colors, the size of the List should stay the same (Gifshuffle needs this to work)
Set<Color> unsortedBase = new HashSet<>(colors);
Map<Double, List<Color>> sortedLists = new ConcurrentHashMap<>();
......
start_text = No image loaded.
start_text = Drag and drop image here
or = or
browse_files = Browse files
file_menu = &File
load_image_menu = &Open...
......
......@@ -39,13 +39,13 @@ public class EmbeddingAndExtractingTest {
@Test
public void testEmbeddingAndExtractingFromGifFile() throws Exception {
testEmbeddingAndThenExtractingOk("sunflower2.gif");
testEmbeddingAndThenExtractingOk("sunflower3.gif");
}
@Test
public void testEmbeddingAndExtractingFromGifFileUsingGifshuffle() throws Exception {
embeddingAlgorithm = EmbeddingFactory.GIFSHUFFLE;
testEmbeddingAndThenExtractingOk("sunflower2.gif");
testEmbeddingAndThenExtractingOk("sunflower3.gif");
embeddingAlgorithm = null;
}
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!