iPhone ImageMagick Library - converting from batch file script to Objective-C using MagickWand API
I've decided to use the following ImageMagick library for iPhone development:
https://github.com/marforic/imagemagick_lib_iphone
It works quite开发者_StackOverflow well. The sample project compiles just fine, but doesn't make any sense whatsoever.
Usually, I'll use the "convert.exe" that comes with ImageMagick for Windows to convert images via the command line. So I'll write a little batch file like the following:
@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 alongside that 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 that status
is always MagickFalse
, which means it throws an exception. I'm also not sure whether I'm using ConvertImageCommand()
in the correct way either.
Any help would be greatly appreciated. Thanks in advance.
I ended up using MagickCommandGenesis()
to achieve the desired result.
None of these are the right answer. The code above is just plain wrong and has been copied and pasted all over the internet in some 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 - converting from batch file script to Objective-C using MagickWand API http://www.imagemagick.org/discourse-server/viewtopic.php?f=6&t=20527
the list goes on
MagicWand
is the framework to do image manipulations using the imagemagick API, whereas ConvertImageCommand
calls directly into the commandline interface for the convert
command. If you wish to do things through imagemagick's api, then use MagicWand etc, but if you wish to simply call into the same method that is used from the commandline, then call ConvertImageCommand
.
The fact that it is returning MagickFalse
is correct. While I don't claim to have read the whole method and know everything it's doing 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 are
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 commandline, which is fairly reasonable.
The above code will work fine without all the MagicWand stuff as so -
// 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 plenty of samples online that provide examples of how to use MagicWand.
The above code is attempting to mix and match two different methodologies. The MagicWand instantiation above is not doing anything, and if you will look at the image in the NSData
at the end of the above code snippet, it is the same image you started with. The output of the ConvertImageCommand
ought to be what you're expecting though.
精彩评论