Basics
Create StreamableImage
From file
StreamableImage streamableImage = new StreamableImage(new File("path/to/file"));
From BufferedImage
BufferedImage bufferedImage = ImageIO.read(new File("path/to/file"));
StreamableImage streamableImage = new StreamableImage(bufferedImage);
Create ImageStream
streamableImage.stream();
Create ParallelImageStream
streamableImage.parallelStream();
Collect ImageStream
streamableImage.stream().collect(new Collector<BufferedImage>() {
@Override
public BufferedImage collect(BufferedImage bufferedImage) {
return bufferedImage;
}
});
Predicates
Usage
We use Predicates to select which pixels of the
image we want to work on further (f.e. apply a filter).
They are applied with method ImageStream bounds(Predicate<Pixel> predicate)
Filters
Arithmetic filters
Invert filter
BufferedImage bufferedImage = streamableImage.stream()
.apply(Filters.invertFilter())
.collect(Collectors.toBufferedImage());

Binarization filters
Otsu filter
BufferedImage bufferedImage = streamableImage.parallelStream()
.apply(Filters.otsuBinarizationFilter())
.collect(Collectors.toBufferedImage());

Color filters
Grayscale filter
BufferedImage bufferedImage = streamableImage.stream()
.apply(Filters.grayScaleFilter())
.collect(Collectors.toBufferedImage());

Sepia filter
BufferedImage bufferedImage = streamableImage.stream()
.apply(Filters.sepiaFilter())
.collect(Collectors.toBufferedImage());

Convolve filters
Box blur filter
BufferedImage bufferedImageBlur5 = streamableImage.stream()
.apply(Filters.boxBlurFilter(5))
.collect(Collectors.toBufferedImage());

Emboss filter
BufferedImage bufferedImage = streamableImage.stream()
.apply(Filters.embossFilter())
.collect(Collectors.toBufferedImage());

Sharpen filter
BufferedImage bufferedImage = streamableImage.stream()
.apply(Filters.sharpenFilter())
.collect(Collectors.toBufferedImage());

Edge detection filters
Roberts filter
BufferedImage bufferedImageX = streamableImage.parallelStream()
.apply(Filters.grayScaleFilter())
.apply(Filters.robertsCrossXFilter())
.collect(Collectors.toBufferedImage());

BufferedImage bufferedImageY = streamableImage.parallelStream()
.apply(Filters.grayScaleFilter())
.apply(Filters.robertsCrossYFilter())
.collect(Collectors.toBufferedImage());

BufferedImage bufferedImage = streamableImage.parallelStream()
.apply(Filters.edgeDetection(bufferedImageX, bufferedImageY))
.collect(Collectors.toBufferedImage());

Sobel filter
BufferedImage bufferedImageX = streamableImage.parallelStream()
.apply(Filters.grayScaleFilter())
.apply(Filters.sobelXFilter())
.collect(Collectors.toBufferedImage());

BufferedImage bufferedImageY = streamableImage.parallelStream()
.apply(Filters.grayScaleFilter())
.apply(Filters.sobelYFilter())
.collect(Collectors.toBufferedImage());

BufferedImage bufferedImage = streamableImage.parallelStream()
.apply(Filters.edgeDetection(bufferedImageX, bufferedImageY))
.collect(Collectors.toBufferedImage());

Equalization filters
Histogram equalization filter
BufferedImage bufferedImage = streamableImage.parallelStream()
.apply(Filters.histogramEqualizationFilter())
.collect(Collectors.toBufferedImage());

Morphology filters
Dilatation filter
BufferedImage bufferedImage = streamableImage.stream()
.apply(Filters.dilatationFilter())
.collect(Collectors.toBufferedImage());

Erosion filter
BufferedImage bufferedImage = streamableImage.stream()
.apply(Filters.erosionFilter())
.collect(Collectors.toBufferedImage());

Noise generators
Salt and pepper generator
BufferedImage bufferedImage = streamableImage.stream()
.apply(Filters.saltAndPepperFilter())
.collect(Collectors.toBufferedImage());

Statistical filters
Max filter
BufferedImage bufferedImage = streamableImage.parallelStream()
.setThreads(50)
.apply(Filters.maxFilter(9))
.collect(Collectors.toBufferedImage());

Min filter
BufferedImage bufferedImage = streamableImage.parallelStream()
.setThreads(50)
.apply(Filters.minFilter(9))
.collect(Collectors.toBufferedImage());

Mean filter
BufferedImage bufferedImage = streamableImage.parallelStream()
.setThreads(50)
.apply(Filters.meanFilter(9))
.collect(Collectors.toBufferedImage());

Median filter
BufferedImage bufferedImage = streamableImage.parallelStream()
.setThreads(50)
.apply(Filters.medianFilter(9))
.collect(Collectors.toBufferedImage());

Logging mechanism
Where is the logger
There is a protected field in Filter class called
logger which lets us collect information
about what is happening in Filter subclasses.
How to use it
Simply put the information you want to investigate
like logger.info("Your message").
To make the logs visible, a configuration file
log4j2.xml needs to be set up. Example configuration:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{1} - %msg%n" />
</Console>
</Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="Console" />
</Root>
</Loggers>
</Configuration>
Using the presented configuration, the result of this line looks as follows (if it is put in SaltAndPepperFilter class):
20:00:22.423 [main] INFO SaltAndPepperFilter - Your message
Levels of logs
In the previous example, the log level used is called INFO. Currently the logger is set to display levels:
DEBUG, INFO, WARN, ERROR and FATAL.
You can still use logs of level TRACE yet those will not be shown in the output at the moment.
More about logging levels and architecure: log4j2 manual