func main() { // Some GraphicsMagick boilerplate C.InitializeMagick(nil) defer C.DestroyMagick() C.GetExceptionInfo(&exceptionInfo) imageInfo = C.CloneImageInfo(nil) defer C.DestroyExceptionInfo(&exceptionInfo) defer C.DestroyImageInfo(imageInfo) // main OMIT Show("./cgo/armed_gopher.jpg") img, err := Read("./cgo/armed_gopher.jpg") if err != nil { fmt.Println(err) return } if img, err = Resize(img, 200, 800); err != nil { fmt.Println("resize error:", err) return } if err = Save(img, "./cgo/resized_gopher.jpg"); err != nil { fmt.Println("save error:", err) return } Show("./cgo/resized_gopher.jpg") }
// NewInfo returns a newly allocated *Info structure. Do not // create Info objects directly, since they need to allocate // some internal structures while being created. func NewInfo() *Info { cinfo := C.CloneImageInfo(nil) info := new(Info) info.info = cinfo runtime.SetFinalizer(info, func(i *Info) { if i.info != nil { C.DestroyImageInfo(i.info) i.info = nil } }) return info }
func decodeData(data []byte, try int) (*Image, error) { if len(data) == 0 { return nil, ErrNoData } info := C.CloneImageInfo(nil) defer C.DestroyImageInfo(info) var ex C.ExceptionInfo C.GetExceptionInfo(&ex) defer C.DestroyExceptionInfo(&ex) im := C.BlobToImage(info, unsafe.Pointer(&data[0]), C.size_t(len(data)), &ex) if im == nil && try < maxGifTries && ex.severity == C.CorruptImageError && looksLikeGif(data) { return fixAndDecodeGif(data, try) } return checkImage(im, nil, &ex, "decoding") }
// NewFromBlob takes a byte slice of image data and an extension that defines the // image type (e.g. "png", "jpg", etc). It loads the image data and returns a MagickImage. // The extension is required so that Magick knows what processor to use. func NewFromBlob(blob []byte, extension string) (im *MagickImage, err error) { if len(blob) < 1 { return nil, &MagickError{"fatal", "", "zero length blob passed to NewFromBlob"} } if len(extension) < 1 { return nil, &MagickError{"fatal", "", "zero length extension passed to NewFromBlob"} } exception := C.AcquireExceptionInfo() defer C.DestroyExceptionInfo(exception) info := C.AcquireImageInfo() defer C.DestroyImageInfo(info) c_filename := C.CString("image." + extension) defer C.free(unsafe.Pointer(c_filename)) C.SetImageInfoFilename(info, c_filename) var success (C.MagickBooleanType) success = C.SetImageInfo(info, 1, exception) if success != C.MagickTrue { return nil, ErrorFromExceptionInfo(exception) } cloned_info := C.CloneImageInfo(info) success = C.GetBlobSupport(info) if success != C.MagickTrue { // No blob support, lets try reading from a file file, err := ioutil.TempFile("", "image."+extension) if _, err = file.Write(blob); err != nil { return nil, &MagickError{"fatal", "", "image format " + extension + " does not support blobs and could not write temp file"} } file.Close() return NewFromFile(file.Name()) } length := (C.size_t)(len(blob)) if length == 0 { return nil, &MagickError{"fatal", "", "empty blob"} } blob_start := unsafe.Pointer(&blob[0]) image := C.ReadImageFromBlob(info, blob_start, length) if image == nil { return nil, &MagickError{"fatal", "", "corrupt image, not a " + extension} } if failed := C.CheckException(exception); failed == C.MagickTrue { return nil, ErrorFromExceptionInfo(exception) } return &MagickImage{Image: image, ImageInfo: cloned_info}, nil }
func (im *Image) AnnotateImage(x, y int, text string, fontSize int, color string) { image_info := C.CloneImageInfo(nil) defer C.DestroyImageInfo(image_info) draw_info := C.CloneDrawInfo(image_info, nil) defer C.DestroyDrawInfo(draw_info) textBytes := []byte(text) bytesPointer := unsafe.Pointer(&textBytes[0]) textArray := (*C.uchar)(bytesPointer) colorArray := C.CString(color) defer C.free(unsafe.Pointer(colorArray)) draw_context := C.DrawAllocateContext(draw_info, im.image) defer C.DrawDestroyContext(draw_context) C.DrawSetFontSize(draw_context, C.double(fontSize)) C.DrawSetStrokeColorString(draw_context, colorArray) C.DrawSetFillColorString(draw_context, colorArray) C.DrawAnnotation(draw_context, C.double(x), C.double(y), textArray) C.DrawRender(draw_context) }