imagick icon indicating copy to clipboard operation
imagick copied to clipboard

TransformImage needed

Open ajatprabha opened this issue 7 years ago • 18 comments

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

ajatprabha avatar May 31 '18 06:05 ajatprabha

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 :-)

justinfx avatar May 31 '18 07:05 justinfx

You can still call ResizeImage() and CropImage(). Do you specifically need the string expression format?

justinfx avatar May 31 '18 07:05 justinfx

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

ajatprabha avatar May 31 '18 07:05 ajatprabha

But that is a private symbol. It isn't part of the public headers: https://www.imagemagick.org/api/MagickCore/transform_8h.html

justinfx avatar Jun 01 '18 04:06 justinfx

Yes noticed that later. 😅 Is there any other way that might work similar to the terminal command above?

ajatprabha avatar Jun 01 '18 04:06 ajatprabha

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 avatar Jun 01 '18 04:06 justinfx

@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?

ajatprabha avatar Jun 01 '18 07:06 ajatprabha

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

justinfx avatar Jun 01 '18 07:06 justinfx

Can you tell me where is the definition of C.MagickCropImage? I need a reference for C.MagickCropImageToTiles.

ajatprabha avatar Jun 04 '18 05:06 ajatprabha

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 avatar Jun 04 '18 05:06 justinfx

@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. 😞

ajatprabha avatar Jun 14 '18 08:06 ajatprabha

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.

justinfx avatar Jun 14 '18 12:06 justinfx

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.

ajatprabha avatar Jun 15 '18 10:06 ajatprabha

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.

justinfx avatar Jun 15 '18 12:06 justinfx

any change to this? I want to use TransformImage in v3 too

piotrkochan avatar Jun 17 '19 12:06 piotrkochan

Or at lest I have to figure out how to programatically use "^" effect

piotrkochan avatar Jun 17 '19 14:06 piotrkochan

No one has submitted any updates to this yet. Feel free to submit a PR!

justinfx avatar Jun 17 '19 20:06 justinfx

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.

justinfx avatar Jan 05 '20 01:01 justinfx

This has been available for a while. Closing ticket

justinfx avatar Jul 14 '23 21:07 justinfx