美文网首页
自己做个命令行工具

自己做个命令行工具

作者: ZHK1024 | 来源:发表于2018-07-19 22:29 被阅读217次

开发中一直在使用 cocoapods , git, class-dump, cycript 等强大的命令行工具.
今天就来自己尝试做一个简单了解一下这些工具的工作原理.

开始前先讲个故事:

UI : iOS 的 icon 都需要那些尺寸 ◔ ‸◔??
我 : 给我一张 1024 的就好 (-_-#). (思路被打断正不爽).

于是后来每次我都只能拿到一张 1024 * 1024 的 icon, 不得不每次都自己用 预览 来导出各种尺寸的 icon.
毕竟自作自受 ("▔□▔)/ , 那今天就写个生成各种尺寸 icon 的工具吧.


0x00 如何开始

  1. 首先使用 Xcode 创建一个 Command Line 工程. 没错, 就是那种只有一个 .m 文件, run 了之后只会 printfNSLog 的那种工程, 我的项目名称就叫 appicon, 后面会提到.

  2. 导入头文件 #import <Cocoa/Cocoa.h>, 因为是基于 macOS 的, 所以导入这个. 不然 NSFileManager 都用不了, 大概...

  3. 先上代码, 下面再解释.

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSString *input = nil;
        NSString *output = nil;
        
        int ch;
        // 读取参数
        while ((ch = getopt(argc, argv, "i:o:")) != -1) {
            switch (ch) {
                case 'o':
                    output = [NSString stringWithUTF8String:optarg];
                    break;
                case 'i':
                    input = [NSString stringWithUTF8String:optarg];
                    break;
            }
        }
        
        BOOL isDir = NO;
        // 判断文件路径, 以及输出目标路径
        if (input && output && [[NSFileManager defaultManager] fileExistsAtPath:output isDirectory:&isDir]) {
            NSImage *image = [[NSImage alloc] initWithContentsOfFile:input];
            if (image == nil) {
                printf("File Load Failed At %s", input.UTF8String);
                exit(0);
            }
            if (!isDir) {
                output = [output stringByAppendingPathComponent:@"icons"];
            }
            writeImage(image, output, 180);
            writeImage(image, output, 120);
            writeImage(image, output, 80);
            writeImage(image, output, 60);
            writeImage(image, output, 40);
        } else {
            printf("Path Error!\n");
        }
    }
    return 0;
}

也没多少代码, 看起来也没多难, 应该都能看懂, 除了这段:

    int ch;
    while ((ch = getopt(argc, argv, "i:o:")) != -1) {
    switch (ch) {
        case 'o':
            output = [NSString stringWithUTF8String:optarg];
            break;
        case 'i':
            input = [NSString stringWithUTF8String:optarg];
            break;
        }
    }

首先要注意一个函数 getopt, 这个就是获取命令行输入参数的关键.

// 函数返回 -1 表示参数解析完毕
int getopt(int argc, char * const argv[], const char *optstring);

看函数声明有没有熟悉的东西?
我们的main 函数 int main(int argc, const char * argv[]) 里面有一模一样的 2 个参数.

argcmain() 函数传递过来的参数的个数
argvmain() 函数传递过来的参数的字符串指针数组
optstring:选项字符串,告知 getopt() 可以处理哪个选项以及哪个选项需要参数

argcargv 直接放进去就可以了, optstring 此处传入的是 "i:o:".
char* optstring = "ab:c::";

字符 意义 格式
单个字符 a 表示选项a没有参数 格式:-a 即可,不加参数
单字符加冒号 b: 表示选项b有且必须加参数 格式:-b 100 或 -b100 ,但 -b=100 错
单字符加2冒号 c: : 表示选项c可以有,也可以无 格式:-c200,其它格式错误

因此此处的 "i:o:", 表示有 2 个参数 -i-o, 分别代表 inputoutput, 可以看成是参数名.
使用一个while 循环来获取所有的参数, 此处的 optarg 就是获取后的参数值.

以下写过 iOS 的稍微转换一下就可以了.都是常见的功能.
压缩图片尺寸:

/**
 压缩图片到指定尺寸

 @param image 图片对象
 @param width 目标尺寸
 @return 压缩结果
 */
NSData * compressImage(NSImage *image, float width) {
    NSData *data = image.TIFFRepresentation;
    if (data == nil) {
        return nil;
    }
    CGImageSourceRef source = CGImageSourceCreateWithData((CFDataRef)data, NULL);
    CGImageRef cgimage = CGImageSourceCreateImageAtIndex(source, 0, NULL);
    
    NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithCGImage:cgimage];
    rep.size = CGSizeMake(width, width);
    NSData *pngData = [rep representationUsingType:NSBitmapImageFileTypePNG properties:@{}];
    return pngData;
}

把 image 写入指定的位置.

/**
 处理图片并把结果写入磁盘

 @param image 被处理的图片对象
 @param path  写入路径
 @param size  目标图片尺寸
 */
void writeImage(NSImage *image, NSString *path, float size) {
    path = [path stringByAppendingPathComponent:[NSString stringWithFormat:@"%.0f.png", size]];
    [compressImage(image, size) writeToFile:path atomically:NO];
}

0x01 如何使用

  1. 项目编译之后会生成一个 appicon , Product 文件夹下的 Mach-O 文件.
  2. 复制 appiconusr/local/bin, 放在此目录下, 在任何文件夹下都能够找到命令, 不然还要指定路径.
  3. 使用命令:
$ appicon -i [输入文件路径] -o [输出目录路径]

例如:

$ appicon -i ~/Desktop/1024.png -o ~/Desktop

或者

$ cd ~/Desktop/
$ appicon -i ./1024.png -o ./

而上文中 inputoutput 分别就对应 ~/Desktop/1024.png~/Desktop.

Github 源码地址

相关文章

  • 自己做个命令行工具

    开发中一直在使用 cocoapods , git, class-dump, cycript 等强大的命令行工具.今...

  • 使用node打造自己的命令行工具方法教程

    这篇文章主要介绍了使用node打造自己的命令行工具方法教程,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一...

  • pod install /Library/Ruby/Gems/2

    百度出来一堆垃圾,做个记录,就是检查一下xcode是否安装命令行工具。 去Xcode - > Preference...

  • Android应用查看CPU与内存占用说明

    一、前置条件: 在电脑端安装 adb 命令行工具. 验证是否安装了 adb 命令行工具打开 命令行工具 , 输入 ...

  • vue实践笔记

    安装方式 直接用script工具 命令行工具 实践指南 环境准备vue命令行工具 可以方便的命令行工具构建一个we...

  • 正则表达式命令行工具

    前言 对于我这种平时喜欢钻研命令行工具给自己的工作提升效率的人来说,遇到一个好的命令行工具会觉得异常的珍惜。命令行...

  • Linux命令行神器

    Linux命令行(terminal)可以做很多有趣的事情,有一些堪称神器的工具,以Ubuntu为例做个分享。 mo...

  • npm包安装

    1.上传自己编写的包和命令行工具 2.下载别人写好的包和命令行工具 一、查看版本 npm -v

  • (翻译) fabric1.2.1新特性-服务发现命令行接口

    服务发现命令行接口 发现服务具有自己的命令行接口工具,该接口工具使用YAML配置文件来保存例如,证书、私钥路径,以...

  • Nodejs构建自己的全局命令行工具

    关键字: Nodejs本文主要介绍一下windows下如何构建一个自己的全局命令行工具,了解创建命令行工具的原理,...

网友评论

      本文标题:自己做个命令行工具

      本文链接:https://www.haomeiwen.com/subject/xhctmftx.html