Skip to content

Instantly share code, notes, and snippets.

@aaronpeterson
Forked from SheffieldKevin/main.m
Created August 9, 2014 03:55
Show Gist options
  • Select an option

  • Save aaronpeterson/20807b893dbcdf9c0da9 to your computer and use it in GitHub Desktop.

Select an option

Save aaronpeterson/20807b893dbcdf9c0da9 to your computer and use it in GitHub Desktop.

Revisions

  1. @SheffieldKevin SheffieldKevin revised this gist Oct 23, 2013. 1 changed file with 9 additions and 3 deletions.
    12 changes: 9 additions & 3 deletions main.m
    Original file line number Diff line number Diff line change
    @@ -1,10 +1,16 @@
    //
    // main.m
    // creategif
    //
    // Created by Kevin Meaney on 21/10/2013.
    // Copyright (c) 2013 Kevin Meaney. All rights reserved.
    //

    // I've briefly blogged about it here:
    // http://blog.yvs.eu.com/2013/10/creating-gif-animations-using-coreimagequartz
    // The following code is all that is all the code needed for a creating a command line tool to generate
    // a gif animation from image files.
    // The main limitation with this code is that apart from the frame delay time of 0.1 second, every
    // other frame delay time has to be a multiple of 0.5 seconds. There is no checking that the frame size
    // of each image file is the same or resizing of frames to make them conform.
    // I provide no warranty as to the operation of this code.

    #import <Foundation/Foundation.h>
    @import ImageIO;
  2. @SheffieldKevin SheffieldKevin revised this gist Oct 23, 2013. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion main.m
    Original file line number Diff line number Diff line change
    @@ -123,7 +123,7 @@ int main(int argc, const char * argv[])
    (__bridge CFDictionaryRef)gifFileProps);
    if (!imageDest)
    {
    printf("Couldn't create image destination");
    printf("Couldn't create image destination\n");
    return 0;
    }

  3. @SheffieldKevin SheffieldKevin revised this gist Oct 23, 2013. 1 changed file with 2 additions and 3 deletions.
    5 changes: 2 additions & 3 deletions main.m
    Original file line number Diff line number Diff line change
    @@ -14,10 +14,9 @@ void PrintUsage()
    printf("creategif - usage:\n");
    printf(" ./creategif [-parameter <value> ...], filename1, filename2, ...\n");
    printf(" Parameters are preceded by a -<parameterName>. The order of the parameters is unimportant.\n");
    printf(" All the input image filenames follow the parameters.\n");
    printf(" All the input image filenames follow the parameters and their values.\n");
    printf(" You probably need to escape or quote paths especially if the paths includes spaces etc..\n");
    printf(" Only one of -delaytime or -unclampeddelaytime needs to be specified, both can be.\n");
    printf(" If the output file already exists then it will be deleted prior to saving the new file if allowed.\n");
    printf(" If the output file already exists then it will be overwritten if possible.\n");
    printf(" Available parameters are:\n");
    printf(" -outputfile <output file path which should finish with a gif extension>\n");
    printf(" -delaytime <should be a floating point number above 0.1>\n");
  4. @SheffieldKevin SheffieldKevin created this gist Oct 23, 2013.
    173 changes: 173 additions & 0 deletions main.m
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,173 @@
    //
    // main.m
    // creategif
    //
    // Created by Kevin Meaney on 21/10/2013.
    // Copyright (c) 2013 Kevin Meaney. All rights reserved.
    //

    #import <Foundation/Foundation.h>
    @import ImageIO;

    void PrintUsage()
    {
    printf("creategif - usage:\n");
    printf(" ./creategif [-parameter <value> ...], filename1, filename2, ...\n");
    printf(" Parameters are preceded by a -<parameterName>. The order of the parameters is unimportant.\n");
    printf(" All the input image filenames follow the parameters.\n");
    printf(" You probably need to escape or quote paths especially if the paths includes spaces etc..\n");
    printf(" Only one of -delaytime or -unclampeddelaytime needs to be specified, both can be.\n");
    printf(" If the output file already exists then it will be deleted prior to saving the new file if allowed.\n");
    printf(" Available parameters are:\n");
    printf(" -outputfile <output file path which should finish with a gif extension>\n");
    printf(" -delaytime <should be a floating point number above 0.1>\n");
    // printf(" -unclampeddelaytime <should be a floating point number above 0.1>\n");
    printf(" Sample export lines:\n");
    printf(" ./creategif -outputfile blahblah.gif -delaytime 0.4 -unclampeddelaytime 0.4 image1.png image2.png image3.png image4.png\n");
    printf(" ./creategif -outputfile \"Users/ktam/gifs/blahblah.gif\" -delaytime 1.0 image1.png image2.png image3.png image4.png\n");
    }

    BOOL GetFloatFromString(NSString *string, CGFloat *value)
    {
    NSScanner *scanner = [[NSScanner alloc] initWithString:string];
    CGFloat floatVal;
    BOOL gotValue = [scanner scanDouble:&floatVal];
    if (gotValue)
    {
    *value = floatVal;
    }
    return gotValue;
    }

    NSMutableArray *inputImageList;
    NSString *outFilePath;
    CGFloat delayTime;
    CGFloat unclampedDelayTime;
    BOOL gotDelayTime = NO;
    BOOL gotUnclampedDelayTime = NO;

    bool GetArgs(int argc, const char **argv) // returns true if successful.
    {
    bool success = true;

    argv++;
    argc--;
    const char *args;
    // Get the parameters
    while (argc > 0 && **argv == '-')
    {
    args = *argv;
    argv++;
    argc--;

    if ( ! strcmp ( args, "-outputfile" ) )
    {
    outFilePath = @(*argv++);
    argc--;
    }
    else if ( ! strcmp( args, "-delaytime" ))
    {
    gotDelayTime = GetFloatFromString(@(*argv++), &delayTime);
    argc--;
    }
    /* else if ( ! strcmp( args, "-unclampeddelaytime"))
    {
    gotUnclampedDelayTime = GetFloatFromString(@(*argv++), &unclampedDelayTime);
    argc--;
    }
    */
    }

    if (!(gotDelayTime || gotUnclampedDelayTime))
    success = false;

    if (!outFilePath)
    success = false;

    // If we've got to the end of arguments and there are no input files then bail.
    if (!success)
    return success;

    inputImageList = [[NSMutableArray alloc] initWithCapacity:0];
    // [inputImageList addObject:@(args)];
    // Finished getting parameters. Now get list of source files. 1 image per file.
    while (argc > 0)
    {
    args = *argv;
    argv++;
    argc--;
    [inputImageList addObject:@(args)];
    }
    if (!inputImageList || [inputImageList count] == 0)
    success = false;

    return success;
    }

    int main(int argc, const char * argv[])
    {
    @autoreleasepool
    {
    if (!GetArgs(argc, argv))
    {
    PrintUsage();
    return 0;
    }

    NSDictionary *gifFileProps = @{ @"{GIF}" : @{ @"HasGlobalColorMap" : @YES,
    @"LoopCount" : @(0) } };
    NSURL *outputURL = [[NSURL alloc] initFileURLWithPath:outFilePath isDirectory:NO];
    CGImageDestinationRef imageDest;
    imageDest = CGImageDestinationCreateWithURL((__bridge CFURLRef)outputURL,
    CFSTR("com.compuserve.gif"),
    [inputImageList count],
    (__bridge CFDictionaryRef)gifFileProps);
    if (!imageDest)
    {
    printf("Couldn't create image destination");
    return 0;
    }

    CGImageDestinationSetProperties(imageDest,
    (__bridge CFDictionaryRef)gifFileProps);

    for (NSString *inputFile in inputImageList)
    {
    NSString *expandedString = [inputFile stringByExpandingTildeInPath];
    NSURL *sourceFile = [[NSURL alloc] initFileURLWithPath:expandedString
    isDirectory:NO];
    CGImageSourceRef imageSource;
    imageSource = CGImageSourceCreateWithURL((__bridge CFURLRef)sourceFile,
    NULL);
    if (!imageSource)
    {
    printf("Invalid source file path\n");
    return 0;
    }

    if (CGImageSourceGetCount(imageSource))
    {
    CGImageRef theImage;
    theImage = CGImageSourceCreateImageAtIndex(imageSource, 0, NULL);
    if (theImage)
    {
    NSMutableDictionary *gifFrameProps;
    gifFrameProps = [[NSMutableDictionary alloc] initWithCapacity:0];
    if (gotDelayTime)
    [gifFrameProps setObject:@(delayTime) forKey:@"DelayTime"];
    // if (gotUnclampedDelayTime)
    // [gifFrameProps setObject:@(unclampedDelayTime)
    // forKey:@"UnclampedDelayTime"];
    NSDictionary *frameProps = @{ @"{GIF}" : gifFrameProps };
    CGImageDestinationAddImage(imageDest, theImage,
    (__bridge CFDictionaryRef)frameProps);
    CFRelease(theImage);
    }
    }
    CFRelease(imageSource);
    }
    CGImageDestinationFinalize(imageDest);
    CFRelease(imageDest);
    }
    return 0;
    }