Skip to content

Instantly share code, notes, and snippets.

Created August 12, 2016 09:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/f978ce6f3157429944ea07b0b7fdc18f to your computer and use it in GitHub Desktop.
Save anonymous/f978ce6f3157429944ea07b0b7fdc18f to your computer and use it in GitHub Desktop.
JavaFX - Task - Affichage des pixels retouchés se bloque
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import javafx.scene.image.PixelReader;
import javafx.scene.paint.Color;
public class GraphicEngine extends Service<Void> {
Pixel pixel_buffer;
public int image_width, image_height;
private PixelReader pixel_reader;
public Task<Void> createTask() {
return new Task<Void>() {
protected Void call() {
double r, g, b;
for (int x = 0; x < image_width; x++) {
for (int y = 0; y < image_height; y++) {
r = pixel_reader.getColor(x, y).getRed() * 255;
g = pixel_reader.getColor(x, y).getGreen() * 255;
b = pixel_reader.getColor(x, y).getBlue() * 255;
pixel_buffer.setAttributes(x, y, Color.rgb((int) (255 - r), (int) (255 - g), (int) (255 - b)));
}
}
return null;
}
};
}
// <!-- GRAPHIC TREATMENTS -->
public void reverseImg() { // Cette fonction n'est jamais appelée : son CODE EST MOMENTANEMENT PLACE DANS createTask > call !!!
double r, g, b;
for(int x = 0; x < this.image_width; x++) {
for(int y = 0; y < this.image_height; y++) {
r = this.pixel_reader.getColor(x, y).getRed()*255;
g = this.pixel_reader.getColor(x, y).getGreen()*255;
b = this.pixel_reader.getColor(x, y).getBlue()*255;
//this.writable_pixel_writer.setColor(x, y, Color.rgb((int) (255 - r), (int) (255 - g), (int) (255 - b)));
}
}
}
public void setAttributes(int image_width, int image_height, PixelReader pixel_reader, Pixel pixel_buffer) {
this.image_width = image_width;
this.image_height = image_height;
this.pixel_reader = pixel_reader;
this.pixel_buffer = pixel_buffer;
}
public void setBackgroundColor(Color color) {
for(int x = 0; x < this.image_width; x++) {
for (int y = 0; y < this.image_height; y++) {
//this.writable_pixel_writer.setColor(x, y, color);
}
}
}
public void setBackgroundColorRandom() {
for(int x = 0; x < this.image_width; x++) {
for (int y = 0; y < this.image_height; y++) {
//this.writable_pixel_writer.setColor(x, y, Color.color(Math.random(), Math.random(), Math.random()));
}
}
}
public void displayHorGraduation(String type) {
double w = this.image_width;
double r = 0, g = 0, b = 0;
for(int x = 0; x < this.image_width; x++) {
for (int y = 0; y < this.image_height; y++) {
if(type.equals("Blanc vers noir")) {
//this.writable_pixel_writer.setColor(x, y, Color.color(-x/w + 1, -x/w + 1, -x/w + 1));
} else if(type.equals("Noir vers blanc")) {
//this.writable_pixel_writer.setColor(x, y, Color.color(x/w, x/w, x/w));
} else if(type.equals("Polychrome")) {
if(x >= 0 && x < w/6) {
r = 255;
g = 1530*x/w;
}
if(x >= 0 && x < 2*w/6) {
b = 0;
}
if(x >= 2*w/6 && x < 3*w/6) {
b = 1530*x/w - 510;
}
if(x >= 3*w/6 && x < 5*w/6) {
b = 255;
}
if(x >= 5*w/6 && x <= w) {
b = -1530*x/w + 1530;
}
if (x >= w/6 && x < 3*w/6) {
g = 255;
}
if(x >= 3*w/6 && x < 4*w/6) {
g = -1530*x/w + 1020;
}
if(x >= 4*w/6 && x <= w) {
g = 0;
}
if(x >= w/6 && x < 2*w/6) {
r = -1530*x/w + 510;
}
if(x >= 2*w/6 && x < 4*w/6) {
r = 0;
}
if(x >= 4*w/6 && x < 5*w/6) {
r = 1530*x/w - 1020;
}
if(x >= 5*w/6 && x <= w) {
r = 255;
}
//this.writable_pixel_writer.setColor(x, y, Color.color(r/255, g/255, b/255));
}
}
}
}
public void displayCircle() {
double pi = 3.14159;
double ra = 100, x0 = 200, y0 = 300, x, y;
double r, g, b;
double shift = 0;
double w = 2 * pi;
for (double width = 0; width < 5; width++) {
r = 0;
g = 0;
b = 0;
for (double angle = shift; angle <= (w + shift); angle += 0.00001) {
x = (width + ra) * Math.cos(angle) + x0;
y = (width + ra) * Math.sin(angle) + y0;
if (angle >= (0 + shift) && angle < (w / 6 + shift)) {
r = 255;
g = (1530 * angle / w) + (-1530 / w * shift);
}
if (angle >= (0 + shift) && angle < (2 * w / 6) + shift) {
b = 0;
}
if (angle >= (2 * w / 6 + shift) && angle < (3 * w / 6 + shift)) {
b = 1530 * angle / w + (-510 - 1530 * shift / w);
}
if (angle >= (3 * w / 6 + shift) && angle < (5 * w / 6 + shift)) {
b = 255;
}
if (angle >= (5 * w / 6 + shift) && angle <= (w + shift)) {
b = -1530 * angle / w + (1530 + 1530 * shift / w);
}
if (angle >= (w / 6 + shift) && angle < (3 * w / 6 + shift)) {
g = 255;
}
if (angle >= (3 * w / 6 + shift) && angle < (4 * w / 6 + shift)) {
g = -1530 * angle / w + (1020 + 1530 * shift / w);
}
if (angle >= (4 * w / 6 + shift) && angle <= (w + shift)) {
g = 0;
}
if (angle >= (w / 6 + shift) && angle < (2 * w / 6 + shift)) {
r = -1530 * angle / w + (510 + 1530 * shift / w);
}
if (angle >= (2 * w / 6 + shift) && angle < (4 * w / 6 + shift)) {
r = 0;
}
if (angle >= (4 * w / 6 + shift) && angle < (5 * w / 6 + shift)) {
r = 1530 * angle / w + (-1020 - 1530 * shift / w);
}
if (angle >= (5 * w / 6 + shift) && angle <= (w + shift)) {
r = 255;
}
//this.writable_pixel_writer.setColor((int) x, (int) y, Color.color(r / 255, g / 255, b / 255));
}
}
}
}
import javafx.collections.FXCollections;
import javafx.embed.swing.SwingFXUtils;
import javafx.geometry.HPos;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.*;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.FlowPane;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;
import java.util.Observable;
import java.util.Observer;
public class Gui extends Scene implements Observer {
private Stage stage;
private final String TITLE_FULL_FX = " - GraphicEngine : JAVAFX", TITLE_WITHOUT_FX = " - GraphicEngine : Java AWT";
private String STAGE_ORIGINAL_TITLE;
private BorderPane root;
private GraphicEngine graphic_engine;
private ColorPicker color_picker;
// NAV
private MenuBar menu_bar;
private Menu file;
private MenuItem open, save;
private Menu menu_create_sheet;
private MenuItem sheet_customized;
private Menu menu_create_gradation;
private MenuItem gradation_customized;
// TOP
private FlowPane top_pane;
private TextField img_path;
private Button button_load_img_from_web;
private Text or;
private Button button_load_img_from_local;
private FileChooser file_chooser;
// LEFT
private FlowPane left_pane;
private Button create_sheet;
private Text title_creation_img;
private Label label_width;
private Label label_height;
private TextField field_width;
private TextField field_height;
private FlowPane creation_img_pane;
private Button cancel_creation_img;
private Button continue_creation_img;
private CheckBox checkbox_random_color_points;
private Button button_hor_gradation;
private Button button_draw_circle;
// CENTER
private ScrollPane scroll_pane;
// RIGHT
private FlowPane right_pane;
private Button button_reverse_image;
// BOT
private FlowPane bot_pane;
private Button save_img;
private final String VERSION_WITH_MENU = "Passer à la version avec menu", VERSION_WITH_BUTTONS = "Passer à la version avec boutons";
private Button switch_mode;
// DIALOG
private Dialog dialog_gradation;
private FlowPane dialog_flowpane;
private Label dialog_label_width;
private Label dialog_label_height;
private TextField dialog_field_width;
private TextField dialog_field_height;
private ChoiceBox<String> dialog_choiceBox;
// IMAGE
private Pixel pixel_buffer;
private ImageView img_view;
private WritableImage writable_image;
private PixelReader pixel_reader;
private PixelWriter pixel_writer;
// <!-- CONSTRUCTORS -->
public Gui(Stage stage, BorderPane border_pane, int width, int height) {
super(border_pane, width, height);
this.stage = stage;
this.STAGE_ORIGINAL_TITLE = this.stage.getTitle();
this.stage.setTitle(this.STAGE_ORIGINAL_TITLE + this.TITLE_FULL_FX);
this.root = border_pane;
this.color_picker = new ColorPicker();
this.graphic_engine = new GraphicEngine();
this.pixel_buffer = new Pixel();
this.pixel_buffer.addObserver(this);
// MENU
this.menu_bar = new MenuBar();
this.menu_bar.setStyle("-fx-background-color : #e74c3c");
this.file = new Menu("Fichier");
this.open = new MenuItem("Ouvrir");
this.save = new MenuItem("Sauvegarder");
this.menu_create_sheet = new Menu("Nouvelle feuille");
this.sheet_customized = new MenuItem("Vos propres dimensions");
this.menu_create_gradation = new Menu("Nouveau dégradé");
this.gradation_customized = new MenuItem("Vos propres dimensions");
// For top pane
this.top_pane = new FlowPane();
this.top_pane.setStyle("-fx-background-color : #e74c3c");
this.img_path = new TextField("https://s3-eu-west-1.amazonaws.com/s3.housseniawriting.com/wp-content/uploads/2016/01/Google-Panda.jpg");
this.button_load_img_from_web = new Button("Charger une image Web");
this.button_load_img_from_web.setStyle("-fx-background-color : #FFF");
this.or = new Text(" OU ");
this.or.setFill(Color.WHITE);
this.button_load_img_from_local = new Button("Charger une image locale");
this.button_load_img_from_local.setStyle("-fx-background-color : #FFF");
this.file_chooser = new FileChooser();
// For left pane
this.left_pane = new FlowPane();
this.left_pane.setStyle("-fx-background-color : #e74c3c");
this.left_pane.setOrientation(Orientation.VERTICAL);
this.left_pane.setVgap(5);
this.left_pane.setColumnHalignment(HPos.CENTER);
this.create_sheet = new Button("Nouvelle feuille de dessin");
this.create_sheet.setStyle("-fx-background-color : #FFF");
this.title_creation_img = new Text("CRÉATION D'UNE IMAGE");
this.title_creation_img.setFill(Color.WHITE);
this.label_width = new Label("Largeur : ");
this.field_width = new TextField("500");
this.label_width.setTextFill(Color.WHITE);
this.label_height = new Label("Longueur : ");
this.field_height = new TextField("500");
this.label_height.setTextFill(Color.WHITE);
this.checkbox_random_color_points = new CheckBox("Points de couleur aléatoire");
this.checkbox_random_color_points.setTextFill(Color.WHITE);
this.creation_img_pane = new FlowPane();
this.creation_img_pane.setHgap(10);
this.creation_img_pane.setAlignment(Pos.CENTER);
this.cancel_creation_img = new Button("ANNULER");
this.cancel_creation_img.setStyle("-fx-background-color : #FFF");
this.continue_creation_img = new Button("CRÉER");
this.continue_creation_img.setStyle("-fx-background-color : #FFF");
this.button_hor_gradation = new Button("Dégradé horizontal");
this.button_hor_gradation.setStyle("-fx-background-color : #FFF");
this.button_draw_circle = new Button("Nouveau cercle");
this.button_draw_circle.setStyle("-fx-background-color : #FFF");
// At center
this.img_view = new ImageView();
this.scroll_pane = new ScrollPane(this.img_view);
this.scroll_pane.setStyle("-fx-background : #FFF");
// For right pane
this.right_pane = new FlowPane();
this.right_pane.setStyle("-fx-background-color : #27ae60");
this.right_pane.setOrientation(Orientation.VERTICAL);
this.button_reverse_image = new Button("Inverser l'image");
this.button_reverse_image.setStyle("-fx-background-color : #FFF");
// For bot pane
this.bot_pane = new FlowPane();
this.bot_pane.setAlignment(Pos.BASELINE_CENTER);
this.bot_pane.setHgap(20);
this.bot_pane.setStyle("-fx-background-color : #27ae60");
this.save_img = new Button("Sauvegarder votre travail");
this.save_img.setStyle("-fx-background-color : #FFF");
this.switch_mode = new Button(this.VERSION_WITH_MENU);
this.switch_mode.setStyle("-fx-background-color : #FFF");
// Dialogs
this.dialog_gradation = new Dialog();
this.dialog_flowpane = new FlowPane(Orientation.VERTICAL);
this.dialog_gradation.getDialogPane().setContent(this.dialog_flowpane);
this.dialog_gradation.setTitle("Créer un dégradé");
this.dialog_label_width = new Label("Largeur :");
this.dialog_field_width = new TextField("500");
this.dialog_label_height = new Label("Hauteur :");
this.dialog_field_height = new TextField("500");
this.dialog_choiceBox = new ChoiceBox<String>(FXCollections.observableArrayList("Blanc vers noir", "Noir vers blanc", "Polychrome"));
this.dialog_choiceBox.getSelectionModel().selectFirst();
this.dialog_flowpane.getChildren().addAll( this.dialog_label_width, this.dialog_field_width,
this.dialog_label_height, this.dialog_field_height,
this.dialog_choiceBox);
this.dialog_gradation.getDialogPane().getButtonTypes().addAll(ButtonType.CANCEL, ButtonType.OK);
}
public void update(Observable o, Object ob) {
if(o instanceof Pixel) {
draw();
}
}
public void draw() {
this.pixel_writer.setColor(pixel_buffer.x, pixel_buffer.y, pixel_buffer.color);
}
// <!-- FILL FUNCTIONS -->
public void fill() {
this.fillMenuBar();
this.fillTopPane();
this.fillLeftPane();
this.fillRightPane();
this.fillBotPane();
this.fillCreationImgPane();
this.fillRoot();
this.disableButtonsBecauseNoLoadedImage(true);
this.bindUIEvents();
this.bindGraphicEngineEvents();
}
private void fillBotPane() { this.bot_pane.getChildren().addAll(this.save_img, this.switch_mode); }
private void fillCreationImgPane() { this.creation_img_pane.getChildren().addAll(this.cancel_creation_img, this.continue_creation_img); }
private void fillLeftPane() {
this.left_pane.getChildren().addAll(this.create_sheet, this.button_hor_gradation,
this.button_draw_circle
);
}
private void fillMenuBar() {
this.menu_bar.getMenus().addAll(this.file, this.menu_create_sheet, this.menu_create_gradation);
this.file.getItems().addAll(this.open, this.save);
this.menu_create_sheet.getItems().addAll(this.sheet_customized);
this.menu_create_gradation.getItems().addAll(this.gradation_customized);
}
private void fillRightPane() { this.right_pane.getChildren().addAll(this.button_reverse_image); }
private void fillRoot() {
this.root.setLeft(this.left_pane);
this.root.setTop(this.top_pane);
this.root.setBottom(this.bot_pane);
this.root.setCenter(this.scroll_pane);
this.root.setRight(this.right_pane);
}
private void fillTopPane() { this.top_pane.getChildren().addAll(this.img_path, this.button_load_img_from_web, this.or, this.button_load_img_from_local); }
// <!-- HANDLE EVENTS -->
private void bindGraphicEngineEvents() {
this.button_reverse_image.setOnAction(button -> {
this.graphic_engine.restart();
});
}
public void setCustomImg(int width, int height) {
this.writable_image = new WritableImage(width, height);
this.pixel_reader = this.writable_image.getPixelReader();
this.pixel_writer = this.writable_image.getPixelWriter();
this.graphic_engine.setAttributes((int) this.writable_image.getWidth(),
(int) this.writable_image.getHeight(),
this.pixel_reader,
this.pixel_buffer);
}
private void bindUIEvents() {
// MENU'S EVENTS
this.sheet_customized.setOnAction(menuItem -> this.displayCreationGui());
this.gradation_customized.setOnAction(menuItem -> this.dialogHandleEvents());
//this.open.setOnAction(button -> { this.graphic_engine.setImg(this.displayFileChooser(0)); this.displayImage(); });
this.save.setOnAction(button -> this.saveImg(this.displayFileChooser(1)));
// NOT MENU'S && DIALOGS' EVENTS
this.button_load_img_from_web.setOnAction(button -> {
Image img = new Image(this.img_path.getText());
this.writable_image = new WritableImage(img.getPixelReader(), (int) img.getWidth(), (int) img.getHeight());
this.pixel_reader = this.writable_image.getPixelReader();
this.pixel_writer = this.writable_image.getPixelWriter();
this.graphic_engine.setAttributes((int) this.writable_image.getWidth(),
(int) this.writable_image.getHeight(),
this.pixel_reader,
this.pixel_buffer);
this.displayImage();
});
this.button_load_img_from_local.setOnAction(button -> {
if(this.displayFileChooser(0) != null) {
try {
WritableImage writable_img = SwingFXUtils.toFXImage(ImageIO.read(this.displayFileChooser(0)), null);
this.writable_image = new WritableImage(writable_img.getPixelReader(), (int) writable_img.getWidth(), (int) writable_img.getHeight());
this.pixel_reader = this.writable_image.getPixelReader();
this.pixel_writer = this.writable_image.getPixelWriter();
this.graphic_engine.setAttributes((int) this.writable_image.getWidth(),
(int) this.writable_image.getHeight(),
this.pixel_reader,
this.pixel_buffer);
this.displayImage();
} catch(IOException e) {
System.out.println(e);
}
}
});
this.save_img.setOnAction(button -> this.saveImg(this.displayFileChooser(1)));
this.create_sheet.setOnAction(button -> this.displayCreationGui());
this.cancel_creation_img.setOnAction(button -> this.closeCreationGui());
this.checkbox_random_color_points.setOnAction(chck -> {
if(this.checkbox_random_color_points.isSelected()) {
this.color_picker.setDisable(true);
} else {
this.color_picker.setDisable(false);
}
});
this.continue_creation_img.setOnAction(button -> {
this.setCustomImg(Integer.parseInt(this.field_width.getText()), Integer.parseInt(this.field_height.getText()));
if(!this.checkbox_random_color_points.isSelected()) {
this.graphic_engine.setBackgroundColor(this.color_picker.getValue());
} else {
this.graphic_engine.setBackgroundColorRandom();
}
this.closeCreationGui();
this.displayImage();
});
this.switch_mode.setOnAction(button -> this.displayMenuOrButtons());
this.button_hor_gradation.setOnAction(button -> { this.dialogHandleEvents(); });
this.button_draw_circle.setOnAction(button -> {
this.setCustomImg(2000, 2000);
this.graphic_engine.displayCircle();
});
}
public void saveImg(File file) {
if(file != null) {
try {
String format = file.getName().substring( file.getName().lastIndexOf(".") + 1);
ImageIO.write(SwingFXUtils.fromFXImage(this.writable_image, null), format, file);
} catch(IOException e) {
System.out.println(e);
}
}
}
private void dialogHandleEvents() {
this.dialog_gradation.showAndWait().ifPresent( r -> {
if(r == ButtonType.OK) {
this.setCustomImg(Integer.parseInt(this.dialog_field_width.getText()), Integer.parseInt(this.dialog_field_height.getText()));
this.graphic_engine.displayHorGraduation(this.dialog_choiceBox.getValue());
this.displayImage();
}
});
}
// <!-- DISPLAY AND CLOSE/HIDE FUNCTIONS -->
private void closeCreationGui() {
this.left_pane.getChildren().removeAll( this.title_creation_img, this.label_width,
this.field_width, this.label_height,
this.field_height, this.color_picker, this.checkbox_random_color_points, this.creation_img_pane);
if(!this.root.getChildren().contains(this.menu_bar)) {
this.left_pane.getChildren().addAll(this.create_sheet, this.button_hor_gradation);
}
}
private void disableButtonsBecauseNoLoadedImage(boolean b) {
this.button_reverse_image.setDisable(b);
this.save_img.setDisable(b);
}
private void displayCreationGui() {
this.left_pane.getChildren().removeAll(this.create_sheet, this.button_hor_gradation);
this.left_pane.getChildren().addAll( this.title_creation_img, this.label_width,
this.field_width, this.label_height,
this.field_height, this.color_picker, this.checkbox_random_color_points, this.creation_img_pane);
}
private File displayFileChooser(int flag) {
File selected_file = null;
switch(flag) {
case 0:
this.file_chooser.setTitle("Sélectionnez une image");
selected_file = this.file_chooser.showOpenDialog(this.stage);
break;
case 1:
this.file_chooser.setTitle("Enregistrer votre travail");
this.file_chooser.getExtensionFilters().addAll(
new FileChooser.ExtensionFilter("Image Files", "*.gif", "*.png", "*.jpeg", "*.jpg")
);
selected_file = this.file_chooser.showSaveDialog(this.stage);
break;
}
return selected_file;
}
public void displayImage() {
this.img_view.setImage(this.writable_image);
if(this.writable_image != null || this.writable_image!= null) {
this.enableButtonsBecauseLoadedImageExists();
}
}
private void displayMenuOrButtons() {
if(this.root.getChildren().contains(this.menu_bar)) {
this.root.setTop(this.top_pane);
this.switch_mode.setText(this.VERSION_WITH_MENU);
this.left_pane.getChildren().addAll(this.create_sheet, this.button_hor_gradation);
} else {
this.root.setTop(this.menu_bar);
this.switch_mode.setText(this.VERSION_WITH_BUTTONS);
this.left_pane.getChildren().removeAll(this.create_sheet, this.button_hor_gradation);
}
}
private void enableButtonsBecauseLoadedImageExists() { this.disableButtonsBecauseNoLoadedImage(false); }
}
import javafx.application.Application;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class Launcher extends Application {
public static void main(String args[]) {
launch(args);
}
public void start(Stage stage) {
stage.setWidth(700);
stage.setHeight(700);
stage.setMaximized(true);
Gui gui = new Gui(stage, new BorderPane(), 700, 500);
gui.fill();
stage.setScene(gui);
stage.show();
}
}
import javafx.scene.paint.Color;
import java.util.Observable;
public class Pixel extends Observable {
public int x, y;
public Color color;
public Pixel() {
}
public Pixel(int x, int y, Color color) {
this.x = x;
this.y = y;
this.color = color;
}
public void setAttributes(int x, int y, Color color) {
this.x = x;
this.y = y;
this.color = color;
this.setChanged();
this.notifyObservers(this.color);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment