Package de.chris_soft.fyllgen.widget.dialog

Source Code of de.chris_soft.fyllgen.widget.dialog.ImageCutDialog

/**
* FyLLGen - A Java based tool for collecting and distributing family data
*
* Copyright (C) 2007-2011 Christian Packenius
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package de.chris_soft.fyllgen.widget.dialog;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.MouseWheelListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.events.ShellListener;
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.Rectangle;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Dialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

import de.chris_soft.fyllgen.GUI;
import de.chris_soft.fyllgen.Statics;
import de.chris_soft.fyllgen.utilities.SwtConsts;
import de.chris_soft.fyllgen.utilities.SwtUtilities;

/**
* Zurechtschneiden eines Images, damit es als Portrait eingebunden werden kann.
* @author Christian Packenius, 20110905.
*/
public class ImageCutDialog extends Dialog implements SelectionListener, PaintListener, ShellListener,
    MouseWheelListener, MouseListener, MouseMoveListener {
  /**
   * Das eigentliche Fenster-Objekt.
   */
  private Shell shell;

  /**
   * Button, um eine angew�hlte Person zu verwenden.
   */
  private Button buttonUse;

  /**
   * Canvas, in dem eventuell ein Image angezeigt wird.
   */
  private Canvas canvasImage;

  /**
   * Zu beschneidendes Image.
   */
  private File image2view;

  /**
   * Original-Image.
   */
  private Image image;

  /**
   * Name des beschnittenen Bildes.
   */
  public String newImageName = null;

  /**
   * Gr��e des Canvas mit dem Image - wird beim �ffnen gesetzt.
   */
  private Rectangle canvasSize;

  /**
   * Faktor, mit dem die Imagegr��e vor der Anzeige multipliziert wird.
   */
  private double imageFactor;

  /**
   * X-Koordinate f�r die Darstellung.
   */
  private int imageX;

  /**
   * Y-Koordinate f�r die Darstellung.
   */
  private int imageY;

  /**
   * Gr��e des Images.
   */
  private Rectangle imageBounds;

  /**
   * Verschiedene Koordinaten.
   */
  private int mouseX = -1, mouseY = -1, imageOldX, imageOldY;

  /**
   * Verschiedene Rechtecksangaben.
   */
  private Rectangle portraitBounds, portraitBounds1, portraitBounds2;

  /**
   * Gr��e des vergr��erten/verkleinerten Images.
   */
  private int resizedWidth, resizedHeight;

  /**
   * Breite der erzeugten Portraitfotos.
   */
  private int portraitWidth = 97;

  /**
   * H�he der erzeugten Portraitfotos.
   */
  private int portraitHeight = 128;

  /**
   * Angabe, ob das Portrait in Graustufen umgewandelt werden soll.
   */
  private boolean intoGray = true;

  /**
   * Konstruktor. Erzeugt das Fenster, ohne es anzuzeigen.
   * @param parent Parent-Shell, �ber der dieser Dialog angezeigt wird.
   * @param imageFile Image-Datei, die zu editieren ist.
   * @throws IOException Probleme beim Laden des Images.
   */
  public ImageCutDialog(Shell parent, File imageFile) throws IOException {
    super(parent, 0);
    image2view = imageFile;

    FileInputStream in = new FileInputStream(image2view);
    image = new Image(SwtConsts.display, new ImageData(in));
    in.close();

    shell = new Shell(parent, SWT.CLOSE | SWT.TITLE | SWT.APPLICATION_MODAL);
    shell.setImage(GUI.instance.shellIcon);
    shell.addShellListener(this);
    shell.setText("Portrait festlegen");
    shell.setSize(700, 500);
    shell.addMouseWheelListener(this);

    // Noch mittig ins vorhandene Fenster setzen.
    SwtUtilities.centerInParent(shell, parent);

    // Shell hat innen einen Rahmen.
    FormLayout shellLayout = new FormLayout();
    shellLayout.marginBottom = shellLayout.marginLeft = shellLayout.marginRight = shellLayout.marginTop = 5;
    shell.setLayout(shellLayout);

    // Innen ein Composite.
    Composite inner = new Composite(shell, 0);
    FormLayout innerLayout = new FormLayout();
    inner.setLayout(innerLayout);
    FormData fd = new FormData();
    fd.top = new FormAttachment(0, 0);
    fd.left = new FormAttachment(0, 0);
    fd.right = new FormAttachment(100, 0);
    fd.bottom = new FormAttachment(100, 0);
    inner.setLayoutData(fd);

    // Button zum Verwenden der in der Liste angeklickten Person erzeugen.
    buttonUse = new Button(inner, SWT.PUSH);
    buttonUse.setText("�bernehmen");
    fd = new FormData();
    fd.left = new FormAttachment(0, 0);
    fd.right = new FormAttachment(100, 0);
    fd.bottom = new FormAttachment(100, 0);
    buttonUse.setLayoutData(fd);
    buttonUse.addSelectionListener(this);
    buttonUse.setEnabled(true);
    buttonUse.addMouseWheelListener(this);

    // Darstellung eines Images.
    canvasImage = new Canvas(inner, 0);
    fd = new FormData();
    fd.top = new FormAttachment(0, 0);
    fd.right = new FormAttachment(100, 0);
    fd.bottom = new FormAttachment(buttonUse, -5, SWT.TOP);
    fd.left = new FormAttachment(0, 0);
    canvasImage.setLayoutData(fd);
    canvasImage.addPaintListener(this);
    canvasImage.addMouseWheelListener(this);
    canvasImage.addMouseListener(this);
    canvasImage.addMouseMoveListener(this);
  }

  /**
   * Shell sichtbar machen. Vorher aber alle Personen in die Liste einf�gen.
   */
  public void open() {
    portraitBounds2 = portraitBounds1 = portraitBounds = imageBounds = canvasSize = new Rectangle(0, 0, 2, 2);
    shell.open();
    canvasSize = canvasImage.getBounds();
    portraitBounds = new Rectangle(canvasSize.width / 2 - portraitWidth / 2,
        canvasSize.height / 2 - portraitHeight / 2, portraitWidth, portraitHeight);
    portraitBounds1 = new Rectangle(portraitBounds.x - 1, portraitBounds.y - 1, portraitBounds.width + 2,
        portraitBounds.height + 2);
    portraitBounds2 = new Rectangle(portraitBounds1.x - 1, portraitBounds1.y - 1, portraitBounds1.width + 2,
        portraitBounds1.height + 2);

    initImageSize();
    canvasImage.redraw();

    // Ereignis-Liste abarbeiten.
    while (!shell.isDisposed()) {
      if (!SwtConsts.display.readAndDispatch()) {
        SwtConsts.display.sleep();
      }
    }
  }

  private void initImageSize() {
    imageBounds = image.getBounds();
    imageFactor = 1;// Math.max(fWidth, fHeight);
    imageX = (canvasSize.width - imageBounds.width) / 2;
    imageY = (canvasSize.height - imageBounds.height) / 2;
    resizedWidth = imageBounds.width;
    resizedHeight = imageBounds.height;
  }

  /**
   * @see org.eclipse.swt.events.ShellListener#shellActivated(org.eclipse.swt.events.ShellEvent)
   */
  public void shellActivated(ShellEvent e) {
    // Ignorieren.
  }

  /**
   * @see org.eclipse.swt.events.ShellListener#shellClosed(org.eclipse.swt.events.ShellEvent)
   */
  public void shellClosed(ShellEvent e) {
    shell.removeShellListener(this);
    image.dispose();
  }

  /**
   * @see org.eclipse.swt.events.ShellListener#shellDeactivated(org.eclipse.swt.events.ShellEvent)
   */
  public void shellDeactivated(ShellEvent e) {
    // Ignorieren.
  }

  /**
   * @see org.eclipse.swt.events.ShellListener#shellDeiconified(org.eclipse.swt.events.ShellEvent)
   */
  public void shellDeiconified(ShellEvent e) {
    // Ignorieren.
  }

  /**
   * @see org.eclipse.swt.events.ShellListener#shellIconified(org.eclipse.swt.events.ShellEvent)
   */
  public void shellIconified(ShellEvent e) {
    // Ignorieren.
  }

  /**
   * Ein Button wurde gedr�ckt.
   * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
   */
  public void widgetDefaultSelected(SelectionEvent e) {
    testButtonsPressed(e);
  }

  /**
   * Ein Button wurde gedr�ckt.
   * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
   */
  public void widgetSelected(SelectionEvent e) {
    testButtonsPressed(e);
  }

  /**
   * Pr�ft, ob einer der Buttons gedr�ckt wurde.
   */
  private void testButtonsPressed(SelectionEvent e) {
    if (e.widget == buttonUse) {
      Image helperImage = new Image(SwtConsts.display, portraitWidth, portraitHeight);
      GC gc = new GC(helperImage);
      gc.drawImage(image, 0, 0, imageBounds.width, imageBounds.height, imageX - portraitBounds.x, imageY
          - portraitBounds.y, resizedWidth, resizedHeight);
      gc.dispose();
      Image grayImage = null;
      if (intoGray) {
        grayImage = new Image(SwtConsts.display, helperImage, SWT.IMAGE_GRAY);
        helperImage.dispose();
      }
      else {
        grayImage = helperImage;
      }
      ImageLoader io = new ImageLoader();
      io.data = new ImageData[] { grayImage.getImageData() };
      newImageName = Statics.getUniqueID() + ".png";
      new File("images").mkdir();
      io.save("images/" + newImageName, SWT.IMAGE_PNG);
      grayImage.dispose();
      shell.dispose();
    }
  }

  /**
   * Das Bild soll neu gezeichnet werden.
   * @see org.eclipse.swt.events.PaintListener#paintControl(org.eclipse.swt.events.PaintEvent)
   */
  public void paintControl(PaintEvent e) {
    // Das eigentliche Bild vergr��ert/verkleinert und verschoben darstellen.
    e.gc.drawImage(image, 0, 0, imageBounds.width, imageBounds.height, imageX, imageY, resizedWidth, resizedHeight);

    // Schwarz/wei�-Rahmen f�r das Grau-Portrait.
    e.gc.setForeground(SwtConsts.COLOR_WHITE);
    e.gc.drawRectangle(portraitBounds1);
    e.gc.setForeground(SwtConsts.COLOR_BLACK);
    e.gc.drawRectangle(portraitBounds2);

    // Den Mittelteil als Portrait grau darstellen.
    Image helperImage = new Image(SwtConsts.display, portraitWidth, portraitHeight);
    GC gc = new GC(helperImage);
    gc.drawImage(image, 0, 0, imageBounds.width, imageBounds.height, imageX - portraitBounds.x, imageY
        - portraitBounds.y, resizedWidth, resizedHeight);
    gc.dispose();
    Image grayImage = null;
    if (intoGray) {
      grayImage = new Image(SwtConsts.display, helperImage, SWT.IMAGE_GRAY);
      helperImage.dispose();
    }
    else {
      grayImage = helperImage;
    }
    e.gc.drawImage(grayImage, portraitBounds.x, portraitBounds.y);
    grayImage.dispose();
  }

  /**
   * Scrollen des Mausrades f�hrt zu einer Vergr��erung/Verkleinerung des
   * Bildes. Der Zoom wird gleichzeitig derart verschoben, dass das Zentrum des
   * Bildes bestehen bleibt.
   * @see org.eclipse.swt.events.MouseWheelListener#mouseScrolled(org.eclipse.swt.events.MouseEvent)
   */
  public void mouseScrolled(MouseEvent e) {
    double percentX = ((double) canvasSize.width / 2 - imageX) / resizedWidth;
    double percentY = ((double) canvasSize.height / 2 - imageY) / resizedHeight;
    if (e.count > 0) {
      imageFactor *= 1.05;
    }
    else if (e.count < 0) {
      imageFactor /= 1.05;
    }
    resizedWidth = (int) (imageBounds.width * imageFactor + .5);
    resizedHeight = (int) (imageBounds.height * imageFactor + .5);
    imageX = (int) ((double) canvasSize.width / 2 - percentX * resizedWidth);
    imageY = (int) ((double) canvasSize.height / 2 - percentY * resizedHeight);
    canvasImage.redraw();
  }

  /**
   * Doppelklick bleibt ungenutzt.
   * @see org.eclipse.swt.events.MouseListener#mouseDoubleClick(org.eclipse.swt.events.MouseEvent)
   */
  public void mouseDoubleClick(MouseEvent e) {
    // Methodenaufruf wird ignoriert.
  }

  /**
   * Das Bild soll verschoben werden. Dies wird hier initiiert.
   * @see org.eclipse.swt.events.MouseListener#mouseDown(org.eclipse.swt.events.MouseEvent)
   */
  public void mouseDown(MouseEvent e) {
    mouseX = e.x;
    mouseY = e.y;
    imageOldX = imageX;
    imageOldY = imageY;
  }

  /**
   * Das Bild wurde zu Ende verschoben.
   * @see org.eclipse.swt.events.MouseListener#mouseUp(org.eclipse.swt.events.MouseEvent)
   */
  public void mouseUp(MouseEvent e) {
    mouseX = -1;
    mouseY = -1;
  }

  /**
   * Wenn die Maus bei gedr�ckter Maustaste bewegt wird, verschiebt sich das
   * Bild.
   * @see org.eclipse.swt.events.MouseMoveListener#mouseMove(org.eclipse.swt.events.MouseEvent)
   */
  public void mouseMove(MouseEvent e) {
    if (mouseX >= 0) {
      imageX = imageOldX + e.x - mouseX;
      imageY = imageOldY + e.y - mouseY;
      canvasImage.redraw();
    }
  }

  /**
   * Dieser Dialog kann auch als eigenst�ndige Applikation gestartet werden.
   * @param args
   * @throws IOException
   */
  public static void main(String[] args) throws IOException {
    Display display = Display.getDefault();
    Shell shell = new Shell(display);

    // Properties-File einlesen.
    Properties props = new Properties();
    props.setProperty("portraitX", "97");
    props.setProperty("portraitY", "128");
    int width = 97;
    int height = 128;
    boolean intoGray = true;
    try {
      FileInputStream in = new FileInputStream("size.properties");
      props.load(in);
      in.close();
      width = Integer.parseInt(props.getProperty("portraitX"));
      height = Integer.parseInt(props.getProperty("portraitY"));
      intoGray = props.getProperty("intoGray").equals("true");
    }
    catch (Exception e) {
      // Ignorieren.
    }

    // Alle Bilder im aktuellen Verzeichnis finden.
    for (File file : new File(".").listFiles()) {
      String filename = file.getName();
      if (filename.toLowerCase().endsWith(".jpg") || filename.toLowerCase().endsWith(".png")) {
        ImageCutDialog icd = null;
        do {
          icd = new ImageCutDialog(shell, file);
          icd.portraitWidth = width;
          icd.portraitHeight = height;
          icd.intoGray = intoGray;
          icd.newImageName = null;
          icd.open();
        } while (icd.newImageName != null);
      }
    }

    shell.dispose();
    display.dispose();
  }
}
TOP

Related Classes of de.chris_soft.fyllgen.widget.dialog.ImageCutDialog

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.