Skip to content

Commit

Permalink
Updated Change Log, Minor Updates & Fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
SonarSonic committed Jun 18, 2022
1 parent 79a2dc6 commit 5ca1c86
Show file tree
Hide file tree
Showing 18 changed files with 135 additions and 46 deletions.
51 changes: 51 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,54 @@
### [v1.4.1-beta](https://github.com/SonarSonic/DrawingBotV3/releases/tag/v1.4.1-beta-free)
- Added: **Colour Match - Premium Only** - A new Colour Seperation mode for Sketch PFMs only, it will compare the pens in your drawing set to the colours in the image and when drawing will try to use the best matched pen.
You also have a few options to configure colour match further, found to the right of the Colour Seperation drop-down.

- "Colour Accuracy" - Decreasing the Colour Accuracy will lower the quality of the colour match and allows pens to draw over areas where they have a higher colour difference. Colour Accuracy relates to a Delta-E colour measurement in the following way
- 100: No colour difference
- 99: Slight colour difference
- 98: Small colour difference
- 97: Medium colour difference
- 96: Large colour difference
- 95: Very large colour difference

- "Brightness Multiplier" - Decreases the overlap of the pens in the image
- "Pen Limit" - Limits the number of pens which can be used when matching, if this value is set to 18, only the 18 best matched pens will be used. If this value is set to 0, there is no limit.
- "Use Canvas Colour" - Adds an invisible pen which matches the colour of the Canvas, helps to avoid drawing unnecessary lines.
- "Line Density - from Sketch PFMs" - the line density control found in the Sketch PFMs can also be used to control the Colour Match output.
- **For the best results**
- Use all the pens of a specific manufacturer, i.e. Use the presets for the set of 60 Staedtler Fineliners, then use the Pen Limit feature, to limit selection to approx 18+ pens allowing colour match to choose your best matched pens for each plot.
- Use a bright, saturated image, murky images or ones with a limited colour palette will perform poorly.
- Added: **SVG Import & SVG Converter PFM - Premium Only**
- You can now import SVGs generated in other softwares or in DrawingBotV3, this opens up many possibilities, such as SVG cropping, rotation, flipping, masking, pen/layer reassignment, layering multiple SVGs and recovering old DBV3 projects. Note: Any text in the SVGs will be blank, you should use "Object to Path" in Inkscape before importing SVGs with text.
- SVGs can be also be treated like any other image allowing them to be run through any PFM, they will be rasterised at the highest quality possible before plotting (the image tab will show a low quality preview of the SVG).
- You can control the conversion process in the new PFM SVG Converter, it has a few settings.
- SVG Path: The path to the SVG to be used, if this isn't set it will use the current imported SVG, if there isn't one the PFM will produce no output. You can however use this PFM as part of a Layers PFM, to layer SVGs together, when you run the PFM like this you can set the SVG Path to use an SVG which hasn't been imported.
- Derive Drawing Set: When enabled DrawingBotV3 will generate a new Drawing Pen for each colour in the SVG, allowing you to access them each as layers. This opens up possibilities for splitting SVGs by colour using a per/layer export, or even re-assigning colours to your SVG, once the SVG Converter PFM has been run you'll have access to change the colour of lines with all the tools available with a default drawing.
- You can also import an SVG to run through a standard PFM

