Skip to content

Instantly share code, notes, and snippets.

@angstyloop
Created March 5, 2023 01:29
Show Gist options
  • Save angstyloop/37d4454442beea452b718bb11469f2a4 to your computer and use it in GitHub Desktop.
Save angstyloop/37d4454442beea452b718bb11469f2a4 to your computer and use it in GitHub Desktop.
Threshold an image to black and white with the amazing open-source VIPS C library for image processing. Create a "binary image".
/** threshold.c
Create a "binary image" from an image - an image with only black (rgb(0, 0, 0))
and white (rgb(255, 255, 255)) pixels, based on a cutoff threshold for the pixel
values of the grayscale image. Pixel values above the threshold are set to 255,
255, and pixel values below the threshold are set to 0, in the new image.
COMPILE
gcc -o threshold threshold.c `pkg-config vips --cflags --libs`
EXAMPLE USAGE
./threshold 128 in.png out.png
*/
#include <vips/vips.h>
typedef guint8 PixelRGB[1];
int main (int argc, char** argv) {
if (argc != 4 || !argv[1][0] || !argv[2][0] || !argv[3][0]) {
printf("USAGE: %s <THRESHOLD (0-255)> <IMAGE_PATH>\n", argv[0]);
vips_error_exit(NULL);
}
if (VIPS_INIT(argv[0]))
vips_error_exit(NULL);
VipsImage* in, * out;
unsigned long threshold_ = strtoul(argv[1], NULL, 10);
guint8 threshold = threshold_ < 0 ? 0 : threshold_ > 255 ? 255 : threshold_;
if (!(in = vips_image_new_from_file(argv[2], NULL)))
vips_error_exit(NULL);
guint width = in->Xsize;
guint height = in->Ysize;
if (vips_colourspace(in, &out, VIPS_INTERPRETATION_B_W, NULL))
vips_error_exit(NULL);
g_object_unref(in);
in = out;
if (vips_extract_band(in, &out, 0, "n", 1, NULL))
vips_error_exit(NULL);
g_object_unref(in);
in = out;
if (vips_image_wio_input(in))
vips_error_exit(NULL);
PixelRGB* pixels = (PixelRGB*) VIPS_IMAGE_ADDR(in, 0, 0);
VipsPel* pels = VIPS_ARRAY(NULL, width * height, VipsPel);
for (int i = 0; i < width * height; ++i)
pels[i] = pixels[i][0] < threshold ? 0 : 255;
g_object_unref(in);
in = out;
if (!(in = vips_image_new_from_memory_copy(pels, width * height,
width, height, 1, VIPS_FORMAT_UCHAR)))
vips_error_exit(NULL);
if (vips_image_write_to_file(in, argv[3], NULL))
vips_error_exit(NULL);
g_object_unref(in);
in = out;
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment