Skip to content

Commit 0d82957

Browse files
Flash-nDiesteve.3282
andauthored
Add some functions (#464)
* add arithmetic functions * add functions which get background color * add/revise vips_text function * add Min function --------- Co-authored-by: steve.3282 <[email protected]>
1 parent 8d9c549 commit 0d82957

File tree

14 files changed

+316
-11
lines changed

14 files changed

+316
-11
lines changed

vips/arithmetic.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,19 @@ int hist_norm(VipsImage *in, VipsImage **out) {
6969
int hist_entropy(VipsImage *in, double *out) {
7070
return vips_hist_entropy(in, out, NULL);
7171
}
72+
73+
int subtract(VipsImage *in1, VipsImage *in2, VipsImage **out) {
74+
return vips_subtract(in1, in2, out, NULL);
75+
}
76+
77+
int absOp(VipsImage *img, VipsImage **out) {
78+
return vips_abs(img, out, NULL);
79+
}
80+
81+
int project(VipsImage *in, VipsImage **col, VipsImage **row) {
82+
return vips_project(in, col, row, NULL);
83+
}
84+
85+
int minOp(VipsImage *in, double *out, int *x, int *y, int size) {
86+
return vips_min(in, out, "x", x, "y", y, "size", size, NULL);
87+
}

vips/arithmetic.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,3 +174,50 @@ func vipsHistEntropy(in *C.VipsImage) (float64, error) {
174174

175175
return float64(out), nil
176176
}
177+
178+
// https://www.libvips.org/API/current/libvips-arithmetic.html#vips-subtract
179+
func vipsSubtract(in1 *C.VipsImage, in2 *C.VipsImage) (*C.VipsImage, error) {
180+
incOpCounter("subtract")
181+
var out *C.VipsImage
182+
183+
if err := C.subtract(in1, in2, &out); err != 0 {
184+
return nil, handleImageError(out)
185+
}
186+
187+
return out, nil
188+
}
189+
190+
// https://www.libvips.org/API/current/libvips-arithmetic.html#vips-abs
191+
func vipsAbs(img *C.VipsImage) (*C.VipsImage, error) {
192+
incOpCounter("abs")
193+
var out *C.VipsImage
194+
if err := C.absOp(img, &out); err != 0 {
195+
return nil, handleImageError(out)
196+
}
197+
198+
return out, nil
199+
}
200+
201+
// https://www.libvips.org/API/current/libvips-arithmetic.html#vips-project
202+
func vipsProject(in *C.VipsImage) (*C.VipsImage, *C.VipsImage, error) {
203+
incOpCounter("project")
204+
var col, row *C.VipsImage
205+
206+
if err := C.project(in, &col, &row); err != 0 {
207+
return nil, nil, handleVipsError()
208+
}
209+
return col, row, nil
210+
}
211+
212+
// https://www.libvips.org/API/current/libvips-arithmetic.html#vips-min
213+
func vipsMin(in *C.VipsImage) (float64, int, int, error) {
214+
incOpCounter("min")
215+
var out C.double
216+
var x, y C.int
217+
218+
if err := C.minOp(in, &out, &x, &y, C.int(1)); err != 0 {
219+
return 0, 0, 0, handleVipsError()
220+
}
221+
222+
return float64(out), int(x), int(y), nil
223+
}

vips/arithmetic.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,7 @@ int hist_find(VipsImage *in, VipsImage **out);
1818
int hist_cum(VipsImage *in, VipsImage **out);
1919
int hist_norm(VipsImage *in, VipsImage **out);
2020
int hist_entropy(VipsImage *in, double *out);
21+
int subtract(VipsImage *in1, VipsImage *in2, VipsImage **out);
22+
int absOp(VipsImage *img, VipsImage **out);
23+
int project(VipsImage *in, VipsImage **col, VipsImage **row);
24+
int minOp(VipsImage *in, double *out, int *x, int *y, int size);

vips/create.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,9 @@ int identity(VipsImage **out, int ushort) {
2222
return vips_identity(out, NULL);
2323
}
2424
}
25+
26+
// https://libvips.github.io/libvips/API/current/libvips-create.html#vips-text
27+
int text(VipsImage **out, TextOptions *o) {
28+
return vips_text(out, o->Text, "font", o->Font, "width", o->Width, "height", o->Height, "align", o->Align,
29+
"dpi", o->DPI, "rgba", o->RGBA, "justify", o->Justify, "spacing", o->Spacing, "wrap", o->Wrap, NULL);
30+
}

vips/create.go

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,35 @@ package vips
22

33
// #include "create.h"
44
import "C"
5+
import "unsafe"
6+
7+
type TextWrap int
8+
9+
type TextParams struct {
10+
Text string
11+
Font string
12+
Width int
13+
Height int
14+
Alignment Align
15+
DPI int
16+
RGBA bool
17+
Justify bool
18+
Spacing int
19+
Wrap TextWrap
20+
}
21+
22+
type vipsTextOptions struct {
23+
Text *C.char
24+
Font *C.char
25+
Width C.int
26+
Height C.int
27+
DPI C.int
28+
RGBA C.gboolean
29+
Justify C.gboolean
30+
Spacing C.int
31+
Alignment C.VipsAlign
32+
Wrap C.VipsTextWrap
33+
}
534

635
// https://libvips.github.io/libvips/API/current/libvips-create.html#vips-xyz
736
func vipsXYZ(width int, height int) (*C.VipsImage, error) {
@@ -35,3 +64,48 @@ func vipsIdentity(ushort bool) (*C.VipsImage, error) {
3564

3665
return out, nil
3766
}
67+
68+
// TextWrap enum
69+
const (
70+
TextWrapWord TextWrap = C.VIPS_TEXT_WRAP_WORD
71+
TextWrapChar TextWrap = C.VIPS_TEXT_WRAP_CHAR
72+
TextWrapWordChar TextWrap = C.VIPS_TEXT_WRAP_WORD_CHAR
73+
TextWrapNone TextWrap = C.VIPS_TEXT_WRAP_NONE
74+
)
75+
76+
// https://libvips.github.io/libvips/API/current/libvips-create.html#vips-text
77+
func vipsText(params *TextParams) (*C.VipsImage, error) {
78+
var out *C.VipsImage
79+
80+
text := C.CString(params.Text)
81+
defer freeCString(text)
82+
83+
font := C.CString(params.Font)
84+
defer freeCString(font)
85+
86+
opts := vipsTextOptions{
87+
Text: text,
88+
Font: font,
89+
Width: C.int(params.Width),
90+
Height: C.int(params.Height),
91+
DPI: C.int(params.DPI),
92+
Alignment: C.VipsAlign(params.Alignment),
93+
Spacing: C.int(params.Spacing),
94+
Wrap: C.VipsTextWrap(params.Wrap),
95+
}
96+
97+
if params.RGBA {
98+
opts.RGBA = C.TRUE
99+
}
100+
101+
if params.Justify {
102+
opts.Justify = C.TRUE
103+
}
104+
105+
err := C.text(&out, (*C.TextOptions)(unsafe.Pointer(&opts)))
106+
if err != 0 {
107+
return nil, handleImageError(out)
108+
}
109+
110+
return out, nil
111+
}

vips/create.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,20 @@
66
#include <vips/vips.h>
77
#include <vips/foreign.h>
88
// clang-format on
9+
typedef struct {
10+
const char *Text;
11+
const char *Font;
12+
int Width;
13+
int Height;
14+
int DPI;
15+
gboolean RGBA;
16+
gboolean Justify;
17+
int Spacing;
18+
VipsAlign Align;
19+
VipsTextWrap Wrap;
20+
} TextOptions;
921

1022
int xyz(VipsImage **out, int width, int height);
1123
int black(VipsImage **out, int width, int height);
1224
int identity(VipsImage **out, int ushort);
25+
int text(VipsImage **out, TextOptions *o);

vips/header.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@ int get_meta_loader(const VipsImage *in, const char **out) {
7979
return vips_image_get_string(in, VIPS_META_LOADER, out);
8080
}
8181

82+
int get_background(VipsImage *in, double **out, int *n) {
83+
return vips_image_get_array_double(in, "background", out, n);
84+
}
85+
8286
int get_image_delay(VipsImage *in, int **out) {
8387
return vips_image_get_array_int(in, "delay", out, NULL);
8488
}
@@ -119,4 +123,4 @@ unsigned long image_get_blob(VipsImage *in, const char *name, const void **data,
119123
}
120124

121125
return 0;
122-
}
126+
}

vips/header.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,18 @@ func vipsImageSetDelay(in *C.VipsImage, data []C.int) error {
149149
return nil
150150
}
151151

152+
func vipsImageGetBackground(in *C.VipsImage) ([]float64, error) {
153+
incOpCounter("imageGetBackground")
154+
var out *C.double
155+
var n C.int
156+
defer gFreePointer(unsafe.Pointer(out))
157+
158+
if err := C.get_background(in, &out, &n); err != 0 {
159+
return nil, handleVipsError()
160+
}
161+
return fromCArrayDouble(out, int(n)), nil
162+
}
163+
152164
// vipsDetermineImageTypeFromMetaLoader determine the image type from vips-loader metadata
153165
func vipsDetermineImageTypeFromMetaLoader(in *C.VipsImage) ImageType {
154166
vipsLoader, ok := vipsImageGetMetaLoader(in)

vips/header.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ void set_page_height(VipsImage *in, int height);
2828
int get_meta_loader(const VipsImage *in, const char **out);
2929
int get_image_delay(VipsImage *in, int **out);
3030
void set_image_delay(VipsImage *in, const int *array, int n);
31+
int get_background(VipsImage *in, double **out, int *n);
3132

3233
void image_set_blob(VipsImage *in, const char *name, const void *data,
3334
size_t dataLength);
@@ -38,4 +39,4 @@ void image_set_double(VipsImage *in, const char *name, double i);
3839
unsigned long image_get_double(VipsImage *in, const char *name, double *out);
3940

4041
void image_set_int(VipsImage *in, const char *name, int i);
41-
unsigned long image_get_int(VipsImage *in, const char *name, int *out);
42+
unsigned long image_get_int(VipsImage *in, const char *name, int *out);

vips/image.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,12 @@ func Black(width, height int) (*ImageRef, error) {
590590
return imageRef, err
591591
}
592592

593+
// Text draws the string text to an image.
594+
func Text(params *TextParams) (*ImageRef, error) {
595+
img, err := vipsText(params)
596+
return newImageRef(img, ImageTypeUnknown, ImageTypeUnknown, nil), err
597+
}
598+
593599
func newImageRef(vipsImage *C.VipsImage, currentFormat ImageType, originalFormat ImageType, buf []byte) *ImageRef {
594600
imageRef := &ImageRef{
595601
image: vipsImage,
@@ -827,6 +833,15 @@ func (r *ImageRef) SetPageDelay(delay []int) error {
827833
return vipsImageSetDelay(r.image, data)
828834
}
829835

836+
// Background get the background of image.
837+
func (r *ImageRef) Background() ([]float64, error) {
838+
out, err := vipsImageGetBackground(r.image)
839+
if err != nil {
840+
return nil, err
841+
}
842+
return out, nil
843+
}
844+
830845
// Export creates a byte array of the image for use.
831846
// The function returns a byte array that can be written to a file e.g. via os.WriteFile().
832847
// N.B. govips does not currently have built-in support for directly exporting to a file.
@@ -1777,6 +1792,43 @@ func (r *ImageRef) DrawRect(ink ColorRGBA, left int, top int, width int, height
17771792
return nil
17781793
}
17791794

1795+
// Subtract calculate subtract operation between two images.
1796+
func (r *ImageRef) Subtract(in2 *ImageRef) error {
1797+
out, err := vipsSubtract(r.image, in2.image)
1798+
if err != nil {
1799+
return err
1800+
}
1801+
1802+
r.setImage(out)
1803+
return nil
1804+
}
1805+
1806+
// Abs calculate abs operation.
1807+
func (r *ImageRef) Abs() error {
1808+
out, err := vipsAbs(r.image)
1809+
if err != nil {
1810+
return err
1811+
}
1812+
1813+
r.setImage(out)
1814+
return nil
1815+
}
1816+
1817+
// Project calculate project operation.
1818+
func (r *ImageRef) Project() (*ImageRef, *ImageRef, error) {
1819+
col, row, err := vipsProject(r.image)
1820+
if err != nil {
1821+
return nil, nil, err
1822+
}
1823+
1824+
return newImageRef(col, r.format, r.originalFormat, nil), newImageRef(row, r.format, r.originalFormat, nil), nil
1825+
}
1826+
1827+
// Min finds the minimum value in an image.
1828+
func (r *ImageRef) Min() (float64, int, int, error) {
1829+
return vipsMin(r.image)
1830+
}
1831+
17801832
// Rank does rank filtering on an image. A window of size width by height is passed over the image.
17811833
// At each position, the pixels inside the window are sorted into ascending order and the pixel at position
17821834
// index is output. index numbers from 0.

0 commit comments

Comments
 (0)