Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bundle ImageMagick library with OS X App?

I am developing an OS X application, and would like to use ImageMagick to do some image manipulation. I have noticed that the CLI ImageMagick utilities require some environment variables to work. Is it possible to bundle the ImageMagick suite of tools with my application and use them in my code?

like image 761
Nippysaurus Avatar asked Jan 23 '11 12:01

Nippysaurus


2 Answers

So here is my solution:

I bundled the OS X binary release with my project, and used an NSTask to call the binaries. You need to specify the "MAGICK_HOME" and "DYLD_LIBRARY_PATH" environment variables for NSTask to work correctly. Here is snippet of what I am using.

Note that this example is hard coded to use the "composite" command ... and uses hard coded arguments, but you can change it to whatever you like ... it is just serving as a proof of concept.

-(id)init
{
    if ([super init])
    {
        NSString* bundlePath = [[NSBundle mainBundle] bundlePath];
        NSString* imageMagickPath = [bundlePath stringByAppendingPathComponent:@"/Contents/Resources/ImageMagick"];
        NSString* imageMagickLibraryPath = [imageMagickPath stringByAppendingPathComponent:@"/lib"];
    
        MAGICK_HOME = imageMagickPath;
        DYLD_LIBRARY_PATH = imageMagickLibraryPath;
    }
    return self;
}

-(void)composite
{
    NSTask *task = [[NSTask alloc] init];

    // the ImageMagick library needs these two environment variables.
    NSMutableDictionary* environment = [[NSMutableDictionary alloc] init];
    [environment setValue:MAGICK_HOME forKey:@"MAGICK_HOME"];
    [environment setValue:DYLD_LIBRARY_PATH forKey:@"DYLD_LIBRARY_PATH"];

    // helper function from
    // http://www.karelia.com/cocoa_legacy/Foundation_Categories/NSFileManager__Get_.m
    NSString* pwd = [Helpers pathFromUserLibraryPath:@"MyApp"];

    // executable binary path
    NSString* exe = [MAGICK_HOME stringByAppendingPathComponent:@"/bin/composite"];

    [task setEnvironment:environment];
    [task setCurrentDirectoryPath:pwd]; // pwd
    [task setLaunchPath:exe]; // the path to composite binary
    // these are just example arguments
    [task setArguments:[NSArray arrayWithObjects: @"-gravity", @"center", @"stupid hat.png", @"IDR663.gif", @"bla.png", nil]];
    [task launch];
    [task waitUntilExit];
}

This solution bundles the bulk of the entire library with your release (37MB at the moment), so it might be less than ideal for some solutions, but it is working :-)

like image 56
Nippysaurus Avatar answered Oct 07 '22 05:10

Nippysaurus


Possible? Yes. Many apps have done so, but it can be tedious.

NSTask allows for custom environment variables.

like image 37
bbum Avatar answered Oct 07 '22 05:10

bbum