package greenfoot.guifx.export;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.image.Image;
import javafx.scene.transform.Affine;
| Component that shows an image and supplies methods for scaling and cropping the view.
|
| @author Poul Henriksen
| @author Amjad Altadmri
|
public class ImageEditCanvas
extends Canvas{
| Original image
|
private Image image;
| Location in the original image that should be in the center of the view
|
private double x;
| Location in the original image that should be in the center of the view
|
private double y;
| Current factor to scale image with
|
private double scaleFactor = 1;
| Minimum scale factor
|
private double minScaleFactor;
| Create a new image canvas.
|
| @param width Width of this component.
| @param height Height of this component.
| @param image The image to manipulate.
|
public ImageEditCanvas(int width, int height, Image image)
{
super(width, height);
setImage(image);
}
| Set the image that should be shown on this canvas.
|
| @param image The JavaFX Image object to be assigned to the Canvas.
| It could be null.
|
public void setImage(Image image)
{
this.image = image;
if (image != null)
{
double minScaleFactorX = getWidth() / image.getWidth();
double minScaleFactorY = getHeight() / image.getHeight();
minScaleFactor = minScaleFactorX < minScaleFactorY ? minScaleFactorX : minScaleFactorY;
if (minScaleFactor > 1)
{
minScaleFactor = 1;
}
}
}
| Paints the image with the current scale and offset.
|
| @param graphics The graphics context used to paint the image.
|
public void paintImage(GraphicsContext graphics)
{
if (image != null)
{
Affine oldTx = graphics.getTransform();
final double canvasWidth = getWidth();
final double canvasHeight = getHeight();
final double imageWidth = image.getWidth();
final double imageHeight = image.getHeight();
x = ensureSuitableCoordinate(x, canvasWidth, imageWidth);
y = ensureSuitableCoordinate(y, canvasHeight, imageHeight);
double xSnapped = x;
double ySnapped = y;
if (Math.abs(scaleFactor - minScaleFactor) < .0000001)
{
double xs = (imageWidth / 2 + xSnapped) * scaleFactor;
double ys = (imageHeight / 2 + ySnapped) * scaleFactor;
final int snapThreshold = 7;
if (Math.abs(xs) < snapThreshold && Math.abs(ys) < snapThreshold)
{
xSnapped = -imageWidth / 2;
ySnapped = -imageHeight / 2;
}
}
graphics.clearRect(0, 0, canvasWidth, canvasHeight);
graphics.translate(canvasWidth / 2, canvasHeight / 2);
graphics.scale(scaleFactor, scaleFactor);
graphics.translate(xSnapped, ySnapped);
graphics.drawImage(image, 0, 0);
graphics.setTransform(oldTx);
}
}
| Study the value of a passed coordinate (i.e. x or y) to guarantee it is
| within acceptable values to keep the image reasonably within the canvas.
| The method returns the same coordinate value if it is acceptable,
| otherwise the nearest calculated value will be returned.
| The following conditions are to be met:
| - The image centers the canvas on a dimension where its edge on that
| dimension is smaller than the canvas's.
| - The image shouldn't be moved beyond the canvas's edge leaving an
| apparent background on a dimension where it is bigger than the canvas's.
|
| @param coordinate The value of a coordinate (x or y) that need to be tested.
| @param canvasEdge The length of the canvas's edge.
| @param imageEdge The length of the image's edge.
| @return The coordinate value suitable to show the image reasonably in the canvas.
|
private double ensureSuitableCoordinate(double coordinate, double canvasEdge, double imageEdge)
{
double maxCoordinate = -(canvasEdge / scaleFactor) / 2;
double minCoordinate = -(imageEdge + maxCoordinate);
if (imageEdge * scaleFactor <= canvasEdge)
{
return -imageEdge / 2;
}
if (coordinate > maxCoordinate)
{
return maxCoordinate;
}
if (coordinate < minCoordinate)
{
return minCoordinate;
}
return coordinate;
}
| Scale and move the image so that it fits within the size of the canvas.
|
public void fit()
{
x = -image.getWidth() / 2;
y = -image.getHeight() / 2;
setScale(minScaleFactor);
}
| Move the image.
|
| @param dx The shift value on the x-axis
| @param dy The shift value on the y-axis
|
public void move(double dx, double dy)
{
x += dx / scaleFactor;
y += dy / scaleFactor;
paintImage(getGraphicsContext2D());
}
| Return the current scale factor.
|
public double getScale()
{
return scaleFactor;
}
| Set the current scale factor. Will not allow the image to become
| smaller than the component.
|
| @param scaleFactor The scale factor. 1 is real size of the image.
|
public void setScale(double scaleFactor)
{
this.scaleFactor = scaleFactor;
if (scaleFactor < minScaleFactor)
{
this.scaleFactor = minScaleFactor;
}
paintImage(getGraphicsContext2D());
}
| Returns the minimum scaling that will be allowed. The minimum scaling is
| usually set so that the scaled size of the image is not smaller than the
| canvas size.
|
public double getMinimumScale()
{
return minScaleFactor;
}
}
top,
use,
map,
class ImageEditCanvas
. ImageEditCanvas
. setImage
. paintImage
. ensureSuitableCoordinate
. fit
. move
. getScale
. setScale
. getMinimumScale
197 neLoCode
+ 41 LoComm