Examples.en.md
January 29, 2023 · View on GitHub
This article will list some examples so that developers can quickly understand the functions of imglib and easily use them. All these examples can be found in example/.../Setting.java, and you can run the example module to execute the corresponding functions.
Image Collection
Create a transparent image
ImagePipes.ofEmptySource()
.register(new TransparentImageGenerator.Builder()
.width(300)
.height(200)
.build())
.toFile(ExampleUtils.tmpFileNameOf("out/transparent.png"));
In this example, an image with size of 300px * 200px and transparent background will be created and saved to the file
of .../out/transparent.png.
Create a mono color image
ImagePipes.ofEmptySource()
.register(new MonoColorImageGenerator.Builder()
.width(300)
.height(200)
.alpha(0.2f)
.color(ColorUtils.random())
.build())
.toFile(ExampleUtils.tmpFileNameOf("out/mono_color.png"));
In this example, an image with size of 300px * 200px, transparency of 0.2 and random background color will be created
and saved to file of .../out/mono_color.png. Tip: the transparency value is between [0, 1], when it is equal to 1,
the image is completely opaque, and when it is equal to 0, the image is completely transparent.

Take a screenshot
ImagePipes.ofEmptySource()
.register(new ScreenshotGenerator.Builder()
.startPoint(600, 300)
.width(280)
.height(190)
.build())
.toFile(ExampleUtils.tmpFileNameOf("out/screenshot.png"));
In this example, a screenshot will be captured. The screenshot range is a rectangular area with the upper left corner
coordinate of [600, 300], width of 280px and height of 190px. The captured screenshot will be saved to the file of
.../out/screenshot.png.

Create a hash image
ImagePipes.ofEmptySource()
.register(new HashImageGenerator.Builder("imglib-user")
.gridVerticalNum(5)
.fgColor(ColorUtils.of(50, 150, 50))
.build())
.toFile(ExampleUtils.tmpFileNameOf("out/hash.png"));
In this example, a two-dimensional matrix with size of 5px * 5px will be created. If the value of the pixel at the
corresponding position in the matrix is true, the foreground color of the pixel will be set to [(R) 50, (G) 150, (B) 50],
and the dot matrix image will be saved to the file of .../out/hash.png.

For the convenience of observation, the displayed image is not the image out/hash.png but the enlarged image, because
the generated image has just only 25 pixels.
Extract image from page of PDF file
ImagePipes.ofPdf(ExampleUtils.tmpFileNameOf("in/jvms8.pdf"))
.register(0)
.dpi(280)
.toFile(ExampleUtils.tmpFileNameOf("out/page_1_of_jvms8.jpg"));
In this example, the specified pdf file of .../in/jvms8.pdf will be parsed, and the page whose index is 0 is extracted
as an image, and the DPI (pixels per inch) is set to 280 when extracting the image, and the image is saved to the file
of .../out/page_1_of_jvms8.jpg.

Extract image from frame of GIF file
ImagePipes.ofGif(ExampleUtils.tmpFileNameOf("in/duck.gif"))
.registerAll()
.toFiles(ExampleUtils.tmpFileNameOf("out/gif/frame_1.jpg"),
ExampleUtils.tmpFileNameOf("out/gif/frame_2.jpg"),
ExampleUtils.tmpFileNameOf("out/gif/frame_3.jpg"),
ExampleUtils.tmpFileNameOf("out/gif/frame_4.jpg"),
ExampleUtils.tmpFileNameOf("out/gif/frame_5.jpg"));
In this example, the specified gif file of .../in/duck.gif will be parsed, all frames of the gif file will be
extracted as a list of images, and these images will be saved to file directory of .../out/gif/ one by one in the
order of frames.
| original GIF file | list of extracted images |
|---|---|
![]() | ![]() |
Merging and Splitting
Split image with grid
ImagePipes.of(ExampleUtils.tmpFileNameOf("in/before_split.jpg"))
.addFilter(new GridSplitHandler.Builder()
.gridWidth(400)
.gridHeight(250)
.build())
.toFiles(ExampleUtils.tmpFileNameOf("out/split/slice_1.jpg"),
ExampleUtils.tmpFileNameOf("out/split/slice_2.jpg"),
ExampleUtils.tmpFileNameOf("out/split/slice_3.jpg"),
ExampleUtils.tmpFileNameOf("out/split/slice_4.jpg"),
ExampleUtils.tmpFileNameOf("out/split/slice_5.jpg"),
ExampleUtils.tmpFileNameOf("out/split/slice_6.jpg"),
ExampleUtils.tmpFileNameOf("out/split/slice_7.jpg"),
ExampleUtils.tmpFileNameOf("out/split/slice_8.jpg"),
ExampleUtils.tmpFileNameOf("out/split/slice_9.jpg"));
In this example, a rectangular area with size of 400px * 250px will be used to extract images from the original image
line by line from left to right until the rectangle touches (or contains) the image boundary, and the extracted images
will be saved to the file directory of .../out/split/ in order.
| original image | list of images after split |
|---|---|
![]() | ![]() |
Merge images with grid
ImagePipes.of(ExampleUtils.tmpFileNameOf("in/to_merge/spring.jpg"),
ExampleUtils.tmpFileNameOf("in/to_merge/summer.jpg"),
ExampleUtils.tmpFileNameOf("in/to_merge/winter.jpg"),
ExampleUtils.tmpFileNameOf("in/to_merge/autumn.jpg"))
.addFilter(new GridMergeHandler.Builder()
.horizontalNum(2)
.fillColor(ColorUtils.of(240, 240, 240))
.gridWidth(530)
.gridHeight(530)
.autoAdapts()
.alignCenter()
.build())
.toFile(ExampleUtils.tmpFileNameOf("out/after_merge.jpg"));
In this example, four images spring.jpg,summer.jpg,winter.jpg,autumn.jpg will be loaded from the file directory
of .../in/to_merge/, and these images will be in order splicing in one image, the splicing rules are as follows:
- use a grid with a fixed size of 530px * 530px to hold each image;
- enable automatic grid adjustment, reset the size of the grid when the grid is not enough to accommodate an image;
- set image center alignment, including horizontal and vertical;
- the number of grids placed in each row is set to 2;
- the blank part is filled with the color [(R) 240, (G) 240, (B) 240] if an image cannot cover the entire grid area;
The stitched image will be saved to file of .../out/after_merge.jpg.
| list of original images | merged image |
|---|---|
![]() | ![]() |
Encode image(s) to GIF file
ImagePipes.of(ExampleUtils.tmpFileNameOf("in/to_merge/spring.jpg"),
ExampleUtils.tmpFileNameOf("in/to_merge/summer.jpg"),
ExampleUtils.tmpFileNameOf("in/to_merge/winter.jpg"),
ExampleUtils.tmpFileNameOf("in/to_merge/autumn.jpg"))
.toFile(new GifFileEncoder.Builder()
.filename(ExampleUtils.tmpFileNameOf("out/seasons.gif"))
.delay(400)
.repeat(0)
.build());
In this example, four images of spring.jpg,summer.jpg,winter.jpg,autumn.jpg will be loaded from the file
directory of .../in/to_merge/ and encoded into the file of .../out/seasons.gif, the output file switches to the
next frame every 400ms, and has been set to repeat mode.
| list of original images | the GIF file after encoded |
|---|---|
![]() | ![]() |
Image Processing
Although Thumbnailator is mainly used to process thumbnails, it still provides us with basic image processing
capabilities, including size scaling, scaling, area cropping, rotation, and adding watermarks, etc. Imglib expands a
series of new image processing capabilities on the basis of Thumbnailator, and all new functions implement the
ImageFilter interface, which can be accessed through Thumbnails.Builder#addFilter(ImageFilter),
Thumbnails.Builder#addFilters(List<ImageFilter>) way to use.
Add a border to the image
Thumbnails.of(ExampleUtils.tmpFileNameOf("in/panda.jpg"))
.addFilter(new BorderHandler.Builder()
.vMargins(30)
.hMargins(20)
.fillColor(ColorUtils.of(240, 230, 175))
.build())
.scale(1.0)
.toFile(ExampleUtils.tmpFileNameOf("out/bordered.jpg"));
In this example, a border will be added to the image of .../in/panda.jpg with a margin of 20 px horizontally and 30 px
vertically, and the processed image will be saved to file of .../out/bordered.jpg.
| original image | after add border |
|---|---|
![]() | ![]() |
Add a mosaic to the image
Thumbnails.of(ExampleUtils.tmpFileNameOf("in/panda.jpg"))
.addFilter(new MosaicHandler.Builder()
.height(160)
.width(180)
.startX(480)
.startY(260)
.sideLength(10)
.build())
.scale(1.0)
.toFile(ExampleUtils.tmpFileNameOf("out/after_mosaic.jpg"));
In this example, a mosaic will be added to a part of the .../in/panda.jpg image.The coordinates of the upper left
corner of the area are [480, 260], and the width and height are 180px and 160px respectively. The side length of each
mosaic block is fixed at 10 px, and the processed image will be saved to the file of.../out/after_mosaic.jpg.
| original image | after mosaic |
|---|---|
![]() | ![]() |
Rounded the corners of image
Thumbnails.of(ExampleUtils.tmpFileNameOf("in/panda.jpg"))
.addFilter(new RoundRectHandler.Builder()
.arcWidth(100)
.arcHeight(100)
.build())
.scale(1.0)
.toFile(ExampleUtils.tmpFileNameOf("out/rounded.png"));
In this example, the four corners of the original image .../in/panda.jpg will be changed to rounded corners, the
horizontal and vertical diameters of the corner arcs are both 100px, and the processed image will be saved to file of
.../out/rounded.png. It is worth noting that the rounded image must be specified as a PNG format when saving,
otherwise it will have no effect.
| original image | after rounded the corners |
|---|---|
![]() | ![]() |
Enlarge image size lossless
Thumbnails.of(ExampleUtils.tmpFileNameOf("in/chaotic_points.png"))
.addFilter(new HighQualityExpandHandler.Builder()
.finalWidth(300)
.keepAspectRatio(true)
.build())
.scale(1.0)
.toFile(ExampleUtils.tmpFileNameOf("out/expanded.png"));
Although Thumbnailator already offers the ability to resize images, images usually become blurry which have been
enlarged by it because of the loss of image quality. When we need to expand the image lossless, we can use
HighQualityExpandHandler to achieve it.
In this example, the size of the original image .../in/chaotic_points.png is 100px * 60px, after zooming in, we will
get a 300px * 180px image which has been saved to file of ... /out/expanded.png. Usually, we only need to specify a
final width (or final height), and set it to keep the aspect ratio, so that we can get an image that is proportional to
the original image.
| original image | enlarged image |
|---|---|
![]() | ![]() |
| size:100px * 60px | size:300px * 180px |
Grayscaled image
Thumbnails.of(ExampleUtils.tmpFileNameOf("in/panda.jpg"))
.addFilter(new ModeAdaptor(
new WeightGrayingStrategy.Builder()
.redWeight(0.3f)
.greenWeight(0.59f)
.build()))
.scale(1.0)
.toFile(ExampleUtils.tmpFileNameOf("out/grayed.jpg"));
In this example, the original image .../in/panda.jpg will be grayscaled, and the strategy adopted is to grayscale by
weight. The red component accounts for 30%, and the green component accounts for 59%. The blue component accounts for
11%, and the grayscaled image will be saved to the file of .../out/grayed.jpg. Assuming that the original RGB value
of any pixel is [r', g', b'], the formula for calculating the gray value is val = (r' * 0.3 + g' * 0.59 + b' * 0.11) ,
and the final RGB value of the pixel is [val, val, val].
In addition to the graying strategy by weight, imglib also provides the average graying strategy AvgGrayingStrategy,
the maximum graying strategy MaxGrayingStrategy, the minimum graying strategy MinGrayingStrategy and the fixed
component graying strategy FixedGrayingStrategy, and developers can extend AbstractGrayingStrategy to achieve custom
grayscale implementation.
| original image | grayscaled image |
|---|---|
![]() | ![]() |
Binarized image
AbstractGrayingStrategy strategy = new FixedGrayingStrategy(FixedGrayingStrategy.FixedOption.R);
Thumbnails.of(ExampleUtils.tmpFileNameOf("in/panda.jpg"))
.addFilter(new ModeAdaptor(
new SimpleBinaryStrategy.Builder()
.grayingStrategy(strategy)
.threshold(120)
.build()))
.scale(1.0)
.toFile(ExampleUtils.tmpFileNameOf("out/binary.jpg"));
In this example, the original image .../in/panda.jpg will be binarized, the grayscale strategy adopted is the fixed
component (R) grayscale strategy, and the binarization strategy is the simple strategy which requires setting a threshold
threshold, when the gray value is greater than the threshold, each component of the pixel will be set to 255, otherwise
it will be set to 0.
In addition to the simple binarization strategy, developers can extend AbstractBinaryStrategy to achieve the custom
binarization implementation.
| original image | binarized image |
|---|---|
![]() | ![]() |
Opening shape
Thumbnails.of(ExampleUtils.tmpFileNameOf("in/panda.jpg"))
.addFilter(new ShapeAdaptor(
new Line.Builder()
.start(new Point(200, 260))
.end(new Point(1000, 260))
.color(ColorUtils.random())
.stroke(new BasicStroke(6))
.build()))
.scale(1.0)
.toFile(ExampleUtils.tmpFileNameOf("out/painted_line.jpg"));
In this example, a straight line will be drawn on the original image /in/panda.jpg, the starting point and ending
point of the line are [200, 260], [1000, 260] respectively, and the color of the line is random. The thickness of
the brush is set to 6px, and the processed image will be saved to file of .../out/painted_line.jpg.
For the extension of the opening shape, developers can implement it by extending AbstractOpenedShape.
| original image | image after adding opening shape |
|---|---|
![]() | ![]() |
Closed shape
Thumbnails.of(ExampleUtils.tmpFileNameOf("in/panda.jpg"))
.addFilter(new ShapeAdaptor(
new Oval.Builder()
.fill(true)
.color(ColorUtils.random())
.rect(new Rectangle(220, 110, 680, 350))
.build()))
.scale(1.0)
.toFile(ExampleUtils.tmpFileNameOf("out/fill_oval.jpg"));
In this example, an oval will be drawn on the original image /in/panda.jpg, the coordinates of the upper left corner
of the circumscribed rectangle of the ellipse are [220, 110], and the length and width of the circumscribed rectangle
are 680px and 350px, and set to fill the oval with a random color, the processed image will be saved to the file of
.../out/fill_oval.jpg.
For a closed shape, there are two modes of drawing, one is to fill the interior, and the other is to only draw the
border. If the developer wishes to draw the shape's border, a brush Stroke object should also be specified. In
addition to the ellipse, imglib also provides the implementation of the rectangle Rect, and developers can achieve
other closed shapes by extending AbstractClosedShape.
| original image | image after adding closed shape |
|---|---|
![]() | ![]() |