- Added: **Masking - Premium Only** - A new useful settings tab, to allow you to mask areas of the image, you can add shapes masks such as Rectangles and Circles, you can move, resize, rotate, skew with the controls in the viewport area. You can also import SVGs as masks, they will keep their original sizing so you can create detailed masks by importing an SVG with the same dimensions as in drawing area controls.
- Added: **Image Cropping** - You can now crop images in the Image Processing tab, this allows you to enter values in pixels for cropping the image. You can also hit the "Edit" button and this will display a resizable box in the viewport area which you can then move to create the desired crop. You can also access this cropping feature via the new Display Mode "Image Cropping".
- Added: **Rulers Overlays** - There are now rulers on the borders of the viewport area to show you an accurate scale of your drawing / image.
- Added: Lock 1:1 button to the viewport toolbar, to allow viewing drawings at the correct scale relative to the screen, useful for evaluating the density of your plot.
- Added: Reference Image exports - You can now export the edited reference image used in your plots, via Export / Export Reference Image File.
- Added: Winsor & Newton ProMarkers, Pens/Drawing Sets - led
- Added: Bic Cristal and Intensity, Pens/Drawing Sets - led
- Added: Staedtler Fineliner 305 Sky Blue - Pen Definition - led
- Added: Support for Googles WebP Image Files (.webp)
- Added: Fullscreen Mode, you can enable it be going to View/Fullscreen Mode
- Added: Frame Hold Start and Frame Hold End to Animation Settings
- Changed: Increased default render quality in the viewport to x4 the previous quality
- Changed: You can now send any file type via the Serial Connection, allowing for sending GCode files to compatible plotters.
- Changed: Image Rotation / Flipping is now Image Specific, when you load a new image these values will be reset.
- Fixed: Drawings/Images flickering when switching Display Modes.
- Fixed: Serial Connection commands will now be executed properly on non-HPGL devices.
- Fixed: Staedtler Fineliner 63 Delft Blue - Pen Definition - led
- Fixed: Export Directory being used instead of Import Directory when importing files - led
- Fixed: Removed duplicate Copic Black Pens - led
- Fixed: "Original Sizing" preset not activating properly
- Fixed: GCode Settings not saving properly
- Fixed: HP-GL Padding/Offsets creating inaccurate drawings outside of the HP-GL bounds
- Fixed: When exporting with N/Pens the render order will now be used rather than the export order, meaning the order will now match the generated HPGL files correctly.

### [v1.4.0-beta](https://github.com/SonarSonic/DrawingBotV3/releases/tag/v1.4.0-beta-free)

Note: This update has kept growing and growing, and it’s time it was released, this is a Public Beta, although it has already been through an alpha testing phase.
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ plugins {
// Apply the application plugin to add support for building a CLI application in Java.
id 'application'
id 'org.openjfx.javafxplugin' version '0.0.11'
id 'com.github.johnrengelman.shadow' version '5.2.0'
id 'com.github.johnrengelman.shadow' version '7.1.2'
id "org.beryx.runtime" version "1.12.7"
}

Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#app version
app_name=DrawingBotV3-Free
app_version=1.4.0
app_version=1.4.1
app_state=beta

