mirror of
https://github.com/talgo-cloud/bimg.git
synced 2026-03-08 23:18:19 -07:00
commit
22d057c12b
7 changed files with 58 additions and 3 deletions
BIN
fixtures/northern_cardinal_bird.jpg
Normal file
BIN
fixtures/northern_cardinal_bird.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 810 KiB |
11
image.go
11
image.go
|
|
@ -41,6 +41,17 @@ func (i *Image) ResizeAndCrop(width, height int) ([]byte, error) {
|
||||||
return i.Process(options)
|
return i.Process(options)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SmartCrop produces a thumbnail aiming at focus on the interesting part.
|
||||||
|
func (i *Image) SmartCrop(width, height int) ([]byte, error) {
|
||||||
|
options := Options{
|
||||||
|
Width: width,
|
||||||
|
Height: height,
|
||||||
|
Crop: true,
|
||||||
|
SmartCrop: true,
|
||||||
|
}
|
||||||
|
return i.Process(options)
|
||||||
|
}
|
||||||
|
|
||||||
// Extract area from the by X/Y axis in the current image.
|
// Extract area from the by X/Y axis in the current image.
|
||||||
func (i *Image) Extract(top, left, width, height int) ([]byte, error) {
|
func (i *Image) Extract(top, left, width, height int) ([]byte, error) {
|
||||||
options := Options{
|
options := Options{
|
||||||
|
|
|
||||||
|
|
@ -455,6 +455,23 @@ func TestFluentInterface(t *testing.T) {
|
||||||
Write("fixtures/test_image_fluent_out.png", image.Image())
|
Write("fixtures/test_image_fluent_out.png", image.Image())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestImageSmartCrop(t *testing.T) {
|
||||||
|
if VipsMajorVersion >= 8 && VipsMinorVersion > 4 {
|
||||||
|
i := initImage("northern_cardinal_bird.jpg")
|
||||||
|
buf, err := i.SmartCrop(300, 300)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Cannot process the image: %#v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = assertSize(buf, 300, 300)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Write("fixtures/test_smart_crop.jpg", buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func initImage(file string) *Image {
|
func initImage(file string) *Image {
|
||||||
buf, _ := imageBuf(file)
|
buf, _ := imageBuf(file)
|
||||||
return NewImage(buf)
|
return NewImage(buf)
|
||||||
|
|
|
||||||
|
|
@ -193,6 +193,7 @@ type Options struct {
|
||||||
Compression int
|
Compression int
|
||||||
Zoom int
|
Zoom int
|
||||||
Crop bool
|
Crop bool
|
||||||
|
SmartCrop bool
|
||||||
Enlarge bool
|
Enlarge bool
|
||||||
Embed bool
|
Embed bool
|
||||||
Flip bool
|
Flip bool
|
||||||
|
|
|
||||||
|
|
@ -249,6 +249,9 @@ func extractOrEmbedImage(image *C.VipsImage, o Options) (*C.VipsImage, error) {
|
||||||
inHeight := int(image.Ysize)
|
inHeight := int(image.Ysize)
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
|
case o.SmartCrop:
|
||||||
|
image, err = vipsSmartCrop(image, o.Width, o.Height)
|
||||||
|
break
|
||||||
case o.Crop:
|
case o.Crop:
|
||||||
width := int(math.Min(float64(inWidth), float64(o.Width)))
|
width := int(math.Min(float64(inWidth), float64(o.Width)))
|
||||||
height := int(math.Min(float64(inHeight), float64(o.Height)))
|
height := int(math.Min(float64(inHeight), float64(o.Height)))
|
||||||
|
|
|
||||||
16
vips.go
16
vips.go
|
|
@ -456,6 +456,22 @@ func vipsExtract(image *C.VipsImage, left, top, width, height int) (*C.VipsImage
|
||||||
return buf, nil
|
return buf, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func vipsSmartCrop(image *C.VipsImage, width, height int) (*C.VipsImage, error) {
|
||||||
|
var buf *C.VipsImage
|
||||||
|
defer C.g_object_unref(C.gpointer(image))
|
||||||
|
|
||||||
|
if width > MaxSize || height > MaxSize {
|
||||||
|
return nil, errors.New("Maximum image size exceeded")
|
||||||
|
}
|
||||||
|
|
||||||
|
err := C.vips_smartcrop_bridge(image, &buf, C.int(width), C.int(height))
|
||||||
|
if err != 0 {
|
||||||
|
return nil, catchVipsError()
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf, nil
|
||||||
|
}
|
||||||
|
|
||||||
func vipsShrinkJpeg(buf []byte, input *C.VipsImage, shrink int) (*C.VipsImage, error) {
|
func vipsShrinkJpeg(buf []byte, input *C.VipsImage, shrink int) (*C.VipsImage, error) {
|
||||||
var image *C.VipsImage
|
var image *C.VipsImage
|
||||||
var ptr = unsafe.Pointer(&buf[0])
|
var ptr = unsafe.Pointer(&buf[0])
|
||||||
|
|
|
||||||
13
vips.h
13
vips.h
|
|
@ -303,9 +303,7 @@ vips_webpsave_bridge(VipsImage *in, void **buf, size_t *len, int strip, int qual
|
||||||
int
|
int
|
||||||
vips_tiffsave_bridge(VipsImage *in, void **buf, size_t *len) {
|
vips_tiffsave_bridge(VipsImage *in, void **buf, size_t *len) {
|
||||||
#if (VIPS_MAJOR_VERSION >= 8 && VIPS_MINOR_VERSION >= 5)
|
#if (VIPS_MAJOR_VERSION >= 8 && VIPS_MINOR_VERSION >= 5)
|
||||||
return vips_tiffsave_buffer(in, buf, len,
|
return vips_tiffsave_buffer(in, buf, len, NULL);
|
||||||
NULL
|
|
||||||
);
|
|
||||||
#else
|
#else
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -572,3 +570,12 @@ vips_watermark_image(VipsImage *in, VipsImage *sub, VipsImage **out, WatermarkIm
|
||||||
g_object_unref(base);
|
g_object_unref(base);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
vips_smartcrop_bridge(VipsImage *in, VipsImage **out, int width, int height) {
|
||||||
|
#if (VIPS_MAJOR_VERSION >= 8 && VIPS_MINOR_VERSION >= 5)
|
||||||
|
return vips_smartcrop(in, out, width, height, NULL);
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue