首页 / JAVA / 如何制作Javafx图像裁剪应用程序
如何制作Javafx图像裁剪应用程序
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了如何制作Javafx图像裁剪应用程序,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含7496字,纯文字阅读大概需要11分钟。
内容图文
![如何制作Javafx图像裁剪应用程序](/upload/InfoBanner/zyjiaocheng/762/2c66912da29b45018efd5dc395fc9538.jpg)
我正在为同事构建一个应用程序来裁剪图像.
我在场景生成器中使用FXML来构建GUI.用户单击按钮从他的计算机中选择图像.然后,图像显示在GUI中.用户可以在窗格中缩放和移动.最后,单击一个按钮将编辑后的图像保存到他的计算机上.但是,我真的不知道应该使用哪个库来构建应用程序.这是我第一次处理图形.我不知道如何阅读图像,裁剪图像和写图像. Javafx Canvas for Pane?除了java doc之外还有什么好的资源可以学习如何做到这一点?
解决方法:
您的问题太多,无法在StackOverflow上得到解答.我建议你先阅读official Oracle documentation about JavaFX.
但是,由于这是一个有趣的话题,这里是代码中的答案.
您需要考虑以下几点:
>使用ImageView作为容器
>如果图像较大,请使用ScrollPane
>提供选择机制
>裁剪图像本身
>将图像保存到文件,提供文件选择器对话框
这就是它.在下面的示例中,使用鼠标左键进行选择,使用鼠标右键选择裁剪上下文菜单,然后在选择边界处获取ImageView节点的快照,然后将图像保存到文件中.
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javafx.application.Application;
import javafx.embed.swing.SwingFXUtils;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Bounds;
import javafx.geometry.Rectangle2D;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.SnapshotParameters;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.ScrollPane;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.image.WritableImage;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.shape.StrokeLineCap;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import javax.imageio.ImageIO;
/**
* Load image, provide rectangle for rubberband selection. Press right mouse button for "crop" context menu which then crops the image at the selection rectangle and saves it as jpg.
*/
public class ImageCropWithRubberBand extends Application {
RubberBandSelection rubberBandSelection;
ImageView imageView;
Stage primaryStage;
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
this.primaryStage = primaryStage;
primaryStage.setTitle("Image Crop");
BorderPane root = new BorderPane();
// container for image layers
ScrollPane scrollPane = new ScrollPane();
// image layer: a group of images
Group imageLayer = new Group();
// load the image
// Image image = new Image( getClass().getResource( "cat.jpg").toExternalForm());
Image image = new Image("https://upload.wikimedia.org/wikipedia/commons/thumb/1/14/Gatto_europeo4.jpg/1024px-Gatto_europeo4.jpg");
// the container for the image as a javafx node
imageView = new ImageView( image);
// add image to layer
imageLayer.getChildren().add( imageView);
// use scrollpane for image view in case the image is large
scrollPane.setContent(imageLayer);
// put scrollpane in scene
root.setCenter(scrollPane);
// rubberband selection
rubberBandSelection = new RubberBandSelection(imageLayer);
// create context menu and menu items
ContextMenu contextMenu = new ContextMenu();
MenuItem cropMenuItem = new MenuItem("Crop");
cropMenuItem.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent e) {
// get bounds for image crop
Bounds selectionBounds = rubberBandSelection.getBounds();
// show bounds info
System.out.println( "Selected area: " + selectionBounds);
// crop the image
crop( selectionBounds);
}
});
contextMenu.getItems().add( cropMenuItem);
// set context menu on image layer
imageLayer.setOnMousePressed(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
if (event.isSecondaryButtonDown()) {
contextMenu.show(imageLayer, event.getScreenX(), event.getScreenY());
}
}
});
primaryStage.setScene(new Scene(root, 1024, 768));
primaryStage.show();
}
private void crop( Bounds bounds) {
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("Save Image");
File file = fileChooser.showSaveDialog( primaryStage);
if (file == null)
return;
int width = (int) bounds.getWidth();
int height = (int) bounds.getHeight();
SnapshotParameters parameters = new SnapshotParameters();
parameters.setFill(Color.TRANSPARENT);
parameters.setViewport(new Rectangle2D( bounds.getMinX(), bounds.getMinY(), width, height));
WritableImage wi = new WritableImage( width, height);
imageView.snapshot(parameters, wi);
// save image
// !!! has bug because of transparency (use approach below) !!!
// --------------------------------
// try {
// ImageIO.write(SwingFXUtils.fromFXImage( wi, null), "jpg", file);
// } catch (IOException e) {
// e.printStackTrace();
// }
// save image (without alpha)
// --------------------------------
BufferedImage bufImageARGB = SwingFXUtils.fromFXImage(wi, null);
BufferedImage bufImageRGB = new BufferedImage(bufImageARGB.getWidth(), bufImageARGB.getHeight(), BufferedImage.OPAQUE);
Graphics2D graphics = bufImageRGB.createGraphics();
graphics.drawImage(bufImageARGB, 0, 0, null);
try {
ImageIO.write(bufImageRGB, "jpg", file);
System.out.println( "Image saved to " + file.getAbsolutePath());
} catch (IOException e) {
e.printStackTrace();
}
graphics.dispose();
}
/**
* Drag rectangle with mouse cursor in order to get selection bounds
*/
public static class RubberBandSelection {
final DragContext dragContext = new DragContext();
Rectangle rect = new Rectangle();
Group group;
public Bounds getBounds() {
return rect.getBoundsInParent();
}
public RubberBandSelection( Group group) {
this.group = group;
rect = new Rectangle( 0,0,0,0);
rect.setStroke(Color.BLUE);
rect.setStrokeWidth(1);
rect.setStrokeLineCap(StrokeLineCap.ROUND);
rect.setFill(Color.LIGHTBLUE.deriveColor(0, 1.2, 1, 0.6));
group.addEventHandler(MouseEvent.MOUSE_PRESSED, onm ousePressedEventHandler);
group.addEventHandler(MouseEvent.MOUSE_DRAGGED, onm ouseDraggedEventHandler);
group.addEventHandler(MouseEvent.MOUSE_RELEASED, onm ouseReleasedEventHandler);
}
EventHandler<MouseEvent> onm ousePressedEventHandler = new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
if( event.isSecondaryButtonDown())
return;
// remove old rect
rect.setX(0);
rect.setY(0);
rect.setWidth(0);
rect.setHeight(0);
group.getChildren().remove( rect);
// prepare new drag operation
dragContext.mouseAnchorX = event.getX();
dragContext.mouseAnchorY = event.getY();
rect.setX(dragContext.mouseAnchorX);
rect.setY(dragContext.mouseAnchorY);
rect.setWidth(0);
rect.setHeight(0);
group.getChildren().add( rect);
}
};
EventHandler<MouseEvent> onm ouseDraggedEventHandler = new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
if( event.isSecondaryButtonDown())
return;
double offsetX = event.getX() - dragContext.mouseAnchorX;
double offsetY = event.getY() - dragContext.mouseAnchorY;
if( offsetX > 0)
rect.setWidth( offsetX);
else {
rect.setX(event.getX());
rect.setWidth(dragContext.mouseAnchorX - rect.getX());
}
if( offsetY > 0) {
rect.setHeight( offsetY);
} else {
rect.setY(event.getY());
rect.setHeight(dragContext.mouseAnchorY - rect.getY());
}
}
};
EventHandler<MouseEvent> onm ouseReleasedEventHandler = new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
if( event.isSecondaryButtonDown())
return;
// remove rectangle
// note: we want to keep the ruuberband selection for the cropping => code is just commented out
/*
rect.setX(0);
rect.setY(0);
rect.setWidth(0);
rect.setHeight(0);
group.getChildren().remove( rect);
*/
}
};
private static final class DragContext {
public double mouseAnchorX;
public double mouseAnchorY;
}
}
}
截图:
裁剪后的图片:
内容总结
以上是互联网集市为您收集整理的如何制作Javafx图像裁剪应用程序全部内容,希望文章能够帮你解决如何制作Javafx图像裁剪应用程序所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。