javaFX_version=17
Expand Down
6 changes: 1 addition & 5 deletions src/main/java/drawingbot/DrawingBotV3.java
Original file line number Diff line number Diff line change
Expand Up @@ -134,10 +134,6 @@ public DrawingBotV3() {
blendMode.addListener((observable, oldValue, newValue) -> reRender());
imgFilterSettings.currentFilters.get().addListener((ListChangeListener<ObservableImageFilter>) c -> onImageFiltersChanged());

imgFilterSettings.imageRotation.addListener((observable, oldValue, newValue) -> onCanvasChanged());
imgFilterSettings.imageFlipHorizontal.addListener((observable, oldValue, newValue) -> onCanvasChanged());
imgFilterSettings.imageFlipVertical.addListener((observable, oldValue, newValue) -> onCanvasChanged());

activeTask.addListener((observable, oldValue, newValue) -> setRenderFlag(Flags.ACTIVE_TASK_CHANGED, true));
renderedTask.addListener((observable, oldValue, newValue) -> setRenderFlag(Flags.ACTIVE_TASK_CHANGED, true));
currentDrawing.addListener((observable, oldValue, newValue) -> setRenderFlag(Flags.CURRENT_DRAWING_CHANGED, true));
Expand Down Expand Up @@ -176,7 +172,7 @@ public UnitsLength getUnits() {

@Override
public boolean flipAxis() {
return imgFilterSettings.imageRotation.get().flipAxis;
return openImage.get() != null && openImage.get().imageRotation.get().flipAxis;
}
};

Expand Down
1 change: 1 addition & 0 deletions src/main/java/drawingbot/files/FileUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public class FileUtils {
public static final FileChooser.ExtensionFilter IMPORT_IMAGES = new FileChooser.ExtensionFilter("Image Files", "*.tif", "*.tga", "*.png", "*.jpg", "*.webp", "*.gif", "*.bmp", "*.jpeg");
public static final FileChooser.ExtensionFilter IMPORT_VIDEOS = new FileChooser.ExtensionFilter("Video Files", "*.mp4", "*.mov", "*.avi");

public static final FileChooser.ExtensionFilter FILTER_ALL_FILES = new FileChooser.ExtensionFilter("All Files", "*.*");
public static final FileChooser.ExtensionFilter FILTER_JSON = new FileChooser.ExtensionFilter("JSON - JavaScript Object Notation", "*.json");
public static final FileChooser.ExtensionFilter FILTER_PROJECT = new FileChooser.ExtensionFilter("DrawingBotV3 - Project File", "*.drawingbotv3");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,24 +168,19 @@ public void loadData(DrawingSetData data, GenericPreset<PresetProjectSettings> p

@Override
public void saveData(ImageSettings data, GenericPreset<PresetProjectSettings> preset) {
data.imageRotation = DrawingBotV3.INSTANCE.imgFilterSettings.imageRotation.get();
data.imageFlipHorizontal = DrawingBotV3.INSTANCE.imgFilterSettings.imageFlipHorizontal.get();
data.imageFlipVertical = DrawingBotV3.INSTANCE.imgFilterSettings.imageFlipVertical.get();
if(DrawingBotV3.INSTANCE.openImage.get() != null){
data.cropStartX = DrawingBotV3.INSTANCE.openImage.get().cropStartX.get();
data.cropStartY = DrawingBotV3.INSTANCE.openImage.get().cropStartY.get();
data.cropEndX = DrawingBotV3.INSTANCE.openImage.get().cropEndX.get();
data.cropEndY = DrawingBotV3.INSTANCE.openImage.get().cropEndY.get();
data.imageRotation = DrawingBotV3.INSTANCE.openImage.get().imageRotation.get();
data.imageFlipHorizontal = DrawingBotV3.INSTANCE.openImage.get().imageFlipHorizontal.get();
data.imageFlipVertical = DrawingBotV3.INSTANCE.openImage.get().imageFlipVertical.get();
}
}

@Override
public void loadData(ImageSettings data, GenericPreset<PresetProjectSettings> preset) {
DrawingBotV3.INSTANCE.imgFilterSettings.imageRotation.set(data.imageRotation);
DrawingBotV3.INSTANCE.imgFilterSettings.imageFlipHorizontal.set(data.imageFlipHorizontal);
DrawingBotV3.INSTANCE.imgFilterSettings.imageFlipVertical.set(data.imageFlipVertical);


if(!preset.data.imagePath.isEmpty()) {
AbstractFileLoader loadingTask = DrawingBotV3.INSTANCE.getImageLoaderTask(new File(preset.data.imagePath), false);
loadingTask.stateProperty().addListener((observable, oldValue, newValue) -> {
Expand All @@ -199,6 +194,9 @@ public void loadData(ImageSettings data, GenericPreset<PresetProjectSettings> pr
imageData.cropStartY.set(data.cropStartY);
imageData.cropEndX.set(data.cropEndX);
imageData.cropEndY.set(data.cropEndY);
imageData.imageRotation.set(data.imageRotation);
imageData.imageFlipHorizontal.set(data.imageFlipHorizontal);
imageData.imageFlipVertical.set(data.imageFlipVertical);
}
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,11 @@ public static GenericPreset<PresetProjectSettings> updatePreset(GenericPreset<Pr
Register.PRESET_LOADER_DRAWING_SET.getDefaultManager().updatePreset(presetDrawingSet);
presetData.drawingSet = presetDrawingSet;

/*
presetData.imageRotation = DrawingBotV3.INSTANCE.imgFilterSettings.imageRotation.get();
presetData.imageFlipHorizontal = DrawingBotV3.INSTANCE.imgFilterSettings.imageFlipHorizontal.get();
presetData.imageFlipVertical = DrawingBotV3.INSTANCE.imgFilterSettings.imageFlipVertical.get();
*/

presetData.optimiseForPrint = DrawingBotV3.INSTANCE.drawingArea.optimiseForPrint.get();
presetData.targetPenWidth = DrawingBotV3.INSTANCE.drawingArea.targetPenWidth.get();
Expand Down Expand Up @@ -104,9 +106,11 @@ public static void applyPreset(GenericPreset<PresetProjectSettings> preset) {
Register.PRESET_LOADER_FILTERS.getDefaultManager().applyPreset(presetData.imageFilters);
Register.PRESET_LOADER_PFM.getDefaultManager().applyPreset(presetData.pfmSettings);

/*
DrawingBotV3.INSTANCE.imgFilterSettings.imageRotation.set(presetData.imageRotation);
DrawingBotV3.INSTANCE.imgFilterSettings.imageFlipHorizontal.set(presetData.imageFlipHorizontal);
DrawingBotV3.INSTANCE.imgFilterSettings.imageFlipVertical.set(presetData.imageFlipVertical);
*/

DrawingBotV3.INSTANCE.drawingArea.optimiseForPrint.set(presetData.optimiseForPrint);
DrawingBotV3.INSTANCE.drawingArea.targetPenWidth.set(presetData.targetPenWidth); //TODO TEST ME
Expand Down
5 changes: 1 addition & 4 deletions src/main/java/drawingbot/image/ImageFilterSettings.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,8 @@
public class ImageFilterSettings implements IProperties {

public final SimpleObjectProperty<ObservableList<ObservableImageFilter>> currentFilters = new SimpleObjectProperty<>(FXCollections.observableArrayList());
public final SimpleObjectProperty<EnumRotation> imageRotation = new SimpleObjectProperty<>(EnumRotation.R0);
public final SimpleBooleanProperty imageFlipHorizontal = new SimpleBooleanProperty(false);
public final SimpleBooleanProperty imageFlipVertical = new SimpleBooleanProperty(false);

public final ObservableList<Property<?>> observables = PropertyUtil.createPropertiesList(currentFilters, imageRotation, imageFlipHorizontal, imageFlipVertical);
public final ObservableList<Property<?>> observables = PropertyUtil.createPropertiesList(currentFilters);

@Override
public ObservableList<Property<?>> getProperties() {
Expand Down
39 changes: 32 additions & 7 deletions src/main/java/drawingbot/image/format/FilteredImageData.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@
import drawingbot.plotting.canvas.SimpleCanvas;
import drawingbot.render.modes.ImageJFXDisplayMode;
import drawingbot.render.shapes.JFXShape;
import drawingbot.utils.EnumRotation;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleFloatProperty;
import javafx.beans.property.SimpleObjectProperty;

import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
Expand Down Expand Up @@ -38,6 +41,7 @@ public FilteredImageData(File sourceFile, ICanvas destCanvas, BufferedImage sour
public FilteredImageData(File sourceFile, ICanvas destCanvas, ICanvas sourceCanvas, BufferedImage sourceImage){
this.sourceFile = sourceFile;
this.targetCanvas = destCanvas;
this.destCanvas = destCanvas;
this.sourceCanvas = sourceCanvas;
this.sourceImage = sourceImage;
this.resetCrop();
Expand Down Expand Up @@ -99,6 +103,28 @@ public boolean isVectorImage(){

///////////////////////////////////////

public final SimpleObjectProperty<EnumRotation> imageRotation = new SimpleObjectProperty<>(EnumRotation.R0);
public final SimpleBooleanProperty imageFlipHorizontal = new SimpleBooleanProperty(false);
public final SimpleBooleanProperty imageFlipVertical = new SimpleBooleanProperty(false);

{
imageRotation.addListener((observable, oldValue, newValue) -> {
if(DrawingBotV3.INSTANCE.openImage.get() == this){
DrawingBotV3.INSTANCE.onCanvasChanged();
}
});
imageFlipHorizontal.addListener((observable, oldValue, newValue) -> {
if(DrawingBotV3.INSTANCE.openImage.get() == this){
DrawingBotV3.INSTANCE.onCanvasChanged();
}
});
imageFlipVertical.addListener((observable, oldValue, newValue) -> {
if(DrawingBotV3.INSTANCE.openImage.get() == this){
DrawingBotV3.INSTANCE.onCanvasChanged();
}
});
}

public final SimpleFloatProperty cropStartX = new SimpleFloatProperty(0);
public final SimpleFloatProperty cropStartY = new SimpleFloatProperty(0);
public final SimpleFloatProperty cropEndX = new SimpleFloatProperty(0);
Expand Down Expand Up @@ -128,7 +154,6 @@ public Rectangle2D getCrop(){
if(width == 0 || height == 0){
return new Rectangle2D.Double(0, 0, sourceCanvas.getWidth(), sourceCanvas.getHeight());
}

return new Rectangle2D.Double(startX, startY, width, height);
}

Expand All @@ -138,16 +163,16 @@ public BufferedImage createPreCroppedImage() {

public BufferedImage createCroppedImage(ICanvas canvas, ImageFilterSettings settings){
BufferedImage image = createPreCroppedImage();
return applyCropping(image, canvas, settings);
return applyCropping(image, canvas, imageRotation.get(), imageFlipHorizontal.get(), imageFlipVertical.get());
}

public void updateAll(ImageFilterSettings settings){
ImageCanvas newCanvas = new ImageCanvas(new SimpleCanvas(targetCanvas), sourceCanvas, false);

if(cropped == null || updateCropping){
preCrop = applyPreCropping(sourceImage, getCrop());
newCanvas = new ImageCanvas(new SimpleCanvas(targetCanvas), preCrop, settings.imageRotation.get().flipAxis);
cropped = applyCropping(preCrop, newCanvas, settings);
newCanvas = new ImageCanvas(new SimpleCanvas(targetCanvas), preCrop, imageRotation.get().flipAxis);
cropped = applyCropping(preCrop, newCanvas, imageRotation.get(), imageFlipHorizontal.get(), imageFlipVertical.get());
}
filteredImage = applyFilters(cropped, updateCropping || updateAllFilters, settings);
destCanvas = newCanvas;
Expand All @@ -167,7 +192,7 @@ public AffineTransform getCanvasTransform(ImageFilterSettings settings){

//rotation transform
if(settings != null){
AffineTransform rotationTransform = ImageTools.getCanvasRotationTransform(canvas, settings.imageRotation.get(), settings.imageFlipHorizontal.get(), settings.imageFlipVertical.get());
AffineTransform rotationTransform = ImageTools.getCanvasRotationTransform(canvas, imageRotation.get(), imageFlipHorizontal.get(), imageFlipVertical.get());
transform.preConcatenate(rotationTransform);
}

Expand All @@ -186,8 +211,8 @@ public static BufferedImage applyPreCropping(BufferedImage src, Rectangle2D crop
return ImageTools.applyPreCrop(src, crop);
}

public static BufferedImage applyCropping(BufferedImage src, ICanvas canvas, ImageFilterSettings imgFilterSettings){
src = ImageTools.rotateImage(src, imgFilterSettings.imageRotation.get(), imgFilterSettings.imageFlipHorizontal.get(), imgFilterSettings.imageFlipVertical.get());
public static BufferedImage applyCropping(BufferedImage src, ICanvas canvas, EnumRotation imageRotation, boolean flipHorizontal, boolean flipVertical){
src = ImageTools.rotateImage(src, imageRotation, flipHorizontal, flipVertical);
return ImageTools.cropToCanvas(src, canvas);
}

Expand Down
8 changes: 5 additions & 3 deletions src/main/java/drawingbot/javafx/FXHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -434,15 +434,17 @@ public static GridPane createSettingsGridPane(Collection<GenericSetting<?, ?>> s
gridPane.addRow(i, label, node);
}else{
TextField field = setting.getEditableTextField();
gridPane.addRow(i, label, node, setting.getEditableTextField());

field.setOnAction(e -> {
setting.setValueFromString(field.getText());
if(onChanged != null) {
onChanged.accept(setting);
}
});

if(node != field){
gridPane.addRow(i, label, node, field);
}else{
gridPane.addRow(i, label, field);
}
}
if(onChanged != null){
node.setOnMouseReleased(e -> onChanged.accept(setting)); //change on mouse release, not on value change
Expand Down
Loading

0 comments on commit 5ca1c86

Please sign in to comment.