Skip to content

Commit

Permalink
documentation / sample
Browse files Browse the repository at this point in the history
  • Loading branch information
olir committed Mar 20, 2018
1 parent 4cc4e01 commit 6fb22c9
Show file tree
Hide file tree
Showing 17 changed files with 225 additions and 50 deletions.
7 changes: 6 additions & 1 deletion NOTICE.TXT
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,9 @@ Soundtrack: "Never Again" by Spender

LICENSED AS

https://creativecommons.org/licenses/by/3.0/
https://creativecommons.org/licenses/by/3.0/

----------------------
Some images for docs taken from https://pixabay.com/de/
licenensed under CC0
https://creativecommons.org/publicdomain/zero/1.0/deed
118 changes: 115 additions & 3 deletions SegmentFilters.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,121 @@

## Howto create a new filter

## Overview
A filter is made of the following parts:
* filter class - contains the image manipulation
* filter configuration controller class - a fxml contoller
* fxml layout file - sub layout for configuration of the filter
* controller class for the filter configuration editor - a fxml contoller
* property files with localized text
* fxml layout file for the filter configuration editor - sub layout for configuration of the filter instances
* filter class - contains the image manipulation.

The easiest way is to create the filter class is to extend de.screenflow.frankenstein.vf.segment.DefaultSegmentFilter.
DefaultSegmentFilter expects all the classes and resources to be placed in the same package.
Look at de.screenflow.frankenstein.vf.segment.BWFilter for an example.

## Step 1: Create a controller class for the filter configuration editor

Start with an empty class. You can place fxml handling code there later:

__samplefilters/SampleConfigController.java__
```java
package samplefilters;

public class SampleConfigController {

}
```


## Step 2: Create property files

The property files are required to store localized text of you Controller Configuration Editor.
The default property file is mandatory and should contain english text. It *must* contain a property
__name__ mapped to the display name of the filter.

The file name is based on an unique identifier for you filter resources.
In this example i choose __sample__
Place it the proper resource package with the suffix .properties


__samplefilters/sample.properties__
```java
name=Sample
message=No configuration options.
```

You may add localized versions of the file like this:

__samplefilters/sample_de.properties__
```
name=Beispiel
message=Keine Einstellungenoptionen.
```


## Step 3: Create a new fxml layout file. Notice: Eclipse FX-Editions have a SceneBuilder.

Start by copying the following example and change the controller class reference to yours from step 1.

```xml
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.*?>
<?import javafx.scene.text.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.BorderPane?>

<BorderPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="samplefilters.SampleConfigController">
<center>
</center>
<center>
<Label text="%message" BorderPane.alignment="CENTER">
<font>
<Font name="System Italic" size="14.0" />
</font></Label>
</center>
</BorderPane>
```

In the example above the property __message__ from step 2 is used, by using the __%__ operator.


## Step 4: Create Filter Class

Now create the filter class:

__samplefilters/SampleFilter.java__
```java
package samplefilters;

import org.opencv.core.Mat;
import de.screenflow.frankenstein.vf.segment.DefaultSegmentFilter;

public class SampleFilter extends DefaultSegmentFilter<SampleConfigController> {

public SampleFilter() {
super("sample");
}

@Override
public Mat process(Mat sourceFrame, int frameId) {
// TODO: Your open OpenCV code here ...
return sourceFrame;
}

@Override
protected void initializeController() {
// optional TODO ...

}
}
```


## Step 5: Finally add filter to the list

Append list in FxMain.createSegmentFilters()


Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public void configure(ProcessingSceneController parent, Stage stage) {
selectedFilter = newFilter.createInstance();
URL url = getClass().getResource("application.css");
String stylesheet = url.toExternalForm();
Scene scene = selectedFilter.createConfigurationScene(FxMain.getLocale(), stylesheet);
Scene scene = selectedFilter.createConfigurationScene(stylesheet);
bpContainer.setCenter(scene.getRoot());
}
}
Expand Down
23 changes: 21 additions & 2 deletions src/main/java/de/screenflow/frankenstein/fxml/FxMain.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,24 @@
package de.screenflow.frankenstein.fxml;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;

import de.screenflow.frankenstein.Configuration;
import de.screenflow.frankenstein.MovieProcessor;
import de.screenflow.frankenstein.vf.SegmentVideoFilter;
import de.screenflow.frankenstein.vf.segment.BWFilter;
import de.screenflow.frankenstein.vf.segment.StereoDistanceFilter;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import samplefilters.SampleFilter;

