ImageResizerpublic class ImageResizer extends Object
Fields Summary |
---|
private static final int | RESIZE_STEPS | private static final int | MARGIN | private int | minWidth | private int | minHeight | private int | displayWidth | private int | displayHeight | private Display | display | private Shell | parent | private Shell | shell | private Cursor | cursor | private Canvas | canvas | private Scale | scale | private long | lastUpdate | private Image | original | private int | originalWidth | private int | originalHeight | private Image | currentImage | private Image | overlay | private Image | overlayDragging | private Image | overlayNotDragging | private boolean | done | private Image | result | private float | zoomRatio | private float | minZoomRatio | private float | maxZoomRatio | private Point | offset | private Listener | moveImageListener |
Constructors Summary |
---|
public ImageResizer(Display display, int width, int height, Shell parent)
this.parent = parent;
this.display = display;
this.minWidth = width;
this.minHeight = height;
|
Methods Summary |
---|
private boolean | checkSize(Image image)
//If the image is smaller than the minimal size, we shouldn't accept it
Rectangle size = image.getBounds();
if (size.width < minWidth || size.height < minHeight) {
return false;
}
float minHRatio = (float) (minHeight) / size.height;
float minWRatio = (float) (minWidth) / size.width;
float maxHRatio = (float) (minHeight * 4) / size.height;
float maxWRatio = (float) (minWidth * 4) / size.width;
//We must keep the min zoom bigger than the "biggest" ratio (ie, smallest zoom out)
minZoomRatio = minHRatio > minWRatio ? minHRatio : minWRatio;
maxZoomRatio = maxHRatio > maxWRatio ? maxHRatio : maxWRatio;
if (maxZoomRatio > 1) {
maxZoomRatio = 1;
}
zoomRatio = minZoomRatio;
return true;
| private Image | computeResultImage()
Image img = new Image(display, minWidth, minHeight);
/*ImageData srcData = original.getImageData();
ImageData dstData = new ImageData(
currentImage.getBounds().width,
currentImage.getBounds().height,
32,
new PaletteData(0xFF,0xFF00,0xFF0000));
Resample resample = new Resample();
resample.setFilter(Resample.FILTER_TYPE_LANCZOS3, 7.0f);
resample.process(srcData, dstData);
Image filtered = new Image(display,dstData);
*/
GC gc = new GC(img);
gc.drawImage(currentImage, offset.x, offset.y);
gc.dispose();
//filtered.dispose();
return img;
| private Image | createOverlayImage(byte marginAlpha, int marginColor, byte borderAlpha, int borderColor)
int width = displayWidth;
int height = displayHeight;
ImageData data = new ImageData(width, height, 32, new PaletteData(
0x000000FF, 0x0000FF00, 0x00FF0000));
byte[] transparency = new byte[width * height];
int[] pixels = new int[width * height];
byte rowAlpha[] = new byte[width];
int rowPixels[] = new int[width];
//Top
//Pattern
for (int i = 0; i < width; i++) {
rowAlpha[i] = marginAlpha;
rowPixels[i] = marginColor;
}
//Fill
for (int i = 0; i < MARGIN; i++) {
System.arraycopy(rowAlpha, 0, transparency, i * width, width);
System.arraycopy(rowPixels, 0, pixels, i * width, width);
}
//Main area
//Pattern
for (int i = 0; i < MARGIN; i++) {
rowAlpha[i] = marginAlpha;
rowAlpha[width - i - 1] = marginAlpha;
}
for (int i = MARGIN; i < width - MARGIN; i++) {
rowAlpha[i] = 0;
}
//Fill
for (int i = MARGIN; i < height - MARGIN; i++) {
System.arraycopy(rowAlpha, 0, transparency, i * width, width);
System.arraycopy(rowPixels, 0, pixels, i * width, width);
}
//Bottom
//Pattern
for (int i = 0; i < width; i++) {
rowAlpha[i] = marginAlpha;
}
//Fill
for (int i = height - MARGIN - 1; i < height; i++) {
System.arraycopy(rowAlpha, 0, transparency, i * width, width);
System.arraycopy(rowPixels, 0, pixels, i * width, width);
}
//Let's do the border part
for (int i = MARGIN; i < width - MARGIN; i++) {
transparency[width * MARGIN + i] = borderAlpha;
pixels[width * MARGIN + i] = borderColor;
}
for (int j = MARGIN; j < height - MARGIN; j++) {
transparency[j * width + MARGIN] = borderAlpha;
pixels[j * width + MARGIN] = borderColor;
transparency[j * width + width - MARGIN - 1] = borderAlpha;
pixels[j * width + width - MARGIN - 1] = borderColor;
}
for (int i = MARGIN; i < width - MARGIN; i++) {
transparency[width * (height - MARGIN - 1) + i] = borderAlpha;
pixels[width * (height - MARGIN - 1) + i] = borderColor;
}
data.alphaData = transparency;
data.setPixels(0, 0, width * height, pixels, 0);
Image overlay = new Image(display, data);
return overlay;
| private void | dispose()
if (shell != null && !shell.isDisposed()) {
shell.dispose();
}
if (currentImage != null && !currentImage.isDisposed()) {
currentImage.dispose();
}
if (overlayDragging != null && !overlayDragging.isDisposed()) {
overlayDragging.dispose();
}
if (overlayNotDragging != null && !overlayNotDragging.isDisposed()) {
overlayNotDragging.dispose();
}
if (cursor != null && !cursor.isDisposed()) {
cursor.dispose();
}
| private void | drawCurrentImage()
GC gcCanvas = new GC(canvas);
Image temp = new Image(display, displayWidth, displayHeight);
GC gc = new GC(temp);
gc.drawImage(currentImage, offset.x + MARGIN + 1, offset.y + MARGIN + 1);
//gc.setAlpha(128);
gc.drawImage(overlay, 0, 0);
//gc.setTextAntialias(SWT.ON);
//gc.drawText("This is a test", 15, displayHeight-15,true);
gc.dispose();
gcCanvas.drawImage(temp, 0, 0);
temp.dispose();
gcCanvas.dispose();
| private void | initUI()
cursor = new Cursor(display, SWT.CURSOR_HAND);
if (parent != null) {
shell = new Shell(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
} else {
shell = new Shell(display, SWT.CLOSE | SWT.BORDER);
}
shell.setText("Thumbnail Assistant");
Utils.setShellIcon(shell);
shell.addListener(SWT.Close, new Listener() {
public void handleEvent(Event event) {
event.doit = false;
result = null;
done = true;
}
});
FormLayout layout = new FormLayout();
layout.marginBottom = 5;
layout.marginTop = 5;
layout.marginLeft = 5;
layout.marginRight = 5;
FormData data;
shell.setLayout(layout);
Label title = new Label(shell, SWT.WRAP);
title.setText("This tool lets you preview how your thumbnail is going to look like on the Azureus Platform");
data = new FormData();
data.width = displayWidth;
title.setLayoutData(data);
canvas = new Canvas(shell, SWT.BORDER);
canvas.setCursor(cursor);
data = new FormData();
data.width = displayWidth;
data.height = displayHeight;
data.top = new FormAttachment(title, 5);
canvas.setLayoutData(data);
canvas.addListener(SWT.MouseDown, moveImageListener);
canvas.addListener(SWT.MouseUp, moveImageListener);
canvas.addListener(SWT.MouseMove, moveImageListener);
canvas.addPaintListener(new PaintListener() {
public void paintControl(PaintEvent arg0) {
drawCurrentImage();
}
});
offset.x = (minWidth - currentImage.getBounds().width) / 2;
offset.y = (minHeight - currentImage.getBounds().height) / 2;
Label label = new Label(shell, SWT.WRAP);
//The label text depends on the presence of the scale,
//Thefore we delay the size computation as well as
//Assiging any FormData (layout) to it see (1)
//The Control to witch the Buttons OK and Cancel are going to be attached
//Depends on the presence of the scale
Control attach = label;
if (minZoomRatio < 1) {
scale = new Scale(shell, SWT.HORIZONTAL);
data = new FormData();
data.width = displayWidth;
data.top = new FormAttachment(label, 5);
scale.setLayoutData(data);
scale.setMaximum((int) (RESIZE_STEPS * maxZoomRatio));
scale.setMinimum((int) (RESIZE_STEPS * minZoomRatio));
scale.setIncrement((int) ((maxZoomRatio - minZoomRatio) * RESIZE_STEPS / 10));
scale.setPageIncrement((int) ((maxZoomRatio - minZoomRatio)
* RESIZE_STEPS / 10));
scale.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event arg0) {
final long timestamp = SystemTime.getCurrentTime();
lastUpdate = timestamp;
final int position = scale.getSelection();
AEThread t = new AEThread("") {
public void runSupport() {
try {
Thread.sleep(150);
} catch (Exception e) {
e.printStackTrace();
}
if (timestamp == lastUpdate) {
if (display != null && !display.isDisposed()) {
display.asyncExec(new Runnable() {
public void run() {
refreshCurrentImage(position);
}
});
}
}
}
};
t.setDaemon(true);
t.start();
}
});
attach = scale;
label.setText("Move the image by dragging it, resize it by using the slider below");
} else {
label.setText("Move the image by dragging it");
}
// (1) Layout of the label, depending on the text in it
int width = label.computeSize(SWT.DEFAULT, SWT.DEFAULT).x;
if (width > displayWidth) {
width = displayWidth;
}
data = new FormData();
data.width = width;
data.top = new FormAttachment(canvas, 5);
data.left = new FormAttachment(canvas, 0, SWT.CENTER);
label.setLayoutData(data);
Button btnCancel = new Button(shell, SWT.PUSH);
btnCancel.setText("Cancel");
data = new FormData();
data.width = 70;
data.top = new FormAttachment(attach, 10);
data.right = new FormAttachment(100, -10);
btnCancel.setLayoutData(data);
btnCancel.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event arg0) {
result = null;
done = true;
}
});
Button btnOk = new Button(shell, SWT.PUSH);
btnOk.setText("OK");
data = new FormData();
data.width = 70;
data.top = new FormAttachment(attach, 10);
data.right = new FormAttachment(btnCancel, -10);
btnOk.setLayoutData(data);
btnOk.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event arg0) {
result = computeResultImage();
done = true;
}
});
shell.setDefaultButton(btnOk);
btnOk.setFocus();
shell.setSize(shell.computeSize(SWT.DEFAULT, SWT.DEFAULT));
if (parent != null) {
Utils.centerWindowRelativeTo(shell, parent);
}
shell.open();
drawCurrentImage();
| private void | insureOffsetIsCorrect()
int minX = minWidth - currentImage.getBounds().width;
if (offset.x < minX) {
offset.x = minX;
}
int minY = minHeight - currentImage.getBounds().height;
if (offset.y < minY) {
offset.y = minY;
}
if (offset.x > 0) {
offset.x = 0;
}
if (offset.y > 0) {
offset.y = 0;
}
| private ImageData | internalResize(Image image, int newWidth, int newHeight)
ImageData srcData = image.getImageData();
//int width = srcData.width,height = srcData.height;
ImageData data = srcData;
//int newWidth = (int)(width*zoomRatio);
//int newHeight = (int)(height*zoomRatio);
final ImageData copy = new ImageData(newWidth, newHeight, 24,
new PaletteData(0x00FF0000, 0x0000FF00, 0x000000FF));
Image src = new Image(display, srcData);
Image dst = new Image(display, copy);
GC gc = new GC(dst);
gc.setAdvanced(true);
try {
gc.setInterpolation(SWT.HIGH);
} catch (Exception e) {
// may not be avail
}
gc.drawImage(src, 0, 0, srcData.width, srcData.height, 0, 0, copy.width,
copy.height);
//gc.setAlpha(50);
//gc.drawImage(src,2,2,srcData.width-2,srcData.height-2,0,0,copy.width,copy.height);
gc.dispose();
data = dst.getImageData();
src.dispose();
dst.dispose();
return data;
| public static void | main(java.lang.String[] args)
Display display = Display.getDefault();
Shell test = new Shell(display);
ImageResizer resizer = new ImageResizer(display, 228, 128, null);
String file = new FileDialog(test).open();
Image img = new Image(display, file);
Image thumbnail = resizer.resize(img);
System.out.println(thumbnail);
thumbnail.dispose();
test.dispose();
if (args.length == 0) {
display.dispose();
}
| private void | refreshCurrentImage(int position)
float previousZoom = zoomRatio;
zoomRatio = (float) position / RESIZE_STEPS;
if (zoomRatio > 1) {
zoomRatio = 1;
}
if (zoomRatio < minZoomRatio) {
zoomRatio = minZoomRatio;
}
if (previousZoom != zoomRatio) {
Image previous = currentImage;
currentImage = new Image(display,
internalResize(original, (int) (originalWidth * zoomRatio),
(int) (originalHeight * zoomRatio)));
//float ratio = zoomRatio / previousZoom;
offset.x += (previous.getBounds().width - currentImage.getBounds().width) / 2;
offset.y += (previous.getBounds().height - currentImage.getBounds().height) / 2;
if (previous != null && !previous.isDisposed()) {
previous.dispose();
}
insureOffsetIsCorrect();
drawCurrentImage();
}
| public Image | resize(Image original)
this.original = original;
//If the image is too small, let's just not deal with it
if (!checkSize(original)) {
dispose();
throw new ImageResizeException(
"The image provided is too small (has to be at least " + minWidth
+ " x " + minHeight + "), please choose a different one");
}
originalWidth = original.getBounds().width;
originalHeight = original.getBounds().height;
currentImage = new Image(display, internalResize(original,
(int) (originalWidth * zoomRatio), (int) (originalHeight * zoomRatio)));
offset = new Point(0, 0);
if (minWidth != original.getBounds().width
|| minHeight != original.getBounds().height) {
displayWidth = minWidth + 2 * (MARGIN + 1);
displayHeight = minHeight + 2 * (MARGIN + 1);
overlay = overlayNotDragging = createOverlayImage((byte) 255, 0x00FFFFFF,
(byte) 255, 0x00000000);
overlayDragging = createOverlayImage((byte) 80, 0x00FFFFFF, (byte) 255,
0x00FFFFFF);
initUI();
done = false;
while (!done) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
} else {
result = computeResultImage();
}
dispose();
return result;
|
|