diff --git a/examples/convert_command/main.go b/examples/convert_command/main.go new file mode 100644 index 0000000..63c714d --- /dev/null +++ b/examples/convert_command/main.go @@ -0,0 +1,21 @@ +package main + +import ( + "fmt" + + "gopkg.in/gographics/imagick.v3/imagick" +) + +func main() { + imagick.Initialize() + defer imagick.Terminate() + + ret, err := imagick.ConvertImageCommand([]string{ + "convert", "logo:", "-resize", "100x100", "/tmp/out.png", + }) + if err != nil { + panic(err) + } + + fmt.Printf("Metadata:\n%s\n", ret.Meta) +} diff --git a/imagick/image.go b/imagick/image.go index be65c7f..0231565 100644 --- a/imagick/image.go +++ b/imagick/image.go @@ -5,10 +5,14 @@ package imagick /* +#include #include */ import "C" -import "runtime" +import ( + "runtime" + "unsafe" +) type Image struct { img *C.Image @@ -33,3 +37,61 @@ func NewMagickImage(info *ImageInfo, width, height uint, return &Image{img: img}, nil } + +// ImageCommandResult is returned by a call to +// ConvertImageCommand. It contains the ImageInfo +// and Metadata string generated by the convert command. +type ImageCommandResult struct { + Info *ImageInfo + Meta string +} + +/* +ConvertImageCommand reads one or more images, applies one or more image +processing operations, and writes out the image in the same or differing +format. +The first item in the args list is expected to be the program name, ie "convert". +*/ +func ConvertImageCommand(args []string) (*ImageCommandResult, error) { + size := len(args) + + cmdArr := make([]*C.char, size) + for i, s := range args { + cmdArr[i] = C.CString(s) + } + + empty := C.CString("") + metaStr := C.AcquireString(empty) + C.free(unsafe.Pointer(empty)) + + defer func() { + for i := range cmdArr { + C.free(unsafe.Pointer(cmdArr[i])) + } + + C.DestroyString(metaStr) + }() + + imageInfo := newImageInfo() + + var exc *C.ExceptionInfo = C.AcquireExceptionInfo() + defer C.DestroyExceptionInfo(exc) + + ok := C.ConvertImageCommand( + imageInfo.info, + C.int(size), // argc + &cmdArr[0], // argv + &metaStr, // metadata + exc, // exception + ) + if C.int(ok) == 0 { + imageInfo.Destroy() + return nil, newExceptionInfo(exc) + } + + ret := &ImageCommandResult{ + Info: imageInfo, + Meta: C.GoString(metaStr), + } + return ret, nil +} diff --git a/imagick/image_test.go b/imagick/image_test.go index c298231..0c3d71a 100644 --- a/imagick/image_test.go +++ b/imagick/image_test.go @@ -5,6 +5,9 @@ package imagick import ( + "fmt" + "io/ioutil" + "os" "testing" ) @@ -28,3 +31,32 @@ func TestNewMagickImage(t *testing.T) { t.Fatal(err.Error()) } } + +func ExampleConvertImageCommand() { + ret, err := ConvertImageCommand([]string{ + "convert", "logo:", "-resize", "100x100", "/tmp/out.png", + }) + if err != nil { + panic(err) + } + fmt.Println("Meta:", ret.Meta) +} + +func TestConvertImageCommand(t *testing.T) { + tmp, err := ioutil.TempFile("", "imagick_test") + if err != nil { + t.Fatal(err) + } + defer os.Remove(tmp.Name()) + + ret, err := ConvertImageCommand([]string{ + "convert", "logo:", "-resize", "100x100", tmp.Name(), + }) + if err != nil { + t.Fatalf("command failed: %v", err) + } + + if ret.Meta == "" { + t.Fatal("got empty metadata string from command result") + } +}