Package com.aelitis.azureus.ui.swt.utils

Source Code of com.aelitis.azureus.ui.swt.utils.ImageResizer$ImageResizerListener

package com.aelitis.azureus.ui.swt.utils;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.*;

import org.gudy.azureus2.core3.internat.MessageText;
import org.gudy.azureus2.core3.util.AEThread;
import org.gudy.azureus2.core3.util.SystemTime;
import org.gudy.azureus2.ui.swt.Utils;
import org.gudy.azureus2.ui.swt.components.shell.ShellFactory;

public class ImageResizer
{

  static private final int RESIZE_STEPS = 100000;

  static private final int MARGIN = 20;

  private int minWidth, minHeight;

  private int displayWidth, displayHeight;

  private Display display;

  private Shell parent;

  private Shell shell;

  private Cursor cursor;

  private Canvas canvas;

  private Scale scale;

  private long lastUpdate = 0l;

  private Image original;

  private int originalWidth, 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 = new Listener() {

    private boolean mouseDown = false;

    private Point pointDown;

    public void handleEvent(Event event) {
      //System.out.println(event);
      switch (event.type) {
        case SWT.MouseDown:
          mouseDown = true;
          pointDown = new Point(event.x, event.y);
          overlay = overlayDragging;
          drawCurrentImage();
          break;
        case SWT.MouseUp:
          mouseDown = false;
          overlay = overlayNotDragging;
          drawCurrentImage();
          break;
        case SWT.MouseMove:
          if (!mouseDown) {
            break;
          }
          offset.x = offset.x + event.x - pointDown.x;
          offset.y = offset.y + event.y - pointDown.y;
          insureOffsetIsCorrect();

          pointDown.x = event.x;
          pointDown.y = event.y;
          drawCurrentImage();
          break;
        case SWT.MouseEnter:

          break;
        case SWT.MouseExit:

          break;
      }

    }
  };

  private ImageResizerListener imageResizerListener;

  public ImageResizer(Display display, int width, int height, Shell parent) {
    this.parent = parent;
    this.display = display;
    this.minWidth = width;
    this.minHeight = height;
  }

  public void resize(Image original, ImageResizerListener l) throws ImageResizeException {

    this.original = original;
    this.imageResizerListener = l;

    //If the image is too small, let's just not deal with it
    if (!checkSize(original)) {
      dispose();
      throw new ImageResizeException(MessageText.getString(
          "ImageResizer.image.too.small", new String[] {
            minWidth + "",
            minHeight + ""
          }));
    }

    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;
    } else {
      result = computeResultImage();
      l.imageResized(result);
    }
  }

  private void initUI() {

    cursor = new Cursor(display, SWT.CURSOR_HAND);

    if (parent != null) {
      shell = ShellFactory.createShell(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
    } else {
      shell = ShellFactory.createMainShell(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;
        shell = null;
        dispose();
        imageResizerListener.imageResized(result);
      }
    });

    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(MessageText.getString("ImageResizer.title"));

    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(MessageText.getString("ImageResizer.move.image.with.slider"));
    } else {
      label.setText(MessageText.getString("ImageResizer.move.image"));
    }

    // (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;
        dispose();
        imageResizerListener.imageResized(result);
      }
    });

    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;
        dispose();
        imageResizerListener.imageResized(result);
      }
    });

    shell.setDefaultButton(btnOk);
    btnOk.setFocus();
    shell.setSize(shell.computeSize(SWT.DEFAULT, SWT.DEFAULT));

    if (parent != null) {
      Utils.centerWindowRelativeTo(shell, parent);
    }

    shell.open();
    drawCurrentImage();

  }

  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 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;
  }

  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 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 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 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(final byte marginAlpha,
      final int marginColor, final byte borderAlpha, final 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 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 interface ImageResizerListener {
    void imageResized(Image image);
  }

  public static void main(final String args[]) throws Exception {
    final Display display = Display.getDefault();
    final 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);
    resizer.resize(img, new  ImageResizerListener() {
      public void imageResized(Image thumbnail) {
        System.out.println(thumbnail);
       
        thumbnail.dispose();
        test.dispose();
        if (args.length == 0) {
          display.dispose();
        }
      }
    });

  }
}
TOP

Related Classes of com.aelitis.azureus.ui.swt.utils.ImageResizer$ImageResizerListener

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.