mirror of
https://github.com/talgo-cloud/bimg.git
synced 2026-03-14 09:55:56 -07:00
feat(#26): support zoom. several refactors and fixes
This commit is contained in:
parent
e603ddd10a
commit
58b2be80a5
7 changed files with 62 additions and 16 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
6
image.go
6
image.go
|
|
@ -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
|
||||||
|
|
|
||||||
20
resize.go
20
resize.go
|
|
@ -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)
|
||||||
|
|
|
||||||
17
vips.go
17
vips.go
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
8
vips.h
8
vips.h
|
|
@ -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…
Add table
Add a link
Reference in a new issue