diff --git a/resources/png-24bit.GetPointWhite-macos-11.golden.png b/resources/png-24bit.GetPointWhite-macos-11.golden.png new file mode 100644 index 00000000..040e136d Binary files /dev/null and b/resources/png-24bit.GetPointWhite-macos-11.golden.png differ diff --git a/resources/png-24bit.GetPointWhiteR-macos-11.golden.png b/resources/png-24bit.GetPointWhiteR-macos-11.golden.png new file mode 100644 index 00000000..040e136d Binary files /dev/null and b/resources/png-24bit.GetPointWhiteR-macos-11.golden.png differ diff --git a/resources/png-24bit.GetPointYellow-macos-11.golden.png b/resources/png-24bit.GetPointYellow-macos-11.golden.png new file mode 100644 index 00000000..040e136d Binary files /dev/null and b/resources/png-24bit.GetPointYellow-macos-11.golden.png differ diff --git a/resources/with_alpha.GetPoint_WithAlpha-macos-11.golden.png b/resources/with_alpha.GetPoint_WithAlpha-macos-11.golden.png new file mode 100644 index 00000000..3969520f Binary files /dev/null and b/resources/with_alpha.GetPoint_WithAlpha-macos-11.golden.png differ diff --git a/resources/with_alpha.GetPoint_WithAlpha2-macos-11.golden.png b/resources/with_alpha.GetPoint_WithAlpha2-macos-11.golden.png new file mode 100644 index 00000000..3969520f Binary files /dev/null and b/resources/with_alpha.GetPoint_WithAlpha2-macos-11.golden.png differ diff --git a/vips/arithmetic.c b/vips/arithmetic.c index 10967ea8..81cd5564 100644 --- a/vips/arithmetic.c +++ b/vips/arithmetic.c @@ -45,3 +45,7 @@ int find_trim(VipsImage *in, int *left, int *top, int *width, int *height, vips_area_unref(VIPS_AREA(vipsBackground)); return code; } + +int getpoint(VipsImage *in, double **vector, int n, int x, int y) { + return vips_getpoint(in, vector, &n, x, y, NULL); +} diff --git a/vips/arithmetic.go b/vips/arithmetic.go index 2227bf3f..f2bda66d 100644 --- a/vips/arithmetic.go +++ b/vips/arithmetic.go @@ -2,6 +2,7 @@ package vips // #include "arithmetic.h" import "C" +import "unsafe" // https://libvips.github.io/libvips/API/current/libvips-arithmetic.html#vips-add func vipsAdd(left *C.VipsImage, right *C.VipsImage) (*C.VipsImage, error) { @@ -99,3 +100,17 @@ func vipsFindTrim(in *C.VipsImage, threshold float64, backgroundColor *Color) (i return int(left), int(top), int(width), int(height), nil } + +// https://libvips.github.io/libvips/API/current/libvips-arithmetic.html#vips-getpoint +func vipsGetPoint(in *C.VipsImage, n int, x int, y int) ([]float64, error) { + incOpCounter("getpoint") + var out *C.double + defer gFreePointer(unsafe.Pointer(out)) + + if err := C.getpoint(in, &out, C.int(n), C.int(x), C.int(y)); err != 0 { + return nil, handleVipsError() + } + + // maximum n is 4 + return (*[4]float64)(unsafe.Pointer(out))[:n:n], nil +} diff --git a/vips/arithmetic.h b/vips/arithmetic.h index e91f2d33..89b8dadc 100644 --- a/vips/arithmetic.h +++ b/vips/arithmetic.h @@ -12,3 +12,4 @@ int invert_image(VipsImage *in, VipsImage **out); int average(VipsImage *in, double *out); int find_trim(VipsImage *in, int *left, int *top, int *width, int *height, double threshold, double r, double g, double b); +int getpoint(VipsImage *in, double **vector, int n, int x, int y); diff --git a/vips/image.go b/vips/image.go index 90438223..37005d21 100644 --- a/vips/image.go +++ b/vips/image.go @@ -1272,6 +1272,16 @@ func (r *ImageRef) FindTrim(threshold float64, backgroundColor *Color) (int, int return vipsFindTrim(r.image, threshold, backgroundColor) } +// GetPoint reads a single pixel on an image. +// The pixel values are returned in a slice of length n. +func (r *ImageRef) GetPoint(x int, y int) ([]float64, error) { + n := 3 + if vipsHasAlpha(r.image) { + n = 4 + } + return vipsGetPoint(r.image, n, x, y) +} + // DrawRect draws an (optionally filled) rectangle with a single colour func (r *ImageRef) DrawRect(ink ColorRGBA, left int, top int, width int, height int, fill bool) error { err := vipsDrawRect(r.image, ink, left, top, width, height, fill) diff --git a/vips/image_golden_test.go b/vips/image_golden_test.go index ab8e9aed..0f936271 100644 --- a/vips/image_golden_test.go +++ b/vips/image_golden_test.go @@ -446,6 +446,73 @@ func TestImage_Rank(t *testing.T) { }, nil, nil) } +func TestImage_GetPointWhite(t *testing.T) { + goldenTest(t, resources+"png-24bit.png", func(img *ImageRef) error { + point, err := img.GetPoint(10, 10) + + assert.Equal(t, 3, len(point)) + assert.Equal(t, 255.0, point[0]) + assert.Equal(t, 255.0, point[1]) + assert.Equal(t, 255.0, point[2]) + + return err + }, nil, nil) +} + +func TestImage_GetPointYellow(t *testing.T) { + goldenTest(t, resources+"png-24bit.png", func(img *ImageRef) error { + point, err := img.GetPoint(400, 10) + + assert.Equal(t, 3, len(point)) + assert.Equal(t, 255.0, point[0]) + assert.Equal(t, 255.0, point[1]) + assert.Equal(t, 0.0, point[2]) + + return err + }, nil, nil) +} + +func TestImage_GetPointWhiteR(t *testing.T) { + goldenTest(t, resources+"png-24bit.png", func(img *ImageRef) error { + point, err := img.GetPoint(10, 10) + + assert.Equal(t, 3, len(point)) + assert.Equal(t, 255.0, point[0]) + assert.Equal(t, 255.0, point[1]) + assert.Equal(t, 255.0, point[2]) + + return err + }, nil, nil) +} + +func TestImage_GetPoint_WithAlpha(t *testing.T) { + goldenTest(t, resources+"with_alpha.png", func(img *ImageRef) error { + point, err := img.GetPoint(10, 10) + + assert.Equal(t, 4, len(point)) + assert.Equal(t, 0.0, point[0]) + assert.Equal(t, 0.0, point[1]) + assert.Equal(t, 0.0, point[2]) + assert.Equal(t, 255.0, point[3]) + + return err + }, nil, nil) +} + +func TestImage_GetPoint_WithAlpha2(t *testing.T) { + goldenTest(t, resources+"with_alpha.png", func(img *ImageRef) error { + point, err := img.GetPoint(0, 0) + + assert.Equal(t, 4, len(point)) + assert.Equal(t, 0.0, point[0]) + assert.Equal(t, 0.0, point[1]) + assert.Equal(t, 0.0, point[2]) + assert.Equal(t, 0.0, point[3]) + + return err + }, nil, nil) +} + func TestImage_SimilarityRGB(t *testing.T) { goldenTest(t, resources+"jpg-24bit.jpg", func(img *ImageRef) error { return img.Similarity(0.5, 5, &ColorRGBA{R: 127, G: 127, B: 127, A: 127},