|
import java.io.InputStream;
import java.net.URL;
import java.text.MessageFormat;
import java.util.ResourceBundle;
import java.util.Vector;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTError;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.events.ShellAdapter;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.ImageLoader;
import org.eclipse.swt.graphics.ImageLoaderEvent;
import org.eclipse.swt.graphics.ImageLoaderListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.printing.PrintDialog;
import org.eclipse.swt.printing.Printer;
import org.eclipse.swt.printing.PrinterData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Dialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Sash;
import org.eclipse.swt.widgets.ScrollBar;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
public class ImageAnalyzer {
Display display;
Shell shell;
Canvas imageCanvas, paletteCanvas;
Label typeLabel, sizeLabel, depthLabel, transparentPixelLabel,
timeToLoadLabel, screenSizeLabel, backgroundPixelLabel,
locationLabel, disposalMethodLabel, delayTimeLabel,
repeatCountLabel, paletteLabel, dataLabel, statusLabel;
Combo backgroundCombo, scaleXCombo, scaleYCombo, alphaCombo;
Button incrementalCheck, transparentCheck, maskCheck, backgroundCheck;
Button previousButton, nextButton, animateButton;
StyledText dataText;
Sash sash;
Color whiteColor, blackColor, redColor, greenColor, blueColor,
canvasBackground;
Font fixedWidthFont;
Cursor crossCursor;
GC imageCanvasGC;
int paletteWidth = 140; // recalculated and used as a width hint
int ix = 0, iy = 0, py = 0; // used to scroll the image and palette
float xscale = 1, yscale = 1; // used to scale the image
int alpha = 255; // used to modify the alpha value of the image
boolean incremental = false; // used to incrementally display an image
boolean transparent = true; // used to display an image with transparency
boolean showMask = false; // used to display an icon mask or transparent
// image mask
boolean showBackground = false; // used to display the background of an
// animated image
boolean animate = false; // used to animate a multi-image file
Thread animateThread; // draws animated images
Thread incrementalThread; // draws incremental images
String lastPath; // used to seed the file dialog
String currentName; // the current image file or URL name
String fileName; // the current image file
ImageLoader loader; // the loader for the current image file
ImageData[] imageDataArray; // all image data read from the current file
int imageDataIndex; // the index of the current image data
ImageData imageData; // the currently-displayed image data
Image image; // the currently-displayed image
Vector incrementalEvents; // incremental image events
long loadTime = 0; // the time it took to load the current image
static final int INDEX_DIGITS = 4;
static final int ALPHA_CONSTANT = 0;
static final int ALPHA_X = 1;
static final int ALPHA_Y = 2;
class TextPrompter extends Dialog {
String message = "";
String result = null;
Shell dialog;
Text text;
public TextPrompter(Shell parent, int style) {
super(parent, style);
}
public TextPrompter(Shell parent) {
this(parent, SWT.APPLICATION_MODAL);
}
public String getMessage() {
return message;
}
public void setMessage(String string) {
message = string;
}
public String open() {
dialog = new Shell(getParent(), getStyle());
dialog.setText(getText());
dialog.setLayout(new GridLayout());
Label label = new Label(dialog, SWT.NULL);
label.setText(message);
label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
text = new Text(dialog, SWT.SINGLE | SWT.BORDER);
GridData data = new GridData(GridData.FILL_HORIZONTAL);
data.widthHint = 300;
text.setLayoutData(data);
Composite buttons = new Composite(dialog, SWT.NONE);
GridLayout grid = new GridLayout();
grid.numColumns = 2;
buttons.setLayout(grid);
buttons.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
Button ok = new Button(buttons, SWT.PUSH);
ok.setText("OK");
data = new GridData();
data.widthHint = 75;
ok.setLayoutData(data);
ok.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
result = text.getText();
dialog.dispose();
}
});
Button cancel = new Button(buttons, SWT.PUSH);
cancel.setText("Cancel");
data = new GridData();
data.widthHint = 75;
cancel.setLayoutData(data);
cancel.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
dialog.dispose();
}
});
dialog.setDefaultButton(ok);
dialog.pack();
dialog.open();
while (!dialog.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
return result;
}
}
public static void main(String[] args) {
Display display = new Display();
ImageAnalyzer imageAnalyzer = new ImageAnalyzer();
Shell shell = imageAnalyzer.open(display);
while (!shell.isDisposed())
if (!display.readAndDispatch())
display.sleep();
display.dispose();
}
public Shell open(Display dpy) {
// Create a window and set its title.
this.display = dpy;
shell = new Shell(display);
shell.setText("Image_analyzer");
// Hook resize and dispose listeners.
shell.addControlListener(new ControlAdapter() {
public void controlResized(ControlEvent event) {
resizeShell(event);
}
});
shell.addShellListener(new ShellAdapter() {
public void shellClosed(ShellEvent e) {
animate = false; // stop any animation in progress
if (animateThread != null) {
// wait for the thread to die before disposing the shell.
while (animateThread.isAlive()) {
if (!display.readAndDispatch())
display.sleep();
}
}
e.doit = true;
}
});
shell.addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent e) {
// Clean up.
if (image != null)
image.dispose();
whiteColor.dispose();
blackColor.dispose();
redColor.dispose();
greenColor.dispose();
blueColor.dispose();
fixedWidthFont.dispose();
crossCursor.dispose();
}
});
// Create colors and fonts.
whiteColor = new Color(display, 255, 255, 255);
blackColor = new Color(display, 0, 0, 0);
redColor = new Color(display, 255, 0, 0);
greenColor = new Color(display, 0, 255, 0);
blueColor = new Color(display, 0, 0, 255);
fixedWidthFont = new Font(display, "courier", 10, 0);
crossCursor = new Cursor(display, SWT.CURSOR_CROSS);
// Add a menu bar and widgets.
createMenuBar();
createWidgets();
shell.pack();
// Create a GC for drawing, and hook the listener to dispose it.
imageCanvasGC = new GC(imageCanvas);
imageCanvas.addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent e) {
imageCanvasGC.dispose();
}
});
// Open the window
shell.open();
return shell;
}
void createWidgets() {
// Add the widgets to the shell in a grid layout.
GridLayout layout = new GridLayout();
layout.marginHeight = 0;
layout.numColumns = 2;
shell.setLayout(layout);
// Separate the menu bar from the rest of the widgets.
Label separator = new Label(shell, SWT.SEPARATOR | SWT.HORIZONTAL);
GridData gridData = new GridData();
gridData.horizontalSpan = 2;
gridData.horizontalAlignment = GridData.FILL;
separator.setLayoutData(gridData);
// Add a composite to contain some control widgets across the top.
Composite controls = new Composite(shell, SWT.NULL);
RowLayout rowLayout = new RowLayout();
rowLayout.marginTop = 0;
rowLayout.marginBottom = 5;
rowLayout.spacing = 8;
controls.setLayout(rowLayout);
gridData = new GridData();
gridData.horizontalSpan = 2;
controls.setLayoutData(gridData);
// Combo to change the background.
Group group = new Group(controls, SWT.NULL);
group.setLayout(new RowLayout());
group.setText("Background");
backgroundCombo = new Combo(group, SWT.DROP_DOWN | SWT.READ_ONLY);
backgroundCombo.setItems(new String[] { "None",
"White", "Black",
"Red", "Green",
"Blue" });
backgroundCombo.select(backgroundCombo.indexOf("White"));
backgroundCombo.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
changeBackground();
}
});
// Combo to change the x scale.
String[] values = { "0.1", "0.2", "0.3", "0.4", "0.5", "0.6", "0.7",
"0.8", "0.9", "1", "1.1", "1.2", "1.3", "1.4", "1.5", "1.6",
"1.7", "1.8", "1.9", "2", "3", "4", "5", "6", "7", "8", "9",
"10", };
group = new Group(controls, SWT.NULL);
group.setLayout(new RowLayout());
group.setText("X_scale");
scaleXCombo = new Combo(group, SWT.DROP_DOWN);
for (int i = 0; i < values.length; i++) {
scaleXCombo.add(values[i]);
}
scaleXCombo.select(scaleXCombo.indexOf("1"));
scaleXCombo.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
scaleX();
}
});
// Combo to change the y scale.
group = new Group(controls, SWT.NULL);
group.setLayout(new RowLayout());
group.setText("Y_scale");
scaleYCombo = new Combo(group, SWT.DROP_DOWN);
for (int i = 0; i < values.length; i++) {
scaleYCombo.add(values[i]);
}
scaleYCombo.select(scaleYCombo.indexOf("1"));
scaleYCombo.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
scaleY();
}
});
// Combo to change the alpha value.
group = new Group(controls, SWT.NULL);
group.setLayout(new RowLayout());
group.setText("Alpha_K");
alphaCombo = new Combo(group, SWT.DROP_DOWN | SWT.READ_ONLY);
for (int i = 0; i <= 255; i += 5) {
alphaCombo.add(String.valueOf(i));
}
alphaCombo.select(alphaCombo.indexOf("255"));
alphaCombo.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
alpha();
}
});
// Check box to request incremental display.
group = new Group(controls, SWT.NULL);
group.setLayout(new RowLayout());
group.setText("Display");
incrementalCheck = new Button(group, SWT.CHECK);
incrementalCheck.setText("Incremental");
incrementalCheck.setSelection(incremental);
incrementalCheck.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
incremental = ((Button) event.widget).getSelection();
}
});
// Check box to request transparent display.
transparentCheck = new Button(group, SWT.CHECK);
transparentCheck.setText("Transparent");
transparentCheck.setSelection(transparent);
transparentCheck.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
transparent = ((Button) event.widget).getSelection();
if (image != null) {
imageCanvas.redraw();
}
}
});
// Check box to request mask display.
maskCheck = new Button(group, SWT.CHECK);
maskCheck.setText("Mask");
maskCheck.setSelection(showMask);
maskCheck.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
showMask = ((Button) event.widget).getSelection();
if (image != null) {
imageCanvas.redraw();
}
}
});
// Check box to request background display.
backgroundCheck = new Button(group, SWT.CHECK);
backgroundCheck.setText("Background");
backgroundCheck.setSelection(showBackground);
backgroundCheck.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
showBackground = ((Button) event.widget).getSelection();
}
});
// Group the animation buttons.
group = new Group(controls, SWT.NULL);
group.setLayout(new RowLayout());
group.setText("Animation");
// Push button to display the previous image in a multi-image file.
previousButton = new Button(group, SWT.PUSH);
previousButton.setText("Previous");
previousButton.setEnabled(false);
previousButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
previous();
}
});
// Push button to display the next image in a multi-image file.
nextButton = new Button(group, SWT.PUSH);
nextButton.setText("Next");
nextButton.setEnabled(false);
nextButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
next();
}
});
// Push button to toggle animation of a multi-image file.
animateButton = new Button(group, SWT.PUSH);
animateButton.setText("Animate");
animateButton.setEnabled(false);
animateButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
animate();
}
});
// Label to show the image file type.
typeLabel = new Label(shell, SWT.NULL);
typeLabel.setText("Type_initial");
typeLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
// Canvas to show the image.
imageCanvas = new Canvas(shell, SWT.V_SCROLL | SWT.H_SCROLL
| SWT.NO_REDRAW_RESIZE);
imageCanvas.setBackground(whiteColor);
imageCanvas.setCursor(crossCursor);
gridData = new GridData();
gridData.verticalSpan = 15;
gridData.horizontalAlignment = GridData.FILL;
gridData.verticalAlignment = GridData.FILL;
gridData.grabExcessHorizontalSpace = true;
gridData.grabExcessVerticalSpace = true;
imageCanvas.setLayoutData(gridData);
imageCanvas.addPaintListener(new PaintListener() {
public void paintControl(PaintEvent event) {
if (image != null)
paintImage(event);
}
});
imageCanvas.addMouseMoveListener(new MouseMoveListener() {
public void mouseMove(MouseEvent event) {
if (image != null) {
showColorAt(event.x, event.y);
}
}
});
// Set up the image canvas scroll bars.
ScrollBar horizontal = imageCanvas.getHorizontalBar();
horizontal.setVisible(true);
horizontal.setMinimum(0);
horizontal.setEnabled(false);
horizontal.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
scrollHorizontally((ScrollBar) event.widget);
}
});
ScrollBar vertical = imageCanvas.getVerticalBar();
vertical.setVisible(true);
vertical.setMinimum(0);
vertical.setEnabled(false);
vertical.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
scrollVertically((ScrollBar) event.widget);
}
});
// Label to show the image size.
sizeLabel = new Label(shell, SWT.NULL);
sizeLabel.setText("Size_initial");
sizeLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
// Label to show the image depth.
depthLabel = new Label(shell, SWT.NULL);
depthLabel.setText("Depth_initial");
depthLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
// Label to show the transparent pixel.
transparentPixelLabel = new Label(shell, SWT.NULL);
transparentPixelLabel.setText("Transparent_pixel_initial");
transparentPixelLabel.setLayoutData(new GridData(
GridData.HORIZONTAL_ALIGN_FILL));
// Label to show the time to load.
timeToLoadLabel = new Label(shell, SWT.NULL);
timeToLoadLabel.setText("Time_to_load_initial");
timeToLoadLabel.setLayoutData(new GridData(
GridData.HORIZONTAL_ALIGN_FILL));
// Separate the animation fields from the rest of the fields.
separator = new Label(shell, SWT.SEPARATOR | SWT.HORIZONTAL);
separator.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
// Label to show the logical screen size for animation.
screenSizeLabel = new Label(shell, SWT.NULL);
screenSizeLabel.setText("Animation_size_initial");
screenSizeLabel.setLayoutData(new GridData(
GridData.HORIZONTAL_ALIGN_FILL));
// Label to show the background pixel.
backgroundPixelLabel = new Label(shell, SWT.NULL);
backgroundPixelLabel.setText("Background_pixel_initial");
backgroundPixelLabel.setLayoutData(new GridData(
GridData.HORIZONTAL_ALIGN_FILL));
// Label to show the image location (x, y).
locationLabel = new Label(shell, SWT.NULL);
locationLabel.setText("Image_location_initial");
locationLabel
.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
// Label to show the image disposal method.
disposalMethodLabel = new Label(shell, SWT.NULL);
disposalMethodLabel.setText("Disposal_initial");
disposalMethodLabel.setLayoutData(new GridData(
GridData.HORIZONTAL_ALIGN_FILL));
// Label to show the image delay time.
delayTimeLabel = new Label(shell, SWT.NULL);
delayTimeLabel.setText("Delay_initial");
delayTimeLabel.setLayoutData(new GridData(
GridData.HORIZONTAL_ALIGN_FILL));
// Label to show the background pixel.
repeatCountLabel = new Label(shell, SWT.NULL);
repeatCountLabel.setText("Repeats_initial");
repeatCountLabel.setLayoutData(new GridData(
GridData.HORIZONTAL_ALIGN_FILL));
// Separate the animation fields from the palette.
separator = new Label(shell, SWT.SEPARATOR | SWT.HORIZONTAL);
separator.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
// Label to show if the image has a direct or indexed palette.
paletteLabel = new Label(shell, SWT.NULL);
paletteLabel.setText("Palette_initial");
paletteLabel
.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
// Canvas to show the image's palette.
paletteCanvas = new Canvas(shell, SWT.BORDER | SWT.V_SCROLL
| SWT.NO_REDRAW_RESIZE);
paletteCanvas.setFont(fixedWidthFont);
|