imagick
imagick copied to clipboard
TransformImage needed
Hi,
I need to do something like convert <input> -geometry WxH^ -crop WxH+0+0 <output> but I'm using v3 release and rolling back to v2 is not an option available to me right now. Can someone suggest how can I achieve the same without the TransformImage which is there in the v2 release but not in the v3 release?
TIA
I'm actually not sure. If we can find out how the ImageMagick 7 C-API offers the support, then we can figure out how to do it in the bindings :-)
You can still call ResizeImage() and CropImage(). Do you specifically need the string expression format?
Yes, I tried mixing the two but I couldn't get the desired result. Do you think this is what we need here? https://www.imagemagick.org/api/MagickCore/transform_8c.html#ac850be2fcfecb8cd2c60b3239cc15822
But that is a private symbol. It isn't part of the public headers: https://www.imagemagick.org/api/MagickCore/transform_8h.html
Yes noticed that later. 😅 Is there any other way that might work similar to the terminal command above?
Ok I found this:
https://www.imagemagick.org/api/transform.php#TransformImage
This function and should probably be deprecated in favor of direct calls to CropImageToTiles() or ResizeImage(), as appropriate.
So we already expose ResizeImage, but not CropImageToTiles: https://www.imagemagick.org/api/MagickCore/transform_8c.html#a3cc91ea163ed75898d12819ca8db96d3
@justinfx I'm trying to write the binding to CropImageToTiles and since I'm new to Golang I don't know much right now. I tried this piece of code:
func (mw *MagickWand) CropImageToTiles(cropGeometry string) error {
cscropgeometry := C.CString(cropGeometry)
defer C.free(unsafe.Pointer(cscropgeometry))
ok := C.MagickCropImageToTiles(mw.mw, cscropgeometry)
return mw.getLastErrorIfFailed(ok)
}
But I'm getting this error imagick/magick_wand_image.go:448:8: could not determine kind of name for C.MagickCropImageToTiles. I searched for C.MagickCropImage() for reference in the project but got no hit. I also tried C.CropImageToTiles(mw.mw, cscropgeometry) and got the function signature mismatch. Can you point me in the right direction?
Here is the signature https://github.com/ImageMagick/ImageMagick/blob/93b707b4a5882ab3d7f8904984684846fe178a97/MagickCore/transform.h#L30
It takes a 3rd parameter for the exception object. You might be able to pass nil and just use the check afterwards. See if any of the other calls are passing the exception parameter
Can you tell me where is the definition of C.MagickCropImage? I need a reference for C.MagickCropImageToTiles.
Its right there in that header: #include <MagickCore/transform.h>
https://github.com/ImageMagick/ImageMagick/blob/master/MagickCore/transform.h
Its not a wand api call; It is a core api call, which takes an Image*. So that means in order to use it you would have to get the Image* from your wand GetImageFromMagickWand
Here is an example C usage of it: https://sourcegraph.com/github.com/ImageMagick/ImageMagick@master/-/blob/MagickWand/operation.c#L2123:21
@justinfx I think I'm wrong but does it require any changes to ImageMagick? I still don't get it how can I bind this. 😞
No it doesn't require changes to ImageMagick. It just means you have to include "<MagickCore/transform.h>" in Go, and wrap the call to C.CropImageToTiles. Once you do that, you would call it from Go by having it pass the *Image ala GetImageFromMagickWand
I haven't tried anything yet but that is what it looks like to me.
I tried what you told and I got type mismatch this time.
magick_wand_image.go:421: cannot use cimage (type *Image) as type *_Ctype_struct__Image in argument to func literal
How can I do the type conversion here? Also, I'm not sure how will I handle the error here.
You can't pass the Go type directly to C. So you need to pass the underlying pointer: unsafe.Pointer(cimage.img)
You can handle the exception by using the existing imagick support for it: https://github.com/gographics/imagick/blob/im-7/imagick/image.go#L20
So all the parts should already be there in the im-7 branch (Image, ExceptionInfo), and you are just creating a new function that can pass the right things into the C call.
any change to this? I want to use TransformImage in v3 too
Or at lest I have to figure out how to programatically use "^" effect
No one has submitted any updates to this yet. Feel free to submit a PR!
I've just added CropImageToTiles as a method of a MagickWand. Can you confirm if this example works for your needs?
mw := imagick.NewMagickWand()
mw.SetSize(640, 480)
if err := mw.ReadImage("logo:"); err != nil {
panic(err)
}
aspect := float64(mw.GetImageWidth()) / float64(mw.GetImageHeight())
mw.ResizeImage(400, uint((400/aspect)+0.5), imagick.FILTER_LANCZOS)
if err := mw.CropImageToTiles("50x50%+100+100"); err != nil {
panic(err)
}
As per the docs about the deprecation of TransformImage, one still has to manually do a ResizeImage before the crop. But this example shows how to preserve the aspect ratio.
This has been available for a while. Closing ticket