Passing and receiving images

Needs["LTemplate`"]
SetDirectory@NotebookDirectory[];

Images are specified as LType[Image, type] or LType[Image3D, type], where type may be any of the usual ImageTypes. The corresponding C++ class templates are ImageRef<> and Image3DRef<>.

It is allowed to pass an image without specifying its element type, using LType[Image] or the shorthand Image. The corresponding C++ class is GenericImageRef, which serves as a base class for both ImageRef and Image3DRef.

template=
LClass["Img",
{
LFun["invert", (* inverts an Image like ColorNegate *)
{LType[Image,"Real"] (* takes a Real image *)},
Image (* the type of the returned image could be specified explicitly, but this is not necessary; Image and LType[Image] are equivalent. *)
],
LFun["blur1", (* blur at radius 1 *)
{LType[Image,"Real"]},
Image
],
LFun["imageDimensions", (* find image dimensions *)
{{Image,"Constant"}}, (* works on images with any pixel type, without converting them *)
{Integer,1} (* return integer vector *)
],
LFun["gradient",{Integer (* width *), Integer (* height *)},LType[Image]],
LFun["mandelbrot",
{Complex (* lower *),Complex (* upper *),Integer (* image width *),Integer (* iterations *)},
LType[Image]
],
LFun["adjust",{LType[Image]},LType[Image]]
}
];

CompileTemplate[template]

LoadTemplate[template]

obj=Make[Img]

Invert an image

im=;

obj@"invert"[im]

The invert() function takes images of type Real. If we pass any other type of image to the function, it will be converted to Real. Thus the result that invert() returns is also of type Real.

ImageType/@{im,obj@"invert"[im]}

Note that the function works on image both with and without an alpha channel. The alpha channel is never modified.

ColorSeparate[obj@"invert"[im]]

ColorSeparate[obj@"invert"[RemoveAlphaChannel[im]]]

Blur an image

im=Image@Graphics[{Antialiasing->False,Circle[]},ImageSize->Tiny]

obj@"blur1"[im]

Nest[obj@"blur1"[#]&,im,10]

Get image dimensions

The imageDimensions() function works on images of arbitrary pixel type without conversions. This, along with using “Constant” passing that avoids copying, makes the function extremely efficient.

obj@"imageDimensions"[]

It is just as fast as the built-in ImageDimensions.

obj@"imageDimensions"[]//RepeatedTiming

ImageDimensions[]//RepeatedTiming

Create a gradient image

obj@"gradient"[200,50]

Mandelbrot set

The first two arguments define the rectangle in the complex plane where the calculation will be done. The third is the image width and the fourth is the maximum number of iterations to try.

ImageAdjust[obj@"mandelbrot"[-2.2-1.2I,1+1.2I,300,30]]

Display the image in nicer colours.

Colorize[%,ColorRules->{0.->Black}]

ImageAdjust[obj@"mandelbrot"[-0.4+0.5I,0.1+1.2I,300,50]]

Generic images

The adjust function “stretches” the values in the image to fill out the entire available range, similarly to ImageAdjust. The C++ code demonstrates working on images of arbitrary type.

im=;

ImageType[im]

obj@"adjust"[im]

ImageType[%]

obj@"adjust"[Image[im,"Real"]]

ImageType[%]