Tips and tricks #13: Bitmaps and Pixel manipulation
This article describes how to write calculators for an image manipulation
Tips and tricks series
- Tips and tricks #1: How to set output value
- Tips and tricks #2: How to make calculator translatable into different languages
- Tips and tricks #3: How to make calculator with custom errors
- Tips and tricks #4: How to make calculator with table output
- Tips and tricks #5: How to show/hide input and output controls in a calculator
- Tips and tricks #6: How to make calculator with virtual keyboard
- Tips and tricks #7: How to make calculator with SVG image map
- Tips and tricks #8: How to reuse existing calculator
- Tips and tricks #9: Big numbers
- Tips and tricks #10: Files, long calculation mode
- Tips and tricks #11: Dynamic table columns
- Tips and tricks #12: Long (infinite) calculations
- Tips and tricks #13: Bitmaps and Pixel manipulation
- Tips and tricks #14: How to use a masked input
This article may rely on knowledge you should get from previous articles, so you may want to check them first.
To manipulate an image, you need to use the "Bitmap" input control. The loaded image is then represented by an input variable with the following properties:
- data, the array of type Uint8ClampedArray, which holds RGBA values of the image in the range 0-255.
- width, integer, the width of the image
- height, integer, the height of the image
While these properties are the same as in the ImageData, the input variable is not an ImageData object. Be careful with data property manipulation - to avoid unnecessary copying, this property corresponds to image data, thus all changes will persist between calculations. So, if you want to display the original image along with the inverted image, as it is done below, copy the data array, then change the copy.
The calculator for inverting image colors below illustrates the feature. The source input variable is the variable of the "Bitmap" type, the outsource and outinv are the output variables of the "Picture" type. The "Picture" output now supports setting an ImageData object as its value.
Here is the complete code of the calculator
var src = new ImageData(source.data, source.width, source.height);
outsource.SetValue(src);
var pix = new Uint8ClampedArray(source.data);
for (var i = 0, n = pix.length; i < n; i += 4) {
pix[i ] = 255 - pix[i ]; // red
pix[i+1] = 255 - pix[i+1]; // green
pix[i+2] = 255 - pix[i+2]; // blue
}
var inv = new ImageData(pix, source.width, source.height);
outinv.SetValue(inv);
Comments