IPhone ImageMagick Library - convert from batch script to Objective-C using MagickWand API
I decided to use the following ImageMagick library for iPhone development:
https://github.com/marforic/imagemagick_lib_iphone
It works really well. The sample project compiles just fine, but doesn't make any sense.
I usually use the " convert.exe " that comes with ImageMagick for Windows to convert images via the command line. So I will write a small batch file like:
@echo off
set SOURCE=image_to_convert.jpg
del result.jpg
del source_copy.jpg
convert.exe %SOURCE% -fill "#fff8f2" -colorize 100%% fill.jpg
copy %SOURCE% source_copy.jpg
convert.exe %SOURCE% -modulate 100,0,100 -|^
convert.exe - source_copy.jpg -compose overlay -composite -|^
convert.exe source_copy.jpg - -compose dissolve -define compose:args=37,100 -composite -|^
convert.exe - -modulate 100,70,100 +level 3.5%%,100%% -|^
convert.exe - -channel red -level 0%%,89%% +level 9%%,100%% -|^
convert.exe - -channel green +level 3.5%%,100%% -|^
convert.exe - -channel blue -level 0%%,93%% +level 4.7%%,100%% -|^
convert.exe - -brightness-contrast -5x3 -|^
convert.exe fill.jpg - -compose multiply -gravity center -composite -|^
convert.exe - -level 3.5%%,100%%,0.91 +level 2.7%%,100%% -|^
convert.exe - -channel red +level 3.5%%,100%% -|^
convert.exe - -channel green -level 0%%,87%% +level 1%%,100%% -|^
convert.exe - -channel blue -level 0%%,100%%,0.94 +level 7%%,100%% -|^
convert.exe - -brightness-contrast -1x0 final_converted_image.jpg
del source_copy.jpg
del fill.jpg
The problem is converting the above batch file to be used along with this particular library.
- (void)convertImage {
MagickWandGenesis();
magick_wand = NewMagickWand();
//UIImageJPEGRepresentation([imageViewButton imageForState:UIControlStateNormal], 90);
NSData * dataObject = UIImagePNGRepresentation([UIImage imageNamed:@"iphone.png"]);
MagickBooleanType status;
status = MagickReadImageBlob(magick_wand, [dataObject bytes], [dataObject length]);
if (status == MagickFalse) {
ThrowWandException(magick_wand);
}
// Resize image.
ImageInfo *imageInfo = AcquireImageInfo();
ExceptionInfo *exceptionInfo = AcquireExceptionInfo();
// Get image from bundle.
char *input_image = strdup([[[NSBundle mainBundle] pathForResource:@"iphone" ofType:@"png"] UTF8String]);
char *output_image = strdup([[[NSBundle mainBundle] pathForResource:@"iphone" ofType:@"png"] UTF8String]);
char *argv[] = { "convert", input_image, "-resize", "100x100", output_image, NULL };
// ConvertImageCommand(ImageInfo *, int, char **, char **, MagickExceptionInfo *);
status = ConvertImageCommand(imageInfo, 5, argv, NULL, exceptionInfo);
free(input_image);
free(output_image);
if (status == MagickFalse) {
ThrowWandException(magick_wand); // Always throws an exception here...
}
size_t my_size;
unsigned char * my_image = MagickGetImageBlob(magick_wand, &my_size);
NSData * data = [[NSData alloc] initWithBytes:my_image length:my_size];
free(my_image);
magick_wand = DestroyMagickWand(magick_wand);
MagickWandTerminus();
UIImage * image = [[UIImage alloc] initWithData:data];
[data release];
[imageViewButton setImage:image forState:UIControlStateNormal];
[image release];
}
The problem is status
always MagickFalse
, which means it throws an exception. I'm also not sure if I'm using it correctly ConvertImageCommand()
.
Any help would be greatly appreciated. Thanks in advance.
source to share
None of these are correct answers. The above code is simply incorrect and has been copied and pasted all over the internet in one form or another.
http://www.imagemagick.org/discourse-server/viewtopic.php?t=19504 http://www.imagemagick.org/discourse-server/viewtopic.php?t=25430 iPhone ImageMagick Library - convert from batch file script in Objective-C using the MagickWand API http://www.imagemagick.org/discourse-server/viewtopic.php?f=6&t=20527
the list continues
MagicWand
is the basis for image processing using the imagemagick API, whereas it ConvertImageCommand
calls directly the command line interface for a command convert
. If you want to do something via the imagemagick api then use MagicWand etc., but if you want to just call the same method used from the command line then call ConvertImageCommand
.
The fact that it returns MagickFalse
is correct. While I don't claim to have read the entire method and know everything it does, or why, if you look at convert.c
http://www.imagemagick.org/api/MagickWand/convert_8c_source.html , the last few lines of the function
3217 status&=WriteImages(image_info,image,argv[argc-1],exception);
3218 if (metadata != (char **) NULL)
3219 {
3220 char
3221 *text;
3222
3223 text=InterpretImageProperties(image_info,image,format);
3224 if (text == (char *) NULL)
3225 ThrowConvertException(ResourceLimitError,"MemoryAllocationFailed",
3226 GetExceptionMessage(errno));
3227 (void) ConcatenateString(&(*metadata),text);
3228 text=DestroyString(text);
3229 }
3230 DestroyConvert();
3231 return(status != 0 ? MagickTrue : MagickFalse);
3232 }
What it says is to return 0 ( MagickFalse
) on success when called from the command line, which is pretty reasonable.
The above code will work fine, without using all the MagicWand stuff -
// Resize image.
ImageInfo *imageInfo = AcquireImageInfo();
ExceptionInfo *exceptionInfo = AcquireExceptionInfo();
// Get image from bundle.
char *input_image = strdup([[[NSBundle mainBundle] pathForResource:@"iphone" ofType:@"png"] UTF8String]);
char *output_image = strdup([[[NSBundle mainBundle] pathForResource:@"iphone" ofType:@"png"] UTF8String]);
char *argv[] = { "convert", input_image, "-resize", "100x100", output_image, NULL };
// ConvertImageCommand(ImageInfo *, int, char **, char **, MagickExceptionInfo *);
status = ConvertImageCommand(imageInfo, 5, argv, NULL, exceptionInfo);
Alternatively, if you want to use the API directly, then there are many examples online that provide examples of using MagicWand.
The above code tries to mix and match two different methodologies. The MagicWand application you created does nothing, and if you look at the image at NSData
the end of the above code snippet, it is the same image you started with. The output ConvertImageCommand
should be what you expect.
source to share