public class FxMain extends Application {

Expand All @@ -37,6 +43,8 @@ public class FxMain extends Application {
private ProcessingSceneController pController;
private ConfigurationSceneController cController;

private List<SegmentVideoFilter> segmentFilters;

public static final String APP_NAME = "Frankenstein VR";

private Configuration configuration;
Expand Down Expand Up @@ -94,6 +102,8 @@ public void start(Stage primaryStage) {
}

private void buildUI() {
createSegmentFilters();

BorderPane sceneRoot = null;
FXMLLoader loader;

Expand Down Expand Up @@ -167,10 +177,19 @@ public void setDocumentInTitle(String name) {
theStage.setTitle(APP_NAME);
}



public static Locale getLocale() {
return locale;
}

public List<SegmentVideoFilter> getLocalFilters() {
return segmentFilters;
}

public void createSegmentFilters() {
segmentFilters = new ArrayList<SegmentVideoFilter>();
segmentFilters.add(new BWFilter());
segmentFilters.add(new StereoDistanceFilter());
segmentFilters.add(new SampleFilter());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.List;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
Expand All @@ -37,8 +36,6 @@
import de.screenflow.frankenstein.vf.SegmentVideoFilter;
import de.screenflow.frankenstein.vf.VideoFilter;
import de.screenflow.frankenstein.vf.VideoStreamSource;
import de.screenflow.frankenstein.vf.segment.BWFilter;
import de.screenflow.frankenstein.vf.segment.StereoDistanceFilter;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
Expand Down Expand Up @@ -97,8 +94,6 @@ public class ProcessingSceneController implements ProcessingListener {

boolean streamRunning = false;

private List<SegmentVideoFilter> localFilters;


@FXML
BorderPane rootBorder;
Expand Down Expand Up @@ -217,10 +212,6 @@ public void changed(ObservableValue<? extends FilterElement> observable, FilterE
}
});

localFilters = new ArrayList<SegmentVideoFilter>();
localFilters.add(new BWFilter());
localFilters.add(new StereoDistanceFilter());

updateDuration();

Platform.runLater(() -> {
Expand Down Expand Up @@ -927,7 +918,8 @@ public void run() {
}

public List<SegmentVideoFilter> getLocalFilters() {
return localFilters;
return main.getLocalFilters();
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,10 @@
*/
package de.screenflow.frankenstein.vf;

import java.util.Locale;

import javafx.scene.Parent;
import javafx.scene.Scene;

public interface SegmentVideoFilter extends VideoFilter {
SegmentVideoFilter createInstance();
Scene createConfigurationScene(Locale locale, String stylesheet);

Scene createConfigurationScene(String stylesheet);
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,7 @@ public class BWFilter extends DefaultSegmentFilter<BWConfigController> {
Mat grayFrame;

public BWFilter() {
super("bw", "Black & White");
}

@Override
public Mat configure(Mat sourceFrame) {
return sourceFrame;
super("bw");
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@
package de.screenflow.frankenstein.vf.segment;

import java.io.IOException;
import java.util.Locale;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;

import org.opencv.core.Mat;

import de.screenflow.frankenstein.fxml.FxMain;
import de.screenflow.frankenstein.vf.SegmentVideoFilter;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
Expand All @@ -28,17 +30,19 @@ public abstract class DefaultSegmentFilter<C> implements SegmentVideoFilter {
private C configController = null;

private final String identifier;
private final String displayName;
protected DefaultSegmentFilter(String identifier, String displayName) {
private final PropertyResourceBundle bundleConfiguration;

protected DefaultSegmentFilter(String identifier) {
this.identifier = identifier;
this.displayName = displayName;

bundleConfiguration = (PropertyResourceBundle) ResourceBundle
.getBundle(getClass().getPackage().getName().replace('.', '/') + '/' + identifier, FxMain.getLocale());
}

public final String toString() {
return displayName;
return bundleConfiguration.getString("name");
}

@Override
public final SegmentVideoFilter createInstance() {
try {
Expand All @@ -48,11 +52,8 @@ public final SegmentVideoFilter createInstance() {
}
}


@Override
public final Scene createConfigurationScene(Locale locale, String stylesheet) {
PropertyResourceBundle bundleConfiguration = (PropertyResourceBundle) ResourceBundle
.getBundle(getClass().getPackage().getName().replace('.', '/') + '/' + identifier, locale);
public final Scene createConfigurationScene(String stylesheet) {
FXMLLoader loader = new FXMLLoader(getClass().getResource(identifier + ".fxml"), bundleConfiguration);
try {
loader.load();
Expand All @@ -65,12 +66,15 @@ public final Scene createConfigurationScene(Locale locale, String stylesheet) {
initializeController(); // custom initialization possible here
return scene;
}

abstract protected void initializeController();

protected final C getConfigController() {
return configController;
}



@Override
public final Mat configure(Mat firstFrame) {
return firstFrame;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,7 @@ public class StereoDistanceFilter extends DefaultSegmentFilter<StereoDistanceCon
private Mat newFrame = null;

public StereoDistanceFilter() {
super("stereodistance", "Stereo Distance");
}

@Override
public Mat configure(Mat sourceFrame) {
return sourceFrame;
super("stereodistance");
}

@Override
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/samplefilters/SampleConfigController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package samplefilters;

public class SampleConfigController {

}

0 comments on commit 6fb22c9

Please sign in to comment.