asciiartist - src/main/java/AsciiArtistController.java
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.*;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.geometry.Insets;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.scene.image.ImageView;
import javafx.scene.image.Image;
import javafx.scene.text.Font;
import javafx.stage.FileChooser;
import javafx.stage.FileChooser.ExtensionFilter;
import javafx.stage.Stage;
import java.io.File;
public class AsciiArtistController {
private GridPane root;
private VBox assetItems;
private GridPane paramItems;
private GridPane imageDetails;
private Button selectButton;
private Button uploadButton;
private Label paramLabelBrightness;
private Slider paramSliderBrightness;
private Spinner<Integer> paramSpinnerBrightness;
private Label paramLabelContrast;
private Slider paramSliderContrast;
private Spinner<Integer> paramSpinnerContrast;
private Label paramLabelScale;
private Spinner<Double> paramSpinnerScale;
private ComboBox<String> formatSel;
private Label paramLabelSkipLine;
private Spinner<Integer> paramSpinnerSkipLine;
private FileChooser imageOpen;
private Stage primStage;
private File currentResourcePath;
private Image selImage;
private ImageView imgPreview;
private Label imageDetailsLabel;
private Label outputDetailsLabel;
private GridPane outputArea;
private TextArea outputText;
private final Processor processor;
private String returnData;
private format currentType;
public AsciiArtistController(Stage stage) {
primStage = stage;
processor = new Processor();
}
public void syncParamInputs(Slider slider, Spinner<Integer> spinner, int minValue, int maxValue) {
double sliderMin = slider.getMin();
double sliderMax = slider.getMax();
double sliderRange = sliderMax - sliderMin;
double spinnerRange = (double) maxValue - (double) minValue;
double scale = spinnerRange / sliderRange;
slider.valueProperty().addListener((obs, oldValue, newValue) -> {
double scaledValue = (newValue.doubleValue() - sliderMin) * scale + (double) minValue;
spinner.getValueFactory().setValue((int) Math.round(scaledValue));
});
spinner.valueProperty().addListener((obs, oldValue, newValue) -> {
double scaledValue = (newValue - (double) minValue) / scale + sliderMin;
slider.setValue(scaledValue);
});
formatSel.valueProperty().addListener((obs, oldValue, newValue) -> {
refreshType();
ensureVal();
});
double initialValue = (slider.getValue() - sliderMin) * scale + (double) minValue;
spinner.getValueFactory().setValue((int) Math.round(initialValue));
}
public void ensureVal() {
uploadButton.setDisable(true);
paramSpinnerScale.setDisable(true);
if (selImage != null) {
if (currentType != null) {
uploadButton.setDisable(false);
paramSpinnerScale.setDisable(false);
}
}
}
EventHandler<ActionEvent> processImageEvent = new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent actionEvent) {
processImage();
}
private void processImage() {
returnData = processor.callIJConvert(paramSpinnerContrast.getValue(), paramSpinnerBrightness.getValue(), currentType);
outputText.clear();
outputText.setText(returnData);
}
};
EventHandler<ActionEvent> selectImageEvent = new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
selectImageInterface();
}
private void selectImageInterface() {
imageOpen = new FileChooser();
imageOpen.setTitle("Select Image File");
imageOpen.getExtensionFilters().addAll(
new ExtensionFilter("Image Files", "*.png", "*.jpg"),
new ExtensionFilter("All Files", "*.*"));
File selectedFile = imageOpen.showOpenDialog(primStage);
if (selectedFile != null) {
currentResourcePath = selectedFile;
selImage = new Image(String.valueOf(currentResourcePath.toURI()));
imgPreview.setImage(selImage);
imageDetailsLabel.setText(String.valueOf(currentResourcePath.getAbsoluteFile()));
processor.setRes(currentResourcePath);
processor.setOutputScale(1);
updateOutputDetails();
}
ensureVal();
}
};
public void refreshType() {
switch (formatSel.getValue()) {
case "Alphanumeric":
currentType = format.alpha;
break;
case "Block":
currentType = format.block;
break;
default:
throw new IllegalStateException("Unexpected value: " + formatSel.getValue());
}
}
public GridPane initGetGrid() {
root = new GridPane();
assetItems = new VBox(5);
paramItems = new GridPane();
imageDetails = new GridPane();
ColumnConstraints col1 = new ColumnConstraints();
col1.setMinWidth(200);
col1.setMaxWidth(200);
col1.setHgrow(Priority.ALWAYS);
ColumnConstraints col2 = new ColumnConstraints();
col2.setHgrow(Priority.ALWAYS);
root.getColumnConstraints().addAll(col1, col2);
selectButton = new Button("Select Image");
uploadButton = new Button("Generate ASCII Art");
selectButton.setOnAction(selectImageEvent);
uploadButton.setOnAction(processImageEvent);
paramLabelBrightness = new Label("Brightness");
paramSliderBrightness = new Slider(-1, 1, 0);
paramSpinnerBrightness = new Spinner<>(-100, 100, 0);
paramLabelContrast = new Label("Contrast");
paramSliderContrast = new Slider(-1, 1, 0.01);
paramSpinnerContrast = new Spinner<>(-100, 100, 1);
paramLabelScale = new Label("Output Scale");
paramSpinnerScale = new Spinner<>(new SpinnerValueFactory.DoubleSpinnerValueFactory(0.0, 2.0, 1.0, 0.05));
paramSpinnerScale.setPrefWidth(52);
paramSpinnerScale.setEditable(true);
paramSpinnerScale.valueProperty().addListener((obs, oldValue, newValue) -> {
processor.setOutputScale(newValue);
updateOutputDetails();
});
paramLabelSkipLine = new Label("Skip Line Every...");
paramSpinnerSkipLine = new Spinner<>(new SpinnerValueFactory.IntegerSpinnerValueFactory(0, 100, 0));
paramSpinnerSkipLine.setPrefWidth(52);
paramSpinnerSkipLine.setEditable(true);
paramSpinnerSkipLine.valueProperty().addListener((obs, oldValue, newValue) -> {
processor.setSkipLineEvery(newValue);
});
paramSpinnerBrightness.setPrefWidth(52);
paramSpinnerContrast.setPrefWidth(52);
paramItems.setPrefWidth(200);
formatSel = new ComboBox<>();
formatSel.getItems().add("Alphanumeric");
formatSel.getItems().add("Block");
formatSel.setValue("Alphanumeric");
refreshType();
outputDetailsLabel = new Label("");
paramSpinnerBrightness.setEditable(true);
paramSpinnerContrast.setEditable(true);
syncParamInputs(paramSliderBrightness, paramSpinnerBrightness, -100, 100);
syncParamInputs(paramSliderContrast, paramSpinnerContrast, -100, 100);
assetItems.getChildren().addAll(selectButton, uploadButton);
paramItems.add(paramLabelBrightness, 0, 0);
paramItems.add(paramSpinnerBrightness, 1, 0);
paramItems.add(paramSliderBrightness, 0, 1, 2, 1);
paramItems.add(paramLabelContrast, 0, 2);
paramItems.add(paramSpinnerContrast, 1, 2);
paramItems.add(paramSliderContrast, 0, 3, 2, 1);
paramItems.add(formatSel, 0, 4, 2, 1);
paramItems.add(paramLabelScale, 0, 5);
paramItems.add(paramSpinnerScale, 1, 5);
paramItems.add(paramLabelSkipLine,0,6);
paramItems.add(paramSpinnerSkipLine, 1,6);
paramItems.add(outputDetailsLabel,0,7,2,1);
imgPreview = new ImageView();
imgPreview.setFitWidth(200);
imgPreview.setPreserveRatio(true);
imageDetailsLabel = new Label();
imageDetailsLabel.setMaxWidth(200);
imageDetails.add(imgPreview, 0, 0, 2, 1);
imageDetails.add(imageDetailsLabel, 0, 1, 1, 1);
outputArea = new GridPane();
outputText = new TextArea();
outputText.setFont(Font.font("Monospaced", 12));
outputText.setPrefWidth(1800);
outputText.setPrefHeight(1800);
outputText.clear();
outputArea.add(outputText, 0, 1, 1, 1);
root.setHgap(5);
root.setVgap(5);
root.setPadding(new Insets(10, 10, 10, 10));
root.add(assetItems, 0, 0, 1, 1);
root.add(paramItems, 0, 1, 1, 1);
root.add(imageDetails, 0, 2, 1, 1);
root.add(outputArea, 1, 0, 1, 3);
ensureVal();
return root;
}
private void updateOutputDetails() {
String warningText;
String resol = (processor.getOutputResX() + " x " + processor.getOutputResY());
if(processor.getNumberOfCharacters() >= 120000) {
warningText = "\nThis may take some time to process!";
} else {
warningText = "";
}
outputDetailsLabel.setText("Output Size: \n" + resol + "\nNumber of Characters (approx.):\n" + processor.getNumberOfCharacters() + warningText);
}
}