Contains image operations.
Overview
Contains image operations. Supported formats are
- BMP - Raster graphics image file format developed by Microsoft. [18]
- PNG - PNG supports palette-based images (with palettes of 24-bit RGB or 32-bit RGBA colors), grayscale images (with or without an alpha channel for transparency), and full-color non-palette-based RGB or RGBA images. [14]
- WSQ - WSQ (Wavelet Scalar Quantization), also known as FBI Print Format, is a raster image file format used for storing images of prints. It uses lossy wavelet compression, and supports only grayscale images.
- IRAW - The format is IRAW (4 bytes), width (4 bytes, big endian unsigned int), height (4 bytes, big endian unsigned int), dpi (4 bytes, big endian unsigned int), type (4 bytes, big endian unsigned int), data.
- JPG - JPEG is a commonly used method of lossy compression for digital images, particularly for those images produced by digital photography. The degree of compression can be adjusted, allowing a selectable tradeoff between storage size and image quality. [12]
- TIFF - TIF is an image file format for storing raster graphics images, popular among graphic artists, the publishing industry, and photographers. [15]
- JPG2000 - JPEG 2000 (JP2) is an image compression standard and coding system. It was developed from 1997 to 2000 by a Joint Photographic Experts Group committee with the intention of superseding their original JPEG standard (created in 1992) [13]
- WEBP - It is intended as a replacement for JPEG, PNG, and GIF file formats. It supports both lossy and lossless compression as well as animation and alpha transparency. [16]
The rest library functionality uses Image class as abstraction of supported image formats. The library extension points are
Reading image
Function Image::Decode is used to create Image object. It automatically detects image type. For supported types see ImageType. On error the function will throw exception, e.g. for not supported ImageType.
-
c++
auto png =
Image::Decode(BinaryFile::ReadAll(
"assets/color.png"));
auto bmp =
Image::Decode(BinaryFile::ReadAll(
"assets/color.bmp"));
auto wsq =
Image::Decode(BinaryFile::ReadAll(
"assets/color.wsq"));
auto raw =
Image::Decode(BinaryFile::ReadAll(
"assets/color.iraw"));
auto jpg =
Image::Decode(BinaryFile::ReadAll(
"assets/color.jpg"));
auto jp2 =
Image::Decode(BinaryFile::ReadAll(
"assets/color.jp2"));
auto webp =
Image::Decode(BinaryFile::ReadAll(
"assets/color.webp"));
auto tiff =
Image::Decode(BinaryFile::ReadAll(
"assets/color.tiff"));
-
java
Image png = Image.
Decode(BinaryFile.ReadAll(
"assets/color.png"));
Image wsq = Image.Decode(BinaryFile.ReadAll("assets/color.wsq"));
Image bmp = Image.Decode(BinaryFile.ReadAll("assets/color.bmp"));
Image raw = Image.Decode(BinaryFile.ReadAll("assets/color.iraw"));
Image jpg = Image.Decode(BinaryFile.ReadAll("assets/color.jpg"));
Image jp2 = Image.Decode(BinaryFile.ReadAll("assets/color.jp2"));
Image tiff = Image.Decode(BinaryFile.ReadAll("assets/color.tiff"));
Image webp = Image.Decode(BinaryFile.ReadAll("assets/color.webp"));
-
csharp
Image png = Image.
Decode(BinaryFile.ReadAll(
"assets/color.png"));
Image wsq = Image.
Decode(BinaryFile.ReadAll(
"assets/color.wsq"));
Image bmp = Image.
Decode(BinaryFile.ReadAll(
"assets/color.bmp"));
Image raw = Image.
Decode(BinaryFile.ReadAll(
"assets/color.iraw"));
Image jpg = Image.
Decode(BinaryFile.ReadAll(
"assets/color.jpg"));
Image jp2 = Image.
Decode(BinaryFile.ReadAll(
"assets/color.jp2"));
Image tiff = Image.
Decode(BinaryFile.ReadAll(
"assets/color.tiff"));
Image webp = Image.
Decode(BinaryFile.ReadAll(
"assets/color.webp"));
Function Image::DecodeRawImage is used to create Image object from provided grayscale/BGR/BGRA data.
-
c++
const RawImage grayscale = {
};
-
java
RawImage grayscale = new RawImage(3, 2, new ImageDpi(500),
RawImage.Type.GRAYSCALE,
new Bytes(new byte[] { 0, 30, 40, -1, 15, -128 }));
-
csharp
RawImage grayscale =
new RawImage(3, 2, new ImageDpi(500), RawImage.Type.GRAYSCALE,
new Bytes(new byte[] { 0, 30, 40, 255, 15, 128 }));
Image img = Image.DecodeRawImage(grayscale);
Writing/Converting image
Function Image::EncodeIn is used to convert image via ImageEncoder.
-
c++
auto png =
Image::Decode(BinaryFile::ReadAll(
"assets/color.png"));
std::ignore = png->EncodeIn(*png->OriginalEncoder());
BmpImageEncoder bmpEncoder;
auto encoded = png->EncodeIn(bmpEncoder);
BinaryFile::WriteAll("output/color_converted.bmp", encoded);
ImageFileSaver wsqFileSaver("output/color_converted.wsq");
png->SaveIn(wsqFileSaver);
png->SaveAs("output/color_converted.iraw");
png->SaveAs("output/color_converted.jpg");
#ifndef __ANDROID__
png->SaveAs("output/color_converted.jp2");
#endif
png->SaveAs("output/color_converted.tiff");
png->SaveAs("output/color_converted.webp");
-
java
Image png = Image.
Decode(BinaryFile.ReadAll(
"assets/color.png"));
BmpImageEncoder bmpEncoder = new BmpImageEncoder();
Bytes encoded = png.
EncodeIn(bmpEncoder);
BinaryFile.WriteAll("output/color_converted.bmp", encoded);
ImageFileSaver wsqSaver = new ImageFileSaver("output/color_converted.wsq");
png.
SaveAs(
"output/color_converted.iraw");
png.
SaveAs(
"output/color_converted.jpg");
if (!"The Android Project".equals(
System.getProperty("java.specification.vendor"))) {
png.
SaveAs(
"output/color_converted.jp2");
}
png.
SaveAs(
"output/color_converted.tiff");
png.
SaveAs(
"output/color_converted.webp");
-
csharp
Image png = Image.
Decode(BinaryFile.ReadAll(
"assets/color.png"));
BmpImageEncoder bmpEncoder = new BmpImageEncoder();
Bytes encoded = png.
EncodeIn(bmpEncoder);
BinaryFile.WriteAll("output/color_converted.bmp", encoded);
ImageFileSaver wsqSaver = new ImageFileSaver("output/color_converted.wsq");
png.
SaveAs(
"output/color_converted.iraw");
png.
SaveAs(
"output/color_converted.jpg");
png.
SaveAs(
"output/color_converted.jp2");
png.
SaveAs(
"output/color_converted.tiff");
png.
SaveAs(
"output/color_converted.webp");
Resize
Functions Image::Resize and Image::ResizeToMaxDimension are used to resize image.
-
c++
auto img =
Image::Decode(BinaryFile::ReadAll(
"assets/color.png"));
auto resized = img->Resize(0.5F);
auto resizedToMaxDimension = img->ResizeToMaxDimension(img->Width() / 2);
resized->SaveAs("output/color_resized_half.png");
resizedToMaxDimension->SaveAs("output/color_resized_half_dimension.png");
-
java
Image img = Image.
Decode(BinaryFile.ReadAll(
"assets/color.png"));
Image resized = img.
Resize(0.5F);
resized.
SaveAs(
"output/color_resized_half.png");
resizedToMaxDimension.
SaveAs(
"output/color_resized_half_dimension.png");
-
csharp
Image img = Image.Decode(BinaryFile.ReadAll("assets/color.png"));
Image resized = img.
Resize(0.5F);
resized.
SaveAs(
"output/color_resized_half.png");
resizedToMaxDimension.
SaveAs(
"output/color_resized_half_dimension.png");
Resize input
Resize output
Change DPI
Function Image::ChangeDpiTo is used to change DPI of image. The original image is resized with factor targetDPI/originalDPI.
-
c++
auto img =
Image::Decode(BinaryFile::ReadAll(
"assets/color.png"), 1000);
auto changed = img->ChangeDpiTo(ImageDpi(500));
changed->SaveAs("output/color_dpi_500.png");
-
java
Image img = Image.Decode(BinaryFile.ReadAll("assets/color.png"), 1000);
changed.
SaveAs(
"output/color_dpi_500.png");
-
csharp
Image img = Image.
Decode(BinaryFile.ReadAll(
"assets/color.png"), 1000);
changed.
SaveAs(
"output/color_dpi_500.png");
DPI change input
DPI change output
Draw shape
For each shape function Image::DrawShape creates new Image to keep current instance immutable. If more shapes need to be drawn in one image, then implement new class with base ImageShape e.g RectanglesShape. Then it is possible to draw into image via ImageShapeDrawer.
Draw input
Draw rectangle output
-
c++
auto img =
Image::Decode(BinaryFile::ReadAll(
"assets/color.png"));
const Rectangle rectangle{ { 37, 20 }, { 79, -11 }, { 109, 29 }, { 67, 60 } };
const RectangleShape shape(rectangle, Shapes::InnoBlue);
auto drawnImage = img->DrawShape(shape);
drawnImage->SaveAs("output/color_drawn.bmp");
-
java
Image img = Image.
Decode(BinaryFile.ReadAll(
"assets/color.png"));
Rectangle rectangle = new Rectangle(new Point(37, 20), new Point(79, -11),
new Point(109, 29), new Point(67, 60));
RectangleShape shape = new RectangleShape(rectangle, Shapes.InnoBlue);
drawnImage.
SaveAs(
"output/color_drawn.bmp");
-
csharp
Image img = Image.
Decode(BinaryFile.ReadAll(
"assets/color.png"));
Rectangle rectangle = new Rectangle(new Point(37, 20), new Point(79, -11),
new Point(109, 29), new Point(67, 60));
RectangleShape shape = new RectangleShape(rectangle, Shapes.InnoBlue);
drawnImage.
SaveAs(
"output/color_drawn.bmp");
Draw circle output
-
c++
auto img =
Image::Decode(BinaryFile::ReadAll(
"assets/color.png"));
const CircleShape shape(Circle{ { 30, 45 }, 10 }, Shapes::InnoBlue);
auto drawnImage = img->DrawShape(shape);
drawnImage->SaveAs("output/color_drawn_circle.bmp");
-
java
Image img = Image.
Decode(BinaryFile.ReadAll(
"assets/color.png"));
CircleShape shape = new CircleShape(
new Circle(new Point(30, 45), 10), Shapes.InnoBlue);
drawnImage.
SaveAs(
"output/color_drawn_circle.bmp");
-
csharp
Image img = Image.
Decode(BinaryFile.ReadAll(
"assets/color.png"));
CircleShape shape =
new CircleShape(new Circle(new Point(30, 45), 10), Shapes.InnoBlue);
drawnImage.
SaveAs(
"output/color_drawn_circle.bmp");
Draw custom shape output
-
c++
class CustomShape : public ImageShape
{
public:
void DrawIn(ImageShapeDrawer& drawer) const final
{
drawer.DrawLine({ { 0, 0 }, { 100, 100 } }, { { { 0, 255, 0 }, 50 }, 5 });
drawer.DrawCircle({ { 0, 0 }, 30 }, { { { 255, 0, 0 }, 100 }, 5 });
}
};
static void DrawCustomShapeInImage()
{
auto img =
Image::Decode(BinaryFile::ReadAll(
"assets/color.png"));
const CustomShape customShape{};
auto drawnImage = img->DrawShape(customShape);
drawnImage->SaveAs("output/color_custom_drawn.png");
}
-
java
public class CustomShape extends ImageShape {
@Override
public void DrawIn(ImageShapeDrawer drawer) {
ImageShapeAttributes attr = new ImageShapeAttributes();
attr.setRgba(new RGBA((short) 0, (short) 255, (short) 0, (short) 50));
attr.setThickness((short) 5);
drawer.
DrawLine(
new Line(
new Point(0, 0),
new Point(100, 100)), attr);
attr.setRgba(new RGBA((short) 255, (short) 0, (short) 0, (short) 100));
drawer.
DrawCircle(
new Circle(
new Point(0, 0), 30), attr);
}
};
public void DrawCustomShapeInImage() {
Image img = Image.
Decode(BinaryFile.ReadAll(
"assets/color.png"));
CustomShape shape = new CustomShape();
drawnImage.
SaveAs(
"output/color_custom_drawn.png");
}
-
csharp
public class CustomShape : ImageShape
{
public override void DrawIn(ImageShapeDrawer drawer)
{
ImageShapeAttributes attr = new ImageShapeAttributes();
attr.rgba = new RGBA(0, 255, 0, 50);
attr.thickness = 5;
drawer.
DrawLine(
new Line(
new Point(0, 0),
new Point(100, 100)), attr);
attr.rgba = new RGBA(255, 0, 0, 100);
drawer.
DrawCircle(
new Circle(
new Point(0, 0), 30), attr);
}
};
public void DrawCustomShapeInImage()
{
Image img = Image.
Decode(BinaryFile.ReadAll(
"assets/color.png"));
CustomShape shape = new CustomShape();
drawnImage.
SaveAs(
"output/color_custom_drawn.png");
}
Mask shape
For each shape function Image::MaskImageBy creates new Image to keep current instance immutable. If more shapes need to be masked in one image, then use custom mask class extending ImageMask where you can add any combination of PolygonImageMask and CircleImageMask. The each mask shape has ImageMaskAttributes
- masked area
- INSIDE - Mask is applied to the region inside the shape, preserving the area outside.
- OUTSIDE - Mask is applied to the region outside the shape, preserving the area inside.
- blurring mask border after applying mask
-
c++
const auto img =
Image::Decode(BinaryFile::ReadAll(
"assets/color.png"));
const Circle circle{ { 60, 60 }, 20 };
auto insideMask = CircleImageMask(
circle,
auto maskedInside = img->MaskImageBy(insideMask);
maskedInside->SaveAs("output/masked_circle_inside.png");
auto outsideMask = CircleImageMask(
circle,
auto maskedOutside = img->MaskImageBy(outsideMask);
maskedOutside->SaveAs("output/masked_circle_outside.png");
-
java
Image img = Image.
Decode(BinaryFile.ReadAll(
"assets/color.png"));
Circle circle = new Circle(new Point(60, 60), 20);
CircleImageMask insideMask = new CircleImageMask(circle,
new ImageMaskConfiguration(
ImageMaskType.INSIDE, Colors.InnoBlue),
maskedInside.
SaveAs(
"output/masked_circle_inside.png");
CircleImageMask outsideMask = new CircleImageMask(circle,
new ImageMaskConfiguration(
ImageMaskType.OUTSIDE, Colors.InnoBlue),
maskedOutside.
SaveAs(
"output/masked_circle_outside.png");
-
csharp
Image img = Image.
Decode(BinaryFile.ReadAll(
"assets/color.png"));
var circle = new Circle(new Point(60, 60), 20);
var insideMask = new CircleImageMask(
circle,
new ImageMaskConfiguration(
ImageMaskType.INSIDE, Colors.InnoBlue),
maskedInside.SaveAs("output/masked_circle_inside.png");
var outsideMask = new CircleImageMask(
circle,
new ImageMaskConfiguration(
ImageMaskType.OUTSIDE, Colors.InnoBlue),
maskedOutside.SaveAs("output/masked_circle_outside.png");
Circle masked inside
Circle masked outside
-
c++
const auto img =
Image::Decode(BinaryFile::ReadAll(
"assets/color.png"));
const Polygon polygon{ { { 50, 20 }, { 80, 80 }, { 20, 80 } } };
auto insideMask = PolygonImageMask(
polygon,
auto maskedInside = img->MaskImageBy(insideMask);
maskedInside->SaveAs("output/masked_polygon_inside.png");
auto outsideMask = PolygonImageMask(
polygon,
auto maskedOutside = img->MaskImageBy(outsideMask);
maskedOutside->SaveAs("output/masked_polygon_outside.png");
-
java
Image img = Image.
Decode(BinaryFile.ReadAll(
"assets/color.png"));
Polygon polygon = new Polygon(new Points(new ArrayList<>(
Arrays.asList(new Point(50, 20), new Point(80, 80), new Point(20, 80)))));
PolygonImageMask insideMask = new PolygonImageMask(polygon,
new ImageMaskConfiguration(
ImageMaskType.INSIDE, Colors.InnoBlue),
maskedInside.
SaveAs(
"output/masked_polygon_inside.png");
PolygonImageMask outsideMask = new PolygonImageMask(polygon,
new ImageMaskConfiguration(
ImageMaskType.OUTSIDE, Colors.InnoBlue),
maskedOutside.
SaveAs(
"output/masked_polygon_outside.png");
-
csharp
var img = Image.
Decode(BinaryFile.ReadAll(
"assets/color.png"));
var polygon = new Polygon(new Points(
new List<Point> { new Point(50, 20), new Point(80, 80), new Point(20, 80) }));
var insideMask = new PolygonImageMask(
polygon,
new ImageMaskConfiguration(
ImageMaskType.INSIDE, Colors.InnoBlue),
var maskedInside = img.MaskImageBy(insideMask);
maskedInside.SaveAs("output/masked_polygon_inside.png");
var outsideMask = new PolygonImageMask(
polygon,
new ImageMaskConfiguration(
ImageMaskType.OUTSIDE, Colors.InnoBlue),
var maskedOutside = img.MaskImageBy(outsideMask);
maskedOutside.SaveAs("output/masked_polygon_outside.png");
Polygon masked and blurred inside
Polygon masked and blurred outside
-
c++
class CustomMask : public ImageMask
{
public:
void MaskWith(ImageMasker& masker) const override
{
const Polygon polygon{ { { 50, 20 }, { 80, 80 }, { 20, 80 } } };
const Circle circle{ { 60, 60 }, 20 };
polygon,
}
};
static void MaskImageWithCombination()
{
const auto img =
Image::Decode(BinaryFile::ReadAll(
"assets/color.png"));
const CustomMask mask;
auto maskedImage = img->MaskImageBy(mask);
maskedImage->SaveAs("output/masked_combination.png");
}
-
java
public class CustomMask extends ImageMask {
@Override
public void MaskWith(ImageMasker masker) {
Polygon polygon = new Polygon(new Points(Arrays.asList(
new Point(50, 20), new Point(80, 80), new Point(20, 80))));
Circle circle = new Circle(new Point(60, 60), 20);
new ImageMaskConfiguration(
ImageMaskType.OUTSIDE, Colors.InnoBlue));
}
};
public void MaskImageWithCombination() {
Image img = Image.
Decode(BinaryFile.ReadAll(
"assets/color.png"));
CustomMask mask = new CustomMask();
maskedImage.
SaveAs(
"output/masked_combination.png");
}
-
csharp
public class CustomMask : ImageMask
{
public override void MaskWith(ImageMasker masker)
{
var polygon = new Polygon(
new Points(new List<Point> { new Point(50, 20), new Point(80, 80),
new Point(20, 80) }));
var circle = new Circle(new Point(60, 60), 20);
circle,
new ImageMaskConfiguration(
ImageMaskType.INSIDE, Colors.White));
Colors.InnoBlue));
}
}
public void MaskImageWithCombination()
{
var img = Image.Decode(BinaryFile.ReadAll("assets/color.png"));
var mask = new CustomMask();
var maskedImage = img.MaskImageBy(mask);
maskedImage.SaveAs("output/masked_combination.png");
}
Masked combination
Crop aligned rectangle
Use function Image::CropAlignedRectangle to crop and align rectangle. It Crop rectangle and align given top left rectangle point to coordinates [0,0] in new image.
Crop aligned rectangle input
Crop aligned rectangle output
-
c++
auto img =
Image::Decode(BinaryFile::ReadAll(
"assets/color.png"));
const Rectangle rectangle{ { 79, -11 }, { 109, 29 }, { 67, 60 }, { 37, 20 } };
auto copiedImage = img->CropAlignedRectangle(rectangle);
copiedImage->SaveAs("output/color_copied_align.bmp");
-
java
Image img = Image.
Decode(BinaryFile.ReadAll(
"assets/color.png"));
Rectangle rectangle = new Rectangle(new Point(79, -11), new Point(109, 29),
new Point(67, 60), new Point(37, 20));
copiedImage.
SaveAs(
"output/color_copied_align.bmp");
-
csharp
Image img = Image.
Decode(BinaryFile.ReadAll(
"assets/color.png"));
Rectangle rectangle = new Rectangle(new Point(79, -11), new Point(109, 29),
new Point(67, 60), new Point(37, 20));
copiedImage.
SaveAs(
"output/color_copied_align.bmp");
Crop rectangle
Use function Image::CropRectangle to crop rectangle. It Crops a rectangle from the image, using a white background for any extra space.
Crop rectangle input
Crop rectangle output
-
c++
auto img =
Image::Decode(BinaryFile::ReadAll(
"assets/color.png"));
const Rectangle rectangle{ { 37, 20 }, { 79, -11 }, { 109, 29 }, { 67, 60 } };
auto copiedImage = img->CropRectangle(rectangle, Colors::InnoBlue);
copiedImage->SaveAs("output/color_copied.bmp");
-
java
Image img = Image.
Decode(BinaryFile.ReadAll(
"assets/color.png"));
Rectangle rectangle = new Rectangle(new Point(37, 20), new Point(79, -11),
new Point(109, 29), new Point(67, 60));
Image copiedImage = img.
CropRectangle(rectangle, Colors.InnoBlue);
copiedImage.
SaveAs(
"output/color_copied.bmp");
-
csharp
Image img = Image.
Decode(BinaryFile.ReadAll(
"assets/color.png"));
Rectangle rectangle = new Rectangle(new Point(37, 20), new Point(79, -11),
new Point(109, 29), new Point(67, 60));
Image copiedImage = img.
CropRectangle(rectangle, Colors.InnoBlue);
copiedImage.
SaveAs(
"output/color_copied.bmp");
Crop circle
For given circle function Image::CropCircle cut circle from image.
Crop circle input
Crop circle output
-
c++
auto img =
Image::Decode(BinaryFile::ReadAll(
"assets/color.png"));
auto copiedImage = img->CropCircle(Circle{ { 30, 45 }, 10 });
copiedImage->SaveAs("output/color_copied_circle.bmp");
-
java
Image img = Image.
Decode(BinaryFile.ReadAll(
"assets/color.png"));
Image copiedImage = img.
CropCircle(
new Circle(
new Point(30, 45), 10));
copiedImage.
SaveAs(
"output/color_copied_circle.bmp");
-
csharp
Image img = Image.
Decode(BinaryFile.ReadAll(
"assets/color.png"));
Image copiedImage = img.
CropCircle(
new Circle(
new Point(30, 45), 10));
copiedImage.
SaveAs(
"output/color_copied_circle.bmp");
Intersection
Library provides functions Image::RectangleIntersection and Image::CircleIntersection that calculates intersection type with Image.
- Partial - The Object and Image has intersection.
Partial intersection
- Inside - Object is fully in Image.
Inside intersection
- Outside - Image is fully in Object.
Outside intersection
- Same - Image has same dimensions and vertices coordinates as Object.
Same intersection
- No - Image and Object has no intersection.
No intersection