mirror of
https://github.com/talgo-cloud/bimg.git
synced 2026-03-14 09:55:56 -07:00
refactor(#47): minor refactors, code normalization and test coverage
This commit is contained in:
parent
6edd96ee41
commit
ed4faadba6
10 changed files with 309 additions and 92 deletions
111
README.md
111
README.md
|
|
@ -238,7 +238,7 @@ bimg.Write("new.jpg", newImage)
|
||||||
|
|
||||||
Run the process passing the `DEBUG` environment variable
|
Run the process passing the `DEBUG` environment variable
|
||||||
```
|
```
|
||||||
DEBUG=* ./app
|
DEBUG=bimg ./app
|
||||||
```
|
```
|
||||||
|
|
||||||
Enable libvips traces (note that a lot of data will be written in stdout):
|
Enable libvips traces (note that a lot of data will be written in stdout):
|
||||||
|
|
@ -248,6 +248,12 @@ VIPS_TRACE=1 ./app
|
||||||
|
|
||||||
### Programmatic API
|
### Programmatic API
|
||||||
|
|
||||||
|
#### func ColourspaceIsSupported
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ColourspaceIsSupported(buf []byte) (bool, error)
|
||||||
|
```
|
||||||
|
Check in the image colourspace is supported by libvips
|
||||||
|
|
||||||
#### func DetermineImageTypeName
|
#### func DetermineImageTypeName
|
||||||
|
|
||||||
|
|
@ -295,7 +301,7 @@ func Resize(buf []byte, o Options) ([]byte, error)
|
||||||
```go
|
```go
|
||||||
func Shutdown()
|
func Shutdown()
|
||||||
```
|
```
|
||||||
Thread-safe function to shutdown libvips. You could call this to drop caches as
|
Thread-safe function to shutdown libvips. You can call this to drop caches as
|
||||||
well. If libvips was already initialized, the function is no-op
|
well. If libvips was already initialized, the function is no-op
|
||||||
|
|
||||||
#### func VipsDebugInfo
|
#### func VipsDebugInfo
|
||||||
|
|
@ -383,6 +389,20 @@ func NewImage(buf []byte) *Image
|
||||||
```
|
```
|
||||||
Creates a new image
|
Creates a new image
|
||||||
|
|
||||||
|
#### func (*Image) Colourspace
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (i *Image) Colourspace(c Interpretation) ([]byte, error)
|
||||||
|
```
|
||||||
|
Colour space conversion
|
||||||
|
|
||||||
|
#### func (*Image) ColourspaceIsSupported
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (i *Image) ColourspaceIsSupported() (bool, error)
|
||||||
|
```
|
||||||
|
Check if the current image has a valid colourspace
|
||||||
|
|
||||||
#### func (*Image) Convert
|
#### func (*Image) Convert
|
||||||
|
|
||||||
```go
|
```go
|
||||||
|
|
@ -453,6 +473,14 @@ func (i *Image) Image() []byte
|
||||||
```
|
```
|
||||||
Get image buffer
|
Get image buffer
|
||||||
|
|
||||||
|
#### func (*Image) Interpretation
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (i *Image) Interpretation() (Interpretation, error)
|
||||||
|
```
|
||||||
|
Get the image interpretation type See:
|
||||||
|
http://www.vips.ecs.soton.ac.uk/supported/current/doc/html/libvips/VipsImage.html#VipsInterpretation
|
||||||
|
|
||||||
#### func (*Image) Metadata
|
#### func (*Image) Metadata
|
||||||
|
|
||||||
```go
|
```go
|
||||||
|
|
@ -533,6 +561,7 @@ type ImageMetadata struct {
|
||||||
Profile bool
|
Profile bool
|
||||||
Type string
|
Type string
|
||||||
Space string
|
Space string
|
||||||
|
Colourspace string
|
||||||
Size ImageSize
|
Size ImageSize
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
@ -609,33 +638,65 @@ const (
|
||||||
func (i Interpolator) String() string
|
func (i Interpolator) String() string
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### type Interpretation
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Interpretation int
|
||||||
|
```
|
||||||
|
|
||||||
|
Image interpretation type See:
|
||||||
|
http://www.vips.ecs.soton.ac.uk/supported/current/doc/html/libvips/VipsImage.html#VipsInterpretation
|
||||||
|
|
||||||
|
```go
|
||||||
|
const (
|
||||||
|
INTERPRETATION_ERROR Interpretation = C.VIPS_INTERPRETATION_ERROR
|
||||||
|
INTERPRETATION_MULTIBAND Interpretation = C.VIPS_INTERPRETATION_MULTIBAND
|
||||||
|
INTERPRETATION_B_W Interpretation = C.VIPS_INTERPRETATION_B_W
|
||||||
|
INTERPRETATION_CMYK Interpretation = C.VIPS_INTERPRETATION_CMYK
|
||||||
|
INTERPRETATION_RGB Interpretation = C.VIPS_INTERPRETATION_RGB
|
||||||
|
INTERPRETATION_sRGB Interpretation = C.VIPS_INTERPRETATION_sRGB
|
||||||
|
INTERPRETATION_RGB16 Interpretation = C.VIPS_INTERPRETATION_RGB16
|
||||||
|
INTERPRETATION_GREY16 Interpretation = C.VIPS_INTERPRETATION_GREY16
|
||||||
|
INTERPRETATION_scRGB Interpretation = C.VIPS_INTERPRETATION_scRGB
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### func ImageInterpretation
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ImageInterpretation(buf []byte) (Interpretation, error)
|
||||||
|
```
|
||||||
|
Get the image interpretation type See:
|
||||||
|
http://www.vips.ecs.soton.ac.uk/supported/current/doc/html/libvips/VipsImage.html#VipsInterpretation
|
||||||
|
|
||||||
#### type Options
|
#### type Options
|
||||||
|
|
||||||
```go
|
```go
|
||||||
type Options struct {
|
type Options struct {
|
||||||
Height int
|
Height int
|
||||||
Width int
|
Width int
|
||||||
AreaHeight int
|
AreaHeight int
|
||||||
AreaWidth int
|
AreaWidth int
|
||||||
Top int
|
Top int
|
||||||
Left int
|
Left int
|
||||||
Extend int
|
Extend int
|
||||||
Quality int
|
Quality int
|
||||||
Compression int
|
Compression int
|
||||||
Zoom int
|
Zoom int
|
||||||
Crop bool
|
Crop bool
|
||||||
Enlarge bool
|
Enlarge bool
|
||||||
Embed bool
|
Embed bool
|
||||||
Flip bool
|
Flip bool
|
||||||
Flop bool
|
Flop bool
|
||||||
NoAutoRotate bool
|
NoAutoRotate bool
|
||||||
NoProfile bool
|
NoProfile bool
|
||||||
Interlace bool
|
Interlace bool
|
||||||
Rotate Angle
|
Rotate Angle
|
||||||
Gravity Gravity
|
Gravity Gravity
|
||||||
Watermark Watermark
|
Watermark Watermark
|
||||||
Type ImageType
|
Type ImageType
|
||||||
Interpolator Interpolator
|
Interpolator Interpolator
|
||||||
|
Interpretation Interpretation
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 58 KiB |
11
image.go
11
image.go
|
|
@ -155,6 +155,17 @@ func (i *Image) Metadata() (ImageMetadata, error) {
|
||||||
return Metadata(i.buffer)
|
return Metadata(i.buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the image interpretation type
|
||||||
|
// See: http://www.vips.ecs.soton.ac.uk/supported/current/doc/html/libvips/VipsImage.html#VipsInterpretation
|
||||||
|
func (i *Image) Interpretation() (Interpretation, error) {
|
||||||
|
return ImageInterpretation(i.buffer)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the current image has a valid colourspace
|
||||||
|
func (i *Image) ColourspaceIsSupported() (bool, error) {
|
||||||
|
return ColourspaceIsSupported(i.buffer)
|
||||||
|
}
|
||||||
|
|
||||||
// Get image type format (jpeg, png, webp, tiff)
|
// Get image type format (jpeg, png, webp, tiff)
|
||||||
func (i *Image) Type() string {
|
func (i *Image) Type() string {
|
||||||
return DetermineImageTypeName(i.buffer)
|
return DetermineImageTypeName(i.buffer)
|
||||||
|
|
|
||||||
|
|
@ -262,12 +262,36 @@ func TestImageMetadata(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestImageColourspaceBW(t *testing.T) {
|
func TestInterpretation(t *testing.T) {
|
||||||
buf, err := initImage("test.jpg").Colourspace(B_W)
|
interpretation, err := initImage("test.jpg").Interpretation()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Cannot process the image: %#v", err)
|
t.Errorf("Cannot process the image: %#v", err)
|
||||||
}
|
}
|
||||||
Write("fixtures/test_image_colourspace_b_w.jpg", buf)
|
if interpretation != INTERPRETATION_sRGB {
|
||||||
|
t.Errorf("Invalid interpretation: %d", interpretation)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestImageColourspaceBW(t *testing.T) {
|
||||||
|
buf, err := initImage("test.jpg").Colourspace(INTERPRETATION_B_W)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Cannot process the image: %#v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
interpretation, err := ImageInterpretation(buf)
|
||||||
|
if interpretation != INTERPRETATION_B_W {
|
||||||
|
t.Errorf("Invalid colourspace")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestImageColourspaceIsSupported(t *testing.T) {
|
||||||
|
supported, err := initImage("test.jpg").ColourspaceIsSupported()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Cannot process the image: %#v", err)
|
||||||
|
}
|
||||||
|
if supported != true {
|
||||||
|
t.Errorf("Non-supported colourspace")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFluentInterface(t *testing.T) {
|
func TestFluentInterface(t *testing.T) {
|
||||||
|
|
|
||||||
12
metadata.go
12
metadata.go
|
|
@ -18,6 +18,7 @@ type ImageMetadata struct {
|
||||||
Profile bool
|
Profile bool
|
||||||
Type string
|
Type string
|
||||||
Space string
|
Space string
|
||||||
|
Colourspace string
|
||||||
Size ImageSize
|
Size ImageSize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -34,6 +35,17 @@ func Size(buf []byte) (ImageSize, error) {
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check in the image colourspace is supported by libvips
|
||||||
|
func ColourspaceIsSupported(buf []byte) (bool, error) {
|
||||||
|
return vipsColourspaceIsSupportedBuffer(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the image interpretation type
|
||||||
|
// See: http://www.vips.ecs.soton.ac.uk/supported/current/doc/html/libvips/VipsImage.html#VipsInterpretation
|
||||||
|
func ImageInterpretation(buf []byte) (Interpretation, error) {
|
||||||
|
return vipsInterpretationBuffer(buf)
|
||||||
|
}
|
||||||
|
|
||||||
// Extract the image metadata (size, type, alpha channel, profile, EXIF orientation...)
|
// Extract the image metadata (size, type, alpha channel, profile, EXIF orientation...)
|
||||||
func Metadata(buf []byte) (ImageMetadata, error) {
|
func Metadata(buf []byte) (ImageMetadata, error) {
|
||||||
defer C.vips_thread_shutdown()
|
defer C.vips_thread_shutdown()
|
||||||
|
|
|
||||||
|
|
@ -38,9 +38,9 @@ func TestMetadata(t *testing.T) {
|
||||||
profile bool
|
profile bool
|
||||||
space string
|
space string
|
||||||
}{
|
}{
|
||||||
{"test.jpg", "jpeg", 0, false, false, "bicubic"},
|
{"test.jpg", "jpeg", 0, false, false, "srgb"},
|
||||||
{"test.png", "png", 0, true, false, "bicubic"},
|
{"test.png", "png", 0, true, false, "srgb"},
|
||||||
{"test.webp", "webp", 0, false, false, "bicubic"},
|
{"test.webp", "webp", 0, false, false, "srgb"},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, file := range files {
|
for _, file := range files {
|
||||||
|
|
@ -61,6 +61,58 @@ func TestMetadata(t *testing.T) {
|
||||||
if metadata.Profile != file.profile {
|
if metadata.Profile != file.profile {
|
||||||
t.Fatalf("Unexpected image profile: %s != %s", metadata.Profile, file.profile)
|
t.Fatalf("Unexpected image profile: %s != %s", metadata.Profile, file.profile)
|
||||||
}
|
}
|
||||||
|
if metadata.Space != file.space {
|
||||||
|
t.Fatalf("Unexpected image profile: %s != %s", metadata.Profile, file.profile)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestImageInterpretation(t *testing.T) {
|
||||||
|
files := []struct {
|
||||||
|
name string
|
||||||
|
interpretation Interpretation
|
||||||
|
}{
|
||||||
|
{"test.jpg", INTERPRETATION_sRGB},
|
||||||
|
{"test.png", INTERPRETATION_sRGB},
|
||||||
|
{"test.webp", INTERPRETATION_sRGB},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, file := range files {
|
||||||
|
interpretation, err := ImageInterpretation(readFile(file.name))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Cannot read the image: %s -> %s", file.name, err)
|
||||||
|
}
|
||||||
|
if interpretation != file.interpretation {
|
||||||
|
t.Fatalf("Unexpected image interpretation")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestColourspaceIsSupported(t *testing.T) {
|
||||||
|
files := []struct {
|
||||||
|
name string
|
||||||
|
}{
|
||||||
|
{"test.jpg"},
|
||||||
|
{"test.png"},
|
||||||
|
{"test.webp"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, file := range files {
|
||||||
|
supported, err := ColourspaceIsSupported(readFile(file.name))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Cannot read the image: %s -> %s", file.name, err)
|
||||||
|
}
|
||||||
|
if supported != true {
|
||||||
|
t.Fatalf("Unsupported image colourspace")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
supported, err := initImage("test.jpg").ColourspaceIsSupported()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Cannot process the image: %#v", err)
|
||||||
|
}
|
||||||
|
if supported != true {
|
||||||
|
t.Errorf("Non-supported colourspace")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
66
options.go
66
options.go
|
|
@ -55,18 +55,20 @@ const (
|
||||||
VERTICAL Direction = C.VIPS_DIRECTION_VERTICAL
|
VERTICAL Direction = C.VIPS_DIRECTION_VERTICAL
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Image interpretation type
|
||||||
|
// See: http://www.vips.ecs.soton.ac.uk/supported/current/doc/html/libvips/VipsImage.html#VipsInterpretation
|
||||||
type Interpretation int
|
type Interpretation int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ERROR Interpretation = C.VIPS_INTERPRETATION_ERROR
|
INTERPRETATION_ERROR Interpretation = C.VIPS_INTERPRETATION_ERROR
|
||||||
MULTIBAND Interpretation = C.VIPS_INTERPRETATION_MULTIBAND
|
INTERPRETATION_MULTIBAND Interpretation = C.VIPS_INTERPRETATION_MULTIBAND
|
||||||
B_W Interpretation = C.VIPS_INTERPRETATION_B_W
|
INTERPRETATION_B_W Interpretation = C.VIPS_INTERPRETATION_B_W
|
||||||
CMYK Interpretation = C.VIPS_INTERPRETATION_CMYK
|
INTERPRETATION_CMYK Interpretation = C.VIPS_INTERPRETATION_CMYK
|
||||||
RGB Interpretation = C.VIPS_INTERPRETATION_RGB
|
INTERPRETATION_RGB Interpretation = C.VIPS_INTERPRETATION_RGB
|
||||||
sRGB Interpretation = C.VIPS_INTERPRETATION_sRGB
|
INTERPRETATION_sRGB Interpretation = C.VIPS_INTERPRETATION_sRGB
|
||||||
RGB16 Interpretation = C.VIPS_INTERPRETATION_RGB16
|
INTERPRETATION_RGB16 Interpretation = C.VIPS_INTERPRETATION_RGB16
|
||||||
GREY16 Interpretation = C.VIPS_INTERPRETATION_GREY16
|
INTERPRETATION_GREY16 Interpretation = C.VIPS_INTERPRETATION_GREY16
|
||||||
scRGB Interpretation = C.VIPS_INTERPRETATION_scRGB
|
INTERPRETATION_scRGB Interpretation = C.VIPS_INTERPRETATION_scRGB
|
||||||
)
|
)
|
||||||
|
|
||||||
const WATERMARK_FONT = "sans 10"
|
const WATERMARK_FONT = "sans 10"
|
||||||
|
|
@ -88,28 +90,28 @@ type Watermark struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Options struct {
|
type Options struct {
|
||||||
Height int
|
Height int
|
||||||
Width int
|
Width int
|
||||||
AreaHeight int
|
AreaHeight int
|
||||||
AreaWidth int
|
AreaWidth int
|
||||||
Top int
|
Top int
|
||||||
Left int
|
Left int
|
||||||
Extend int
|
Extend int
|
||||||
Quality int
|
Quality int
|
||||||
Compression int
|
Compression int
|
||||||
Zoom int
|
Zoom int
|
||||||
Crop bool
|
Crop bool
|
||||||
Enlarge bool
|
Enlarge bool
|
||||||
Embed bool
|
Embed bool
|
||||||
Flip bool
|
Flip bool
|
||||||
Flop bool
|
Flop bool
|
||||||
NoAutoRotate bool
|
NoAutoRotate bool
|
||||||
NoProfile bool
|
NoProfile bool
|
||||||
Interlace bool
|
Interlace bool
|
||||||
Rotate Angle
|
Rotate Angle
|
||||||
Gravity Gravity
|
Gravity Gravity
|
||||||
Watermark Watermark
|
Watermark Watermark
|
||||||
Type ImageType
|
Type ImageType
|
||||||
Interpolator Interpolator
|
Interpolator Interpolator
|
||||||
Interpretation Interpretation
|
Interpretation Interpretation
|
||||||
}
|
}
|
||||||
|
|
|
||||||
14
resize.go
14
resize.go
|
|
@ -117,15 +117,15 @@ func Resize(buf []byte, o Options) ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
saveOptions := vipsSaveOptions{
|
saveOptions := vipsSaveOptions{
|
||||||
Quality: o.Quality,
|
Quality: o.Quality,
|
||||||
Type: o.Type,
|
Type: o.Type,
|
||||||
Compression: o.Compression,
|
Compression: o.Compression,
|
||||||
Interlace: o.Interlace,
|
Interlace: o.Interlace,
|
||||||
NoProfile: o.NoProfile,
|
NoProfile: o.NoProfile,
|
||||||
Interpretation: o.Interpretation,
|
Interpretation: o.Interpretation,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally save as buffer
|
// Finally get the resultant buffer
|
||||||
buf, err = vipsSave(image, saveOptions)
|
buf, err = vipsSave(image, saveOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -145,7 +145,7 @@ func applyDefaults(o *Options, imageType ImageType) {
|
||||||
o.Type = imageType
|
o.Type = imageType
|
||||||
}
|
}
|
||||||
if o.Interpretation == 0 {
|
if o.Interpretation == 0 {
|
||||||
o.Interpretation = sRGB
|
o.Interpretation = INTERPRETATION_sRGB
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
88
vips.go
88
vips.go
|
|
@ -32,11 +32,11 @@ type VipsMemoryInfo struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type vipsSaveOptions struct {
|
type vipsSaveOptions struct {
|
||||||
Quality int
|
Quality int
|
||||||
Compression int
|
Compression int
|
||||||
Type ImageType
|
Type ImageType
|
||||||
Interlace bool
|
Interlace bool
|
||||||
NoProfile bool
|
NoProfile bool
|
||||||
Interpretation Interpretation
|
Interpretation Interpretation
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -224,41 +224,85 @@ func vipsRead(buf []byte) (*C.struct__VipsImage, ImageType, error) {
|
||||||
return image, imageType, nil
|
return image, imageType, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func vipsSave(image *C.struct__VipsImage, o vipsSaveOptions) ([]byte, error) {
|
func vipsColourspaceIsSupportedBuffer(buf []byte) (bool, error) {
|
||||||
length := C.size_t(0)
|
image, _, err := vipsRead(buf)
|
||||||
err := C.int(0)
|
defer C.g_object_unref(C.gpointer(image))
|
||||||
interlace := C.int(boolToInt(o.Interlace))
|
if err != nil {
|
||||||
if o.Interpretation == 0 {
|
return false, err
|
||||||
o.Interpretation = sRGB
|
|
||||||
}
|
}
|
||||||
interpretation := C.VipsInterpretation(o.Interpretation)
|
return vipsColourspaceIsSupported(image), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func vipsColourspaceIsSupported(image *C.struct__VipsImage) bool {
|
||||||
|
return int(C.vips_colourspace_issupported_bridge(image)) == 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func vipsInterpretationBuffer(buf []byte) (Interpretation, error) {
|
||||||
|
image, _, err := vipsRead(buf)
|
||||||
|
defer C.g_object_unref(C.gpointer(image))
|
||||||
|
if err != nil {
|
||||||
|
return Interpretation(-1), err
|
||||||
|
}
|
||||||
|
return vipsInterpretation(image), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func vipsInterpretation(image *C.struct__VipsImage) Interpretation {
|
||||||
|
return Interpretation(C.vips_image_guess_interpretation_bridge(image))
|
||||||
|
}
|
||||||
|
|
||||||
|
func vipsPreSave(image *C.struct__VipsImage, o *vipsSaveOptions) (*C.struct__VipsImage, error) {
|
||||||
// Remove ICC profile metadata
|
// Remove ICC profile metadata
|
||||||
if o.NoProfile {
|
if o.NoProfile {
|
||||||
C.remove_profile(image)
|
C.remove_profile(image)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Force RGB color space
|
// Use a default interpretation and cast it to C type
|
||||||
var outImage *C.struct__VipsImage
|
if o.Interpretation == 0 {
|
||||||
C.vips_colourspace_bridge(image, &outImage, interpretation)
|
o.Interpretation = INTERPRETATION_sRGB
|
||||||
|
}
|
||||||
|
interpretation := C.VipsInterpretation(o.Interpretation)
|
||||||
|
|
||||||
|
// Apply the proper colour space
|
||||||
|
var outImage *C.struct__VipsImage
|
||||||
|
if vipsColourspaceIsSupported(image) {
|
||||||
|
err := int(C.vips_colourspace_bridge(image, &outImage, interpretation))
|
||||||
|
C.g_object_unref(C.gpointer(image))
|
||||||
|
if err != 0 {
|
||||||
|
return nil, catchVipsError()
|
||||||
|
}
|
||||||
|
image = outImage
|
||||||
|
}
|
||||||
|
|
||||||
|
return image, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func vipsSave(image *C.struct__VipsImage, o vipsSaveOptions) ([]byte, error) {
|
||||||
defer C.g_object_unref(C.gpointer(image))
|
defer C.g_object_unref(C.gpointer(image))
|
||||||
defer C.g_object_unref(C.gpointer(outImage))
|
|
||||||
|
image, err := vipsPreSave(image, &o)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
length := C.size_t(0)
|
||||||
|
saveErr := C.int(0)
|
||||||
|
interlace := C.int(boolToInt(o.Interlace))
|
||||||
|
quality := C.int(o.Quality)
|
||||||
|
|
||||||
var ptr unsafe.Pointer
|
var ptr unsafe.Pointer
|
||||||
switch o.Type {
|
switch o.Type {
|
||||||
case PNG:
|
|
||||||
err = C.vips_pngsave_bridge(outImage, &ptr, &length, 1, C.int(o.Compression), C.int(o.Quality), interlace)
|
|
||||||
break
|
|
||||||
case WEBP:
|
case WEBP:
|
||||||
err = C.vips_webpsave_bridge(outImage, &ptr, &length, 1, C.int(o.Quality))
|
saveErr = C.vips_webpsave_bridge(image, &ptr, &length, 1, quality)
|
||||||
|
break
|
||||||
|
case PNG:
|
||||||
|
saveErr = C.vips_pngsave_bridge(image, &ptr, &length, 1, C.int(o.Compression), quality, interlace)
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
err = C.vips_jpegsave_bridge(outImage, &ptr, &length, 1, C.int(o.Quality), interlace)
|
saveErr = C.vips_jpegsave_bridge(image, &ptr, &length, 1, quality, interlace)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
if int(err) != 0 {
|
if int(saveErr) != 0 {
|
||||||
return nil, catchVipsError()
|
return nil, catchVipsError()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
11
vips.h
11
vips.h
|
|
@ -134,6 +134,17 @@ vips_extract_area_bridge(VipsImage *in, VipsImage **out, int left, int top, int
|
||||||
return vips_extract_area(in, out, left, top, width, height, NULL);
|
return vips_extract_area(in, out, left, top, width, height, NULL);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
vips_colourspace_issupported_bridge(VipsImage *in)
|
||||||
|
{
|
||||||
|
return vips_colourspace_issupported(in) ? 1 : 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
VipsInterpretation
|
||||||
|
vips_image_guess_interpretation_bridge(VipsImage *in) {
|
||||||
|
return vips_image_guess_interpretation(in);
|
||||||
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
vips_colourspace_bridge(VipsImage *in, VipsImage **out, VipsInterpretation space)
|
vips_colourspace_bridge(VipsImage *in, VipsImage **out, VipsInterpretation space)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue