Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Created a High-Res screenshot option to gui. #85

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package de.piegames.blockmap.gui;

import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

import org.joml.AABBd;

import javafx.concurrent.Task;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.SnapshotParameters;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.image.Image;
import javafx.scene.image.WritableImage;
import javafx.scene.paint.Color;

/**
* Handles the creation of high-resolution screenshots of maps.
*/
public class ScreenshotHandler {

/**
* Take a high-resolution screenshot of a section of them map
* @param map Map to use.
* @param frustum Bounds of the image.
* @return The captured image.
*/
public static WritableImage takeScreenshot(RenderedMap map, AABBd frustum) {
double width = frustum.maxX - frustum.minX;
double height = frustum.maxY - frustum.minY;

Canvas canvas = new Canvas(width, height);
GraphicsContext gc = canvas.getGraphicsContext2D();
gc.translate(-frustum.minX, -frustum.minY);

map.draw(gc, 0, frustum, 1);

SnapshotParameters parameters = new SnapshotParameters();
parameters.setFill(Color.TRANSPARENT);

return canvas.snapshot(parameters, null);
}

/**
* Save a JavaFX image out to a file in PNG format.
*
* @param image Image to save.
* @param file File to save to.
* @throws IOException If an IO exception occurs while writing the file.
*/
public static void saveImage(Image image, File file) throws IOException {
ImageIO.write(SwingFXUtils.fromFXImage(image, null), "png", file);
}

public static Task<Void> saveImageTask(Image image, File file) {
Task<Void> task = new Task<Void>() {

@Override
protected Void call() throws Exception {
saveImage(image, file);
return null;
}

};
return task;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@ public void render() {
// gc.strokeRect(0, 0, getWidth() - 0, getHeight() - 0);
}

public RenderedMap getMap() {
return map;
}

public ReadOnlyMapProperty<Vector2ic, Map<Vector2ic, ChunkMetadata>> getChunkMetadata() {
return chunkMetadata.getReadOnlyProperty();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package de.piegames.blockmap.gui.standalone;

import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
Expand All @@ -12,6 +13,7 @@
import java.util.Map;
import java.util.ResourceBundle;
import java.util.concurrent.Executors;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
Expand All @@ -21,12 +23,14 @@
import org.controlsfx.control.CheckTreeView;
import org.controlsfx.control.StatusBar;
import org.controlsfx.dialog.ExceptionDialog;
import org.controlsfx.dialog.ProgressDialog;
import org.joml.Vector2d;
import org.joml.Vector2ic;

import com.google.common.util.concurrent.ThreadFactoryBuilder;

import de.piegames.blockmap.gui.MapPane;
import de.piegames.blockmap.gui.ScreenshotHandler;
import de.piegames.blockmap.gui.WorldRendererCanvas;
import de.piegames.blockmap.gui.decoration.DragScrollDecoration;
import de.piegames.blockmap.gui.decoration.GridDecoration;
Expand All @@ -49,6 +53,7 @@
import javafx.beans.value.ChangeListener;
import javafx.collections.FXCollections;
import javafx.collections.MapChangeListener;
import javafx.concurrent.Task;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Alert;
Expand All @@ -57,12 +62,17 @@
import javafx.scene.control.CheckBox;
import javafx.scene.control.CheckBoxTreeItem;
import javafx.scene.control.Label;
import javafx.scene.control.MenuItem;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.TitledPane;
import javafx.scene.control.TreeItem;
import javafx.scene.image.ImageView;
import javafx.scene.image.WritableImage;
import javafx.scene.input.MouseButton;
import javafx.scene.layout.BorderPane;
import javafx.stage.FileChooser;
import javafx.stage.Modality;
import javafx.stage.FileChooser.ExtensionFilter;
import javafx.util.Duration;
import javafx.util.Pair;

Expand Down Expand Up @@ -111,6 +121,11 @@ static enum WorldType {
public CheckTreeView<PinType> pinView;
public Map<PinType, TreeItem<PinType>> checkedPins = new HashMap<>();

/* Menu Bar */
@FXML
protected MenuItem screenshotButton;


protected MapPane pane;
public PinDecoration pins;

Expand Down Expand Up @@ -265,6 +280,14 @@ public void initialize(URL location, ResourceBundle resources) {
if (change.getValueAdded() != null)
GuiController.this.pins.loadRegion(change.getKey(), Pin.convertDynamic(change.getValueAdded(), renderer.viewport));
});

regionFolder.addListener((e, old, val) -> {
if (val == null) {
screenshotButton.setDisable(true);
} else {
screenshotButton.setDisable(false);
}
});
}

/**
Expand Down Expand Up @@ -367,6 +390,32 @@ public void load(String input) {
alert.showAndWait();
}

@FXML
public void screenshot() {
WritableImage image = ScreenshotHandler.takeScreenshot(renderer.getMap(), renderer.viewport.getFrustum());
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("Save Screenshot");
fileChooser.getExtensionFilters().add(new ExtensionFilter("PNG Files", "*.png"));
File file = fileChooser.showSaveDialog(null);
if (file != null) {

Task<Void> task = ScreenshotHandler.saveImageTask(image, file);
task.setOnFailed(value -> {
log.error("Unable to save screenshot.", task.getException());
ExceptionDialog d = new ExceptionDialog(task.getException());
d.setTitle("Error");
d.setHeaderText("Unable to save screenshot.");
d.showAndWait();
});

ProgressDialog progress = new ProgressDialog(task);
progress.setTitle("Saving");
progress.setHeaderText("Saving screenshot");
progress.initModality(Modality.APPLICATION_MODAL);
ForkJoinPool.commonPool().execute(task::run);
}
}

@FXML
public void showLoadDialog() {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@
shortcut="UP" />
</accelerator>
</MenuItem>
<MenuItem
text="Screenshot"
onAction="#screenshot"
disable="true"
fx:id="screenshotButton">
</MenuItem>
<MenuItem
text="Quit"
onAction="#exit">
Expand Down