feat(#26): support zoom. several refactors and fixes

master
Tomas Aparicio 11 years ago
parent e603ddd10a
commit 58b2be80a5

@ -41,10 +41,10 @@ The [install script](https://github.com/lovell/sharp/blob/master/preinstall.sh)
- Resize - Resize
- Enlarge - Enlarge
- Crop - Crop
- Rotate - Rotate (and auto-rotate based on EXIF orientation)
- Auto-rotate (based on EXIF orientation) - Flip (and auto-flip based on EXIF metadata)
- Flip
- Flop - Flop
- Zoom
- Thumbnail - Thumbnail
- Extract area - Extract area
- Format conversion - Format conversion

@ -92,6 +92,12 @@ func (i *Image) Watermark(image []byte, left, top int) ([]byte, error) {
return i.Process(options) return i.Process(options)
} }
// Zoom the image by the given factor
func (i *Image) Zoom(level int) ([]byte, error) {
options := Options{Zoom: level}
return i.Process(options)
}
// Rotate the image by given angle degrees (0, 90, 180 or 270) // Rotate the image by given angle degrees (0, 90, 180 or 270)
func (i *Image) Rotate(a Angle) ([]byte, error) { func (i *Image) Rotate(a Angle) ([]byte, error) {
options := Options{Rotate: a} options := Options{Rotate: a}

@ -119,16 +119,30 @@ func TestImageWatermark(t *testing.T) {
err = assertSize(buf, 800, 600) err = assertSize(buf, 800, 600)
if err != nil { if err != nil {
//t.Error(err) t.Error(err)
} }
if DetermineImageType(buf) != PNG { if DetermineImageType(buf) != JPEG {
//t.Fatal("Image is not jpeg") t.Fatal("Image is not jpeg")
} }
Write("fixtures/test_watermark_out.jpg", buf) Write("fixtures/test_watermark_out.jpg", buf)
} }
func TestImageZoom(t *testing.T) {
buf, err := initImage("test.jpg").Zoom(1)
if err != nil {
t.Errorf("Cannot process the image: %#v", err)
}
err = assertSize(buf, 3360, 2100)
if err != nil {
t.Error(err)
}
Write("fixtures/test_zoom_out.jpg", buf)
}
func TestImageFlip(t *testing.T) { func TestImageFlip(t *testing.T) {
buf, err := initImage("test.jpg").Flip() buf, err := initImage("test.jpg").Flip()
if err != nil { if err != nil {

@ -71,6 +71,7 @@ type Options struct {
Extend int Extend int
Quality int Quality int
Compression int Compression int
Zoom int
Crop bool Crop bool
Enlarge bool Enlarge bool
Embed bool Embed bool

@ -106,6 +106,12 @@ func Resize(buf []byte, o Options) ([]byte, error) {
} }
} }
// Zoom image if necessary
image, err = zoomImage(image, o.Zoom)
if err != nil {
return nil, err
}
// Rotate / flip image if necessary // Rotate / flip image if necessary
image, err = rotateImage(image, o) image, err = rotateImage(image, o)
if err != nil { if err != nil {
@ -205,23 +211,31 @@ func insertImage(image *C.struct__VipsImage, t ImageType, o Insert, save vipsSav
if imageType != t { if imageType != t {
save.Type = t save.Type = t
debug("Image type insert: %s", save.Type)
buf, err := vipsSave(insert, save) buf, err := vipsSave(insert, save)
if err != nil { if err != nil {
return nil, err return nil, err
} }
insert, imageType, err = vipsRead(buf) insert, imageType, err = vipsRead(buf)
debug("New type image: %s", imageType)
if err != nil { if err != nil {
return nil, err return nil, err
} }
} }
debug("Insert images: %#v", insert) debug("Insert image: %#v", insert)
return vipsInsert(image, insert, o.Left, o.Top) return vipsInsert(image, insert, o.Left, o.Top)
} }
func zoomImage(image *C.struct__VipsImage, zoom int) (*C.struct__VipsImage, error) {
if zoom == 0 {
return image, nil
}
zoom += 1
return vipsZoom(image, zoom)
}
func shrinkImage(image *C.struct__VipsImage, o Options, residual float64, shrink int) (*C.struct__VipsImage, float64, error) { func shrinkImage(image *C.struct__VipsImage, o Options, residual float64, shrink int) (*C.struct__VipsImage, float64, error) {
// Use vips_shrink with the integral reduction // Use vips_shrink with the integral reduction
image, err := vipsShrink(image, shrink) image, err := vipsShrink(image, shrink)

@ -76,7 +76,7 @@ func VipsDebug() {
C.im__print_all() C.im__print_all()
} }
// Get the allocated memory by vips in bytes // Get memory info stats from vips
func VipsMemory() VipsMemoryInfo { func VipsMemory() VipsMemoryInfo {
return VipsMemoryInfo{ return VipsMemoryInfo{
Memory: int64(C.vips_tracked_get_mem()), Memory: int64(C.vips_tracked_get_mem()),
@ -109,14 +109,25 @@ func vipsFlip(image *C.struct__VipsImage, direction Direction) (*C.struct__VipsI
return out, nil return out, nil
} }
func vipsZoom(image *C.struct__VipsImage, zoom int) (*C.struct__VipsImage, error) {
var out *C.struct__VipsImage
defer C.g_object_unref(C.gpointer(image))
err := C.vips_zoom_bridge(image, &out, C.int(zoom), C.int(zoom))
if err != 0 {
return nil, catchVipsError()
}
return out, nil
}
func vipsInsert(image *C.struct__VipsImage, sub *C.struct__VipsImage, left, top int) (*C.struct__VipsImage, error) { func vipsInsert(image *C.struct__VipsImage, sub *C.struct__VipsImage, left, top int) (*C.struct__VipsImage, error) {
var out *C.struct__VipsImage var out *C.struct__VipsImage
var cache *C.struct__VipsImage
defer C.g_object_unref(C.gpointer(image)) defer C.g_object_unref(C.gpointer(image))
defer C.g_object_unref(C.gpointer(sub)) defer C.g_object_unref(C.gpointer(sub))
err = C.vips_insert_bridge(image, sub, &out, C.int(left), C.int(top)) err := C.vips_insert_bridge(image, sub, &out, C.int(left), C.int(top))
if err != 0 { if err != 0 {
return nil, catchVipsError() return nil, catchVipsError()
} }

@ -92,15 +92,15 @@ vips_enum_nick_bridge(VipsImage *image) {
}; };
int int
vips_insert_bridge(VipsImage *in, VipsImage *sub, VipsImage **out, int left, int top) vips_zoom_bridge(VipsImage *in, VipsImage **out, int xfac, int yfac)
{ {
return vips_insert(in, sub, out, left, top, NULL); return vips_zoom(in, out, xfac, yfac, NULL);
}; };
int int
vips_bandjoin2_bridge(VipsImage *in, VipsImage *sub, VipsImage **out) vips_insert_bridge(VipsImage *in, VipsImage *sub, VipsImage **out, int left, int top)
{ {
return vips_bandjoin2(in, sub, out, NULL); return vips_insert(in, sub, out, left, top, NULL);
}; };
int int

Loading…
Cancel
Save