Commit 4588e9b0 authored by kirandjiska's avatar kirandjiska

Added zoom box view on ConstraintsSelectionDialog

parent 927a9cbb
package mustic.gui.dialog.classifier;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JWindow;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class ZoomBoxView extends JPanel {
/**
*
*/
private static final long serialVersionUID = 1L;
protected static final int ZOOM_AREA = 40;
// private BufferedImage originalImage;
private JWindow popup;
private Boolean zoomBoxActivated = false;
private ConstraintsSelectionDialog dialog = null;
private BufferedImage buffer;
private float zoomLevel = 4f;
public ZoomBoxView(ConstraintsSelectionDialog dialog) {
this.dialog = dialog;
popup = new JWindow();
popup.setLayout(new BorderLayout());
popup.add(this);
popup.pack();
popup.setAlwaysOnTop(true);
MouseAdapter ma = new MouseAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
Point p = e.getPoint();
// System.out.println(p);
Point pos = e.getLocationOnScreen();
Point origPoint = getOriginalPointCoordinates(p); // get the original position of the point coordinate on the zoomed image
updateBuffer(origPoint);
// popup.setLocation(pos.x + 16, pos.y + 16);
popup.setLocation(pos.x - popup.getWidth()/2, pos.y - popup.getHeight()/2);
repaint();
}
@Override
public void mouseEntered(MouseEvent e) {
if (zoomBoxActivated) {
popup.setVisible(true);
}
}
@Override
public void mouseExited(MouseEvent e) {
popup.setVisible(false);
}
};
dialog.getImgLabel().addMouseListener(ma);
dialog.getImgLabel().addMouseMotionListener(ma);
}
/** p - cursor coordinates relative to parent window*/
/**private void updateBuffer(Point p) {
int width = Math.round(ZOOM_AREA);
int height = Math.round(ZOOM_AREA);
buffer = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d =(Graphics2D) originalImage.getGraphics();
AffineTransform at = new AffineTransform();
// center cursor in the zoomBox
int xPos = (ZOOM_AREA / 2) - p.x;
int yPos = (ZOOM_AREA / 2) - p.y;
if (xPos > 0) {
xPos = 0;
}
if (yPos > 0) {
yPos = 0;
}
// if outside the parent window
// fix parent size on original image size
if ((xPos * -1) + ZOOM_AREA > parent.getWidth()) {
xPos = (parent.getWidth() - ZOOM_AREA) * -1;
}
if ((yPos * -1) + ZOOM_AREA > parent.getHeight()) {
yPos = (parent.getHeight()- ZOOM_AREA) * -1;
}
at.translate(xPos, yPos);
g2d.setTransform(at);
parent.paint(g2d);
g2d.dispose();
}*/
private void updateBuffer(Point p) {
int width = Math.round(ZOOM_AREA);
int height = Math.round(ZOOM_AREA);
buffer = dialog.getImage().getSubimage(p.x - ZOOM_AREA/2, p.y - ZOOM_AREA/2, width, height);
//rajoute condition s'il sort dehors
}
@Override
public Dimension getPreferredSize() {
return new Dimension(Math.round(ZOOM_AREA * zoomLevel), Math.round(ZOOM_AREA * zoomLevel));
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
if (buffer != null) {
AffineTransform at = g2d.getTransform();
g2d.setTransform(AffineTransform.getScaleInstance(zoomLevel, zoomLevel));
g2d.drawImage(buffer, 0, 0, this);
g2d.setTransform(at);
}
g2d.setColor(Color.RED);
g2d.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
g2d.drawLine(getWidth()/2-1, 0, getWidth()/2-1, getHeight()-1);
g2d.drawLine(0,getHeight()/2-1,getWidth()-1,getHeight()/2-1 );
g2d.drawRect(getWidth()/2-1-4, getHeight()/2-1-4, 8, 8);
g2d.dispose();
}
protected void setZoomBoxVisibility(boolean visibility) {
popup.setVisible(visibility);
zoomBoxActivated = visibility;
}
private Point getOriginalPointCoordinates(Point p) {
//point coordinated relative to original image
int x = (int) ((p.getX()
- (int) ((dialog.getImgLabel().getWidth() - (dialog.getImgLabel().getIcon().getIconWidth())) / 2.0)) / dialog.getmZoomRate());
int y = (int) ((p.getY()
- (int) ((dialog.getImgLabel().getHeight() - (dialog.getImgLabel().getIcon().getIconHeight())) / 2.0)) / dialog.getmZoomRate());
// if (x >= 0 && y >= 0 && x < originalImage.getWidth() * zoomLevel
// && y < originalImage.getHeight() * zoomLevel) {
return new Point(x,y);
}
}
package mustic.gui.dialog.classifier;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class ZoomBoxWindow /*extends JPanel*/ {
private ConstraintsSelectionDialog dialog = null;
private Point zoomPoint; // cursor point relative to img panel
private boolean zoomEnabled = true; // a variable indicating if the zoom box panel is enabled
private int zoomArea = 80; // size of zoom box panel
private float zoom = 2.0f; // zoomRate
public ZoomBoxWindow(ConstraintsSelectionDialog dialog) {
this.dialog = dialog;
MouseAdapter ma = new MouseAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
zoomPoint = getOriginalPointCoordinates(e.getPoint()); // at every mouse motion get coordinates of cursor point and repaint the zoom box panel
// System.out.println("ZoomPoint on mouse motion " + zoomPoint);
paintZoomBox();
// repaint(); //calls paintComponent()
// dialog.getImgLabel().validate();
// dialog.getImgLabel().repaint();
}
@Override
public void mouseEntered(MouseEvent e) {
if (zoomEnabled) {
// repaint();
paintZoomBox();
// dialog.getImgLabel().repaint();
}
}
@Override
public void mouseExited(MouseEvent e) {
zoomPoint = null;
// repaint();
paintZoomBox();
// dialog.getImgLabel().repaint();
}
};
dialog.getImgLabel().addMouseListener(ma);
dialog.getImgLabel().addMouseMotionListener(ma);
}
public float getZoom() {
return zoom;
}
public void setZoom(float zoom) {
this.zoom = zoom;
paintZoomBox();
dialog.getImgLabel().repaint();
}
public int getZoomArea() {
return zoomArea;
}
public void setZoomArea(int zoomArea) {
this.zoomArea = zoomArea;
paintZoomBox();
dialog.getImgLabel().repaint();
}
public boolean isZoomEnabled() {
return zoomEnabled;
}
public void setZoomEnabled(boolean zoomEnabled) {
this.zoomEnabled = zoomEnabled;
paintZoomBox();
dialog.getImgLabel().repaint();
}
// @Override
// public Dimension getPreferredSize() {
// return new Dimension(Math.round(zoomArea * zoom), Math.round(zoomArea * zoom));
// }
//offset of image relative to JLabel
protected Point getOffset() {
if (dialog.getImage() == null) {
return new Point(0, 0);
}
int x = (dialog.getImgLabel().getWidth() - dialog.getImgLabel().getIcon().getIconWidth()) / 2;
int y = (dialog.getImgLabel().getHeight() - dialog.getImgLabel().getIcon().getIconHeight()) / 2;
return new Point(x, y);
}
// set a rectangle frame around image
// create bounds of image size, the offset needed is the offset of the getOffset function
// return this rectangle frame
protected Rectangle getImageBounds() {
Rectangle bounds = new Rectangle(0, 0, 0, 0);
if (dialog.getImage() != null) {
bounds.setLocation(getOffset());
bounds.setSize(dialog.getImage().getWidth(), dialog.getImage().getHeight());
}
return bounds;
}
//method called on mouse motion
protected void paintZoomBox() {
if(dialog.getImage() != null) {
Graphics g2d = dialog.getImage().getGraphics(); // get parent image graphics
if(zoomPoint != null) {
BufferedImage zoomBuffer = updateBuffer(zoomPoint); // create the zoomed image
if(zoomBuffer != null) {
Rectangle bounds = getZoomBounds();
System.out.println(zoomPoint);
System.out.println(bounds);
g2d.drawImage(zoomBuffer, bounds.x, bounds.y,100,100, null); // draw zoomed image on top of the another
g2d.setColor(Color.RED);
g2d.drawRect(bounds.x, bounds.y,bounds.width,bounds.height);
}
}
// g2d.dispose();
}
}
/** @Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (img != null) {
Graphics2D g2d = (Graphics2D) g.create();
Point offset = getOffset();
g2d.drawImage(img, offset.x, offset.y, this);
if (zoomPoint != null) { // if clicked inside image bounds
BufferedImage zoomBuffer = updateBuffer(zoomPoint); // create the zoomed image
if (zoomBuffer != null) {
Rectangle bounds = getZoomBounds();
g2d.drawImage(zoomBuffer, bounds.x, bounds.y, this);
g2d.setColor(Color.RED);
g2d.draw(bounds); // draw a red rectangle frame around zoom box panel
}
}
g2d.dispose();
}
}*/
protected Rectangle getZoomBounds() {
Rectangle bounds = null;
if (zoomPoint != null && dialog.getImage() != null) {
int zoomArea = getZoomArea();
//top left point of zoom box panel
int xPos = zoomPoint.x - (zoomArea / 2);
int yPos = zoomPoint.y - (zoomArea / 2);
//create a rectangle around zoom box panel
Rectangle zoomBounds = new Rectangle(xPos, yPos, zoomArea, zoomArea);
Rectangle imageBounds = getImageBounds();
// a voir
bounds = imageBounds.intersection(zoomBounds);
System.out.println(bounds);
}
return bounds;
}
//create a zoomed picture
protected BufferedImage updateBuffer(Point p) {
if (zoomPoint == null) {
return null;
}
Rectangle bounds = getZoomBounds(); // rectangle around zoom box panel
Point offset = getOffset(); // top left point of image
bounds.translate(-offset.x, -offset.y); // move rectangle to position (-offset.x, -offset.y) A VOIR?
if (bounds.x < 0 || bounds.y < 0 || bounds.width <= 0 || bounds.height <= 0) {
return null;
}
BufferedImage zoomBuffer = new BufferedImage(bounds.width, bounds.height, BufferedImage.TYPE_INT_ARGB); // A VOIR
Graphics2D g2d = zoomBuffer.createGraphics();
BufferedImage sample = dialog.getImage().getSubimage(bounds.x, bounds.y, bounds.width, bounds.height); //get subimage of image of size zoom box panel starting of its location
double zoom = getZoom();
//scale the image of rate bounds.width(height) * zoom along the x(y)axis
Image scaled = sample.getScaledInstance((int) (bounds.width * zoom), (int) (bounds.height * zoom), Image.SCALE_SMOOTH);
g2d.drawImage(scaled, 0, 0, null); // draw scaled image inside of zoomBuffer image bounds
g2d.dispose();
return zoomBuffer;
}
protected void setZoomBoxVisibility(boolean visibility) {
// popup.setVisible(visibility);
zoomEnabled = visibility;
}
private Point getOriginalPointCoordinates(Point p) {
//point coordinated relative to original image
int x = (int) ((p.getX()
- (int) ((dialog.getImgLabel().getWidth() - (dialog.getImgLabel().getIcon().getIconWidth())) / 2.0)) / dialog.getmZoomRate());
int y = (int) ((p.getY()
- (int) ((dialog.getImgLabel().getHeight() - (dialog.getImgLabel().getIcon().getIconHeight())) / 2.0)) / dialog.getmZoomRate());
// if (x >= 0 && y >= 0 && x < originalImage.getWidth() * zoomLevel
// && y < originalImage.getHeight() * zoomLevel) {
return new Point(x,y);
}
}
package mustic.gui.tools;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import javax.swing.JPanel;
/**
* Creates a zoom box over a displayed image
*
* @author Marija Kirandjiska
*
*/
public class ZoomBoxPanel extends JPanel{
/** */
private static final long serialVersionUID = 1L;
private Point zoomPoint;
private Zoomable dialog;
private float zoom = 2.0f;
private int zoomArea = 120;
private boolean zoomBoxEnabled = false;
public ZoomBoxPanel(Zoomable dialog, float zoom, int zoomArea) {
this(dialog);
this.zoom = zoom;
this.zoomArea = zoomArea;
}
public ZoomBoxPanel(Zoomable dialog) {
this.dialog = dialog;
addMouseMotionListener(new MouseAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
zoomPoint = e.getPoint();
// method paintComponent() called
repaint();
}
});
addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
// method paintComponent() called
repaint();
}
@Override
public void mouseExited(MouseEvent e) {
zoomPoint = null;
// method paintComponent() called
repaint();
}
});
}
/**
* This method paints the image and the zoom box.
* If the mouse point is out of the image bounds the zoom box is not displayed
*/
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (dialog.getDisplayedImage() != null) {
Graphics2D g2d = (Graphics2D) g.create();
Point offset = getOffset();
g2d.drawImage(dialog.getDisplayedImage(), offset.x, offset.y, this);
if (zoomBoxEnabled && zoomPoint != null) {
BufferedImage zoomBuffer = updateBuffer(/*getOriginalPointCoordinates(*/zoomPoint);
if (zoomBuffer != null) {
Rectangle bounds = getZoomBounds();
Rectangle imgBounds = getImageBounds();
if(zoomPoint.x > imgBounds.x && zoomPoint.x < offset.x + imgBounds.width && zoomPoint.y > offset.y && zoomPoint.y < offset.y + imgBounds.height) {
g2d.drawImage(zoomBuffer, bounds.x, bounds.y, this);
g2d.setColor(Color.RED);
g2d.draw(bounds);
}
}
}
g2d.dispose();
}
}
/**
* Getter of the zoom box visibility
* @return true if the zoom box is enabled,
* false otherwise
*/
public boolean zoomBoxEnabled() {
return zoomBoxEnabled;
}
/**
* Setter for the visibility of the zoom box.
*/
public void setZoomBoxEnabled(boolean zoomBoxEnabled) {
this.zoomBoxEnabled = zoomBoxEnabled;
repaint();
}
/**
* @return the offset of the image displayed in the panel
*/
protected Point getOffset() {
if (dialog.getDisplayedImage() == null) {
return new Point(0, 0);
}
int x = (getWidth() - dialog.getDisplayedImage().getWidth()) / 2;
int y = (getHeight() - dialog.getDisplayedImage().getHeight()) / 2;
return new Point(x, y);
}
/**
* @return the bounds around the image displayed in the panel
*/
protected Rectangle getImageBounds() {
Rectangle bounds = new Rectangle(0, 0, 0, 0);
if (dialog.getDisplayedImage() != null) {
bounds.setLocation(getOffset());
bounds.setSize(dialog.getDisplayedImage().getWidth(), dialog.getDisplayedImage().getHeight());
}
return bounds;
}
/**
* This method creates the zoomed image around the mouse point.
*
* @param p
* mouse point coordinates relative to the panel
*
* @return the zoomed image that fits the zoom box
*/
protected BufferedImage updateBuffer(Point p) {
if (zoomPoint == null) {
return null;
}
Rectangle bounds = getZoomBounds();
Point offset = getOffset();
bounds.x = bounds.x - offset.x;
bounds.y = bounds.y - offset.y;
// if out of bounds
if (bounds.x < 0 || bounds.y < 0 || bounds.width <= 0 || bounds.height <= 0) {
return null;
}
BufferedImage zoomBuffer = new BufferedImage(bounds.width, bounds.height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = zoomBuffer.createGraphics();
Image sample = dialog.getMatchingImage(bounds.x, bounds.y, bounds.width, bounds.height, zoom);
// if the zoom box is within image area
if(bounds.width == zoomArea && bounds.height == zoomArea) {
int srcx = (sample.getWidth(null)-bounds.width)/2;
int srcy = (sample.getHeight(null)-bounds.height)/2;
g2d.drawImage(sample, 0,0, bounds.width, bounds.height, srcx, srcy, srcx +bounds.width, srcy + bounds.height, this);
}
// if the zoom box intersects with image area
else {
// mouse point coordinates relative to image
int p1x = p.x - offset.x;
int p1y = p.y - offset.y;
int p2x;
int p2y;
// left
if(bounds.x == 0) {
// mouse point coordinates relative to subimage
p2x = p1x;
p2y = p1y - bounds.y;
}
// down
else if(bounds.y + bounds.height == dialog.getDisplayedImage().getHeight()) {
// mouse point coordinates relative to subimage
p2x = p1x - bounds.x;
p2y = p1y - bounds.y;
}
// right
else if(bounds.x + bounds.width == dialog.getDisplayedImage().getWidth()) {
// mouse point coordinates relative to subimage
p2x = p1x - bounds.x;
p2y = p1y - bounds.y;
}
// up
else {
// mouse point coordinates relative to subimage
p2x = p1x - bounds.x;
p2y = p1y;
}
// mouse point coordinates relative to zoomed subimage
int p3x = (int) (p2x*zoom);
int p3y = (int) (p2y*zoom);
// top left point of cropped area of the zoomed image
int p4x = p3x