// Negate inverts the colors in the image func (im *MagickImage) Negate() (err error) { exception := C.AcquireExceptionInfo() defer C.DestroyExceptionInfo(exception) new_image := C.Negate(im.Image, exception) if failed := C.CheckException(exception); failed == C.MagickTrue { return ErrorFromExceptionInfo(exception) } im.ReplaceImage(new_image) return nil }
// IntegralRotateImage rotates the image an integral of 90 degrees func (im *MagickImage) IntegralRotateImage(rotations int) (err error) { exception := C.AcquireExceptionInfo() defer C.DestroyExceptionInfo(exception) new_image := C.IntegralRotateImage(im.Image, C.size_t(rotations), exception) if failed := C.CheckException(exception); failed == C.MagickTrue { return ErrorFromExceptionInfo(exception) } im.ReplaceImage(new_image) return nil }
// ParseGeometryToRectangleInfo converts from a geometry string (WxH+X+Y) into a Magick // RectangleInfo that contains the individual properties func (im *MagickImage) ParseGeometryToRectangleInfo(geometry string) (info C.RectangleInfo, err error) { c_geometry := C.CString(geometry) defer C.free(unsafe.Pointer(c_geometry)) exception := C.AcquireExceptionInfo() defer C.DestroyExceptionInfo(exception) C.ParseRegionGeometry(im.Image, c_geometry, &info, exception) if failed := C.CheckException(exception); failed == C.MagickTrue { err = ErrorFromExceptionInfo(exception) } return }
// FillBackgroundColor fills transparent areas of an image with a solid color and stores the filled image in place. // color can be any color format that image magick understands, see: http://www.imagemagick.org/ImageMagick-7.0.0/script/color.php#models func (im *MagickImage) FillBackgroundColor(color string) (err error) { exception := C.AcquireExceptionInfo() defer C.DestroyExceptionInfo(exception) c_color := C.CString(color) defer C.free(unsafe.Pointer(c_color)) new_image := C.FillBackgroundColor(im.Image, c_color, exception) if failed := C.CheckException(exception); failed == C.MagickTrue { return ErrorFromExceptionInfo(exception) } im.ReplaceImage(new_image) return nil }
// Crop crops the image based on the geometry string passed and stores the cropped image in place // For more info about Geometry see http://www.imagemagick.org/script/command-line-processing.php#geometry func (im *MagickImage) Crop(geometry string) (err error) { exception := C.AcquireExceptionInfo() defer C.DestroyExceptionInfo(exception) rect, err := im.ParseGeometryToRectangleInfo(geometry) if err != nil { return err } new_image := C.CropImage(im.Image, &rect, exception) if failed := C.CheckException(exception); failed == C.MagickTrue { return ErrorFromExceptionInfo(exception) } im.ReplaceImage(new_image) return nil }
// NewFromFile loads a file at filename into a MagickImage. // Exceptions are returned as MagickErrors. func NewFromFile(filename string) (im *MagickImage, err error) { exception := C.AcquireExceptionInfo() defer C.DestroyExceptionInfo(exception) info := C.AcquireImageInfo() c_filename := C.CString(filename) defer C.free(unsafe.Pointer(c_filename)) C.SetImageInfoFilename(info, c_filename) image := C.ReadImage(info, exception) if failed := C.CheckException(exception); failed == C.MagickTrue { C.DestroyImageInfo(info) return nil, ErrorFromExceptionInfo(exception) } return &MagickImage{Image: image, ImageInfo: info}, nil }
// ToFile writes the (transformed) MagickImage to the regular file at filename. Magick determines // the encoding of the output file by the extension given to the filename (e.g. "image.jpg", "image.png") func (im *MagickImage) ToFile(filename string) (err error) { exception := C.AcquireExceptionInfo() defer C.DestroyExceptionInfo(exception) c_outpath := C.CString(filename) defer C.free(unsafe.Pointer(c_outpath)) C.SetImageInfoFilename(im.ImageInfo, c_outpath) success := C.WriteImages(im.ImageInfo, im.Image, c_outpath, exception) if failed := C.CheckException(exception); failed == C.MagickTrue { return ErrorFromExceptionInfo(exception) } if success != C.MagickTrue { return &MagickError{"fatal", "", "could not write to " + filename + " for unknown reason"} } return nil }
// ToBlob takes a (transformed) MagickImage and returns a byte slice in the format you specify with extension. // Magick uses the extension to transform the image in to the proper encoding (e.g. "jpg", "png") func (im *MagickImage) ToBlob(extension string) (blob []byte, err error) { exception := C.AcquireExceptionInfo() defer C.DestroyExceptionInfo(exception) c_outpath := C.CString("image." + extension) defer C.free(unsafe.Pointer(c_outpath)) C.SetImageInfoFilename(im.ImageInfo, c_outpath) var outlength (C.size_t) outblob := C.ImageToBlob(im.ImageInfo, im.Image, &outlength, exception) if failed := C.CheckException(exception); failed == C.MagickTrue { return nil, ErrorFromExceptionInfo(exception) } char_pointer := unsafe.Pointer(outblob) defer C.free(char_pointer) return C.GoBytes(char_pointer, (C.int)(outlength)), nil }
// Shadow adds a dropshadow to the current (transparent) image and stores the shadowed image in place // For more information about shadow options see: http://www.imagemagick.org/Usage/blur/#shadow func (im *MagickImage) Shadow(color string, opacity, sigma float32, xoffset, yoffset int) (err error) { exception := C.AcquireExceptionInfo() defer C.DestroyExceptionInfo(exception) c_opacity := (C.double)(opacity) c_sigma := (C.double)(sigma) c_x := (C.ssize_t)(xoffset) c_y := (C.ssize_t)(yoffset) c_color := C.CString(color) defer C.free(unsafe.Pointer(c_color)) new_image := C.AddShadowToImage(im.Image, c_color, c_opacity, c_sigma, c_x, c_y, exception) if failed := C.CheckException(exception); failed == C.MagickTrue { return ErrorFromExceptionInfo(exception) } im.ReplaceImage(new_image) return nil }
// 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 }
// Resize resizes the image based on the geometry string passed and stores the resized image in place // For more info about Geometry see http://www.imagemagick.org/script/command-line-processing.php#geometry func (im *MagickImage) Resize(geometry string) (err error) { exception := C.AcquireExceptionInfo() defer C.DestroyExceptionInfo(exception) rect, err := im.ParseGeometryToRectangleInfo(geometry) if err != nil { return err } ratio := im.ResizeRatio(int(rect.width), int(rect.height)) var new_image *C.Image if ratio > 0.4 { new_image = C.AdaptiveResizeImage(im.Image, rect.width, rect.height, exception) } else { new_image = C.ThumbnailImage(im.Image, rect.width, rect.height, exception) } if failed := C.CheckException(exception); failed == C.MagickTrue { return ErrorFromExceptionInfo(exception) } im.ReplaceImage(new_image) return nil }