美文网首页Mac黑科技软件、网站iOSmac软件收集
Iconista——Mac下最炫酷的主题图标美化工具

Iconista——Mac下最炫酷的主题图标美化工具

作者: Uri | 来源:发表于2015-05-31 22:11 被阅读11110次

    Preface

    是不是早已受够了系统原有的奇丑无比的图标,对于追求完美不放过任何一个细节的我们来说,这个简直不能忍啊。

    Launchpad早期图

    整个事情的起因就是这么简单,那天晚上我决定不能再这样下去了,于是乎我便迫不及待的打开电脑,兴致冲冲的干了起来。

    在MacOSX下替换App图标主要有两种方式:
    1.直接替换App包里的图标
    右键>显示包内容>Contents>Resources,备份原来的图标,将你的图标按照原来的重命名。

    替换icon.icns即可

    2.显示简介里替换

    这个比上面的要简单,将图标直接拖到简介里原来的图标上就可以了。

    上面说的是替换App的icon,但是Finder废纸篓不能用上述方法,需要前往/系统/资源库/CoreServices,找到Dock,然后进入content>resources,替换相对应的findertrashemptytrashfull图片。注意备份哟!

    替换finder

    如果故事发展到这里就结束了,那个没有下文了,然而事情没这么简单。

    Shell Script

    话说刚开始试了几个,感觉还不错。这时候你说干脆写个自动脚本算了,一开始我是拒绝的。可是后来一个一个的替换,一想到还有一百多个图标,实在是太TM蛋疼了。。

    为什么用shell脚本?因为我不会啊,正好给自己一个理由去学学shell编程。

    (最后才发现,原来替换图标是个大坑,用代码更麻烦。。)

    有哪些功能:

    • 用默认的主题替换App icon
    • 恢复原来的图标
    • 从Launchpad中隐藏指定的App
    • 用指定的主题替换App icon
    • 替换指定文件或文件夹的icon
    • 帮助
    # Usage
    function usage() {
        echo "[*] Usage:"
        echo "[*] $0 [-i | -r | -h | -d [app_name] | -s [theme] | -f [file] [icon]]"
        echo "[*] -i: install the default icon theme"
        echo "[*] -r: restore the origin icon"
        echo "[*] -d: delete/hide the app in Launchpad"
        echo "[*] -s: install the specified theme"
        echo "[*] -f: set icon for file or folder"
        echo "[*] -h: help"
    }
    

    由于某些要对系统文件进行操作,所以需要root权限。

    if [ $UID -ne 0 ]; then
        echo "[*] Superuser privileges are required to run this script."
        echo "[*] e.g. \"sudo $0\""
        exit 1
    fi
    
    if [ ! $1 ]; then
        usage
        exit 1
    fi
    

    从上面我们知道有两种方法可以替换图标,其实这两种方法原理不同。下面我们来分别实现:

    1.替换App包里的图标

    第一种方法最简单,我们只需要替换相应的/Contents/Resources/的App图标即可。先备份原来的icon文件,然后复制新的icon过来。

    # setAppIcon [app_path] [iconfile]
    function setAppIcon() {
        apath=$1
        ipath=$2
    
        # Replace the *.app/Contents/Resources/*.icns
        icon=`readPlist "$apath/Contents/Info.plist" "CFBundleIconFile"`
        if [ "${icon##*.}" != "icns" ]; then
            icon="$icon".icns
        fi
    
        if [ ! -e "$apath/Contents/Resources/$icon.bak" ]; then
            cp "$apath/Contents/Resources/$icon" "$apath/Contents/Resources/$icon.bak"
        fi
        cp "$ipath" "$apath/Contents/Resources/$icon"
        
        touch "$apath/1"
        rm "$apath/1"
    }
    

    咦,最后这个奇葩的touch接着rm是干嘛的,老实说当时我手动替换图标后发现半天没有变化,相信大家试过也是这样。

    但是有次不经意间多创建了一个文件,奇怪的发现居然变了,估计是缓存的原因吧,我也不知道。。反正就通过这种方式更新App icon使之生效。。

    还有一个问题就是,App中icns格式的图标众多,如何找到其中的icon图标?

    Plist文件是以.plist为结尾的文件的总称. 众所周知, Plist在Mac OS X系统中起着举足轻重的作用,就如同Windows里面的Registry一样,系统和程序使用Plist文件来存储自己的安装/配置/属性等信息。

    由于每个App的icon文件名不是固定的,但是我们可以在App里的Info.plist文件中找到,其中CFBundleIconFile对应的就是icon文件。

    icon=`readPlist "$apath/Contents/Info.plist" "CFBundleIconFile"`
    

    然而怎么读取plist格式的文件呢?

    cat命令输出文本然后去匹配读取其中的键值对?太麻烦了,这里我们寻找到了一个自带的工具Plutil

    Plutil是开发环境提供的一个命令行命令,使用这个命令可以转换Plist文件的格式,而且可以检查Plist文件的语法和完整性。

    通过plutil -p [plist file]可以以键值对的格式输出。最后,读取键值的readPlist函数如下:

    # readPlist [plist] [key]
    function readPlist() {
        plist=$1
        key=$2
    
        value=`plutil -p "$plist" | grep $key | awk -F '=>' '{print $2}' | sed -e 's/\"//g'`
        echo $value
    }
    

    2.显示简介里替换

    首先我们要搞清楚当我们把图片拖到简介里的小图标时到底改变了什么。

    我们随便打开一个App看看,感觉里面没有什么啊。

    Sketch App

    现在,看不到什么并不意味着没有什么,在终端里再看看:

    居然发现一个隐藏文件Icon?,看名字也知道是干嘛的了,找了半天原来你在这里!

    那个?不是真的问号,而是乱码。其实这个文件的名字应该是Icon\r\r指的就是十六进制的0x0D,因为\r不是可打印字符,所以在终端里显示为?。如果在终端里自动补全的话则会显示Icon^M, ^M 就是 \r

    ls -lO
    

    hidden说明这是一个隐藏文件,所以我们在Finder里看不到。

    当你尝试打开它时

    open Icon^M
    

    打不开,什么都木有。

    可是,不知注意到没,好奇怪,为啥这个文件的大小是零啊~

    The actual icon data is stored in the file's Resource Fork. These days Mac OS doesn't use actual resource forks, so the image is stored in an HFS extended attribute named com.apple.ResourceFork.

    在 Mac OS X 下,文件经常会被附加上 OS X 特有的扩展属性 ( extend attributes ),具体表现是用 ls -l 查看时会有 @ 的标记,这个 @ 属性是用户在 Finder 中对文件进行任意操作后就会被附带上

    通过@参数查看扩展属性:

    ls -l@ Icon^M
    

    果然icon数据存在com.apple.ResourceFork中。

    我们还可以把resource fork里面的数据复制出来:

    sudo cp Icon^M/..namedfork/rsrc Icondata
    

    从十六进制数据中很清楚的看出这是一个icns格式的icon。

    现在我们已经知道替换的东西在哪里了,接下来就是如何替换了。

    这里要用到Xcode里面的Developer Tools一些工具,所以前提是你已安装了Xcode及其Developer Tools,具体过程见代码:

    # xcodeDevToolsSetIcon [filepath] [iconfile]
    function xcodeDevToolsSetIcon() {
        fpath=$1
        ipath=$2
        xcode_devtools="/Applications/Xcode.app/Contents/Developer/Tools/"
    
        if [ -d $xcode_devtools ]; then
            if [ -d "$fpath" ]; then
                # $fpath is a direstory
                touch "$fpath/Icon\r"
                cp "$ipath" tempIcon.icns
                sips -i tempIcon.icns > /dev/null 2>&1
                derez -only icns tempIcon.icns > tempicns.rsrc
                rez -a tempicns.rsrc -o "$fpath/Icon\r"
                setfile -a C "$fpath"
                rm tempIcon.icns
                rm tempicns.rsrc
                # hide Icon^M file inside folder
                setfile -a V "$fpath/Icon\r"
            elif [ -e "$fpath" ]; then
                # $fpath is a file
                cp "$ipath" tempIcon.icns
                sips -i tempIcon.icns > /dev/null 2>&1
                derez -only icns tempIcon.icns > tempicns.rsrc
                rez -a tempicns.rsrc -o "$fpath"
                setfile -a C "$fpath"
                rm tempIcon.icns
                rm tempicns.rsrc
            else
                echo "$fpath is NOT a file or direstory"
                exit 1
            fi
        else
            echo "[*] Error: this need Xcode Developer/Tools. Please install it first!"
            exit 1
        fi
    }
    

    Whst's more

    当上面两个重头完成后,剩下还有一些其他的,比如说替换Finder和废纸篓:

        # Change Finder & Trash app icon
        echo "[*] Replace the Finder & Trash icon ..."
        for img in ${imgs[*]}
        do
            if [ ! -e $dock_res/$img.bak ]; then
                mv $dock_res/$img $dock_res/$img.bak
            else
                rm $dock_res/$img 2> /dev/null
            fi
        done
    
        for file in $default_theme/Docker/*
        do
            cp -p $file $dock_res/
        done
        # delete caches & restart docker
        find /private/var/ -name *dock.iconcache* -exec rm {} \;
        killall Dock
    

    注意的是,要使Dock的上的图标生效需重启Dock。

    隐藏 Launchpad 里的图标:

    # hideAppIconInLaunchpad [app_name]
    function hideAppIconInLaunchpad() {
        appname=$1
        sqlite3 $(find /private/var/folders -name com.apple.dock.launchpad)/db/db "DELETE FROM apps WHERE title='$appname';"
        killall Dock
    }
    

    将动态屏保设置成背景(这是什么鬼。。)

    # Make screensaver load as the desktop wallpaper
    function screensaverWallpaper() {
        /System/Library/Frameworks/ScreenSaver.framework/Resources/ScreenSaverEngine.app/Contents/MacOS/ScreenSaverEngine -background &
    }
    

    当然啦,还要有还原的功能:

    # restoreAppIcon [app_path]
    function restoreAppIcon() {
        apath=$1
    
        for bak in "$apath"/Contents/Resources/*.icns.bak
        do
            if [ "$bak" != "$apath/Contents/Resources/*.icns.bak" ]; then
                pre="${bak%.*}"
                rm "$pre"
                cp "$bak" "$pre"
            fi
        done
    
        if [ -e "$apath/Icon\r" ]; then
            rm "$apath/Icon\r"
        fi
    
        touch "$apath/1"
        rm "$apath/1"
    }
    function restoreDocker() {
        for img in ${imgs[*]}
        do
            if [ -e $dock_res/$img.bak ]; then
                mv $dock_res/$img.bak $dock_res/$img
            fi
        done
        find /private/var/ -name *dock.iconcache* -exec rm {} \;
        killall Dock
    }
    

    主程序的大部分是逻辑控制,这里就不贴出来了,全部代码请移步Github——Iconista

    注:上述所有代码中的 "/Icon\r" 都应该是 "/Icon"$'\r'。为啥会乱码,简书的bug?

    Iconista

    经过本人的慎重决定,这货的名字就叫Iconista,我们的口号是:不要998,就要Iconista~

    本着分享的精神,Iconista是一个开源项目,并且欢迎大家无限次无羞耻的免费使用和反馈。项目地址看这里看这里---->O_O!

    使用方法很简单,下载好源码后:

    cd build/
    sudo ./Iconista -i
    

    即可!
    更多的使用方法见文档

    这里多说一句的是,默认使用的主题图标来自BlackVariant (Patrick),非商业性免费使用。

    其放在/Themes/default/目录下。你也可以使用自己的主题,同时也欢迎大家制作更多更炫酷的主题。

    如何自定义主题

    /Themes/路径下建立一个以你主题为名字的文件夹,必须包含以下目录:

    • /Applications
    • /Apps
    • /Docker
    • /Utilities

    每个文件夹里放相应的icns格式的图标,图标名以App名命名,具体可参考默认主题

    这么酷炫的东东怎么能没有主页呢,当然有啦,在这里也预告一下,关于这个页面有好多要讲的,下一篇文章将要带领你体验背后那些不为人知的故事。

    地址:http://urinx.github.io/app/iconista/

    Iconista主页

    Preview

    用Mac,自定义主题图标,从此逼格又提升一个数量级。这里我就给大家预览一下最后的效果吧!

    这是原先的:


    原来的

    Iconista后期处理后的:

    就是这么任性!

    Last

    最后的最后,欢迎大家关注我的微信公众号(urinx),满满的干货

    如果你有什么建议和想法想和我交流,各种bug想要反馈,或者纯属想要交朋友,这是我的微信(google-2)

    wechat

    Updates

    2015.6.6

    1. 新增了 Mac OS X 10.9 的图标主题
    2. 默认主题补充了更多的第三方App图标
    3. 修复了一些bug

    Reference

    [0]. MAC系统图标的更换
    [1]. 在 10.9 下换 Finder 图标的方法
    [2]. plutil(1) Mac OS X Manual Page
    [3]. Mac OS X: 编辑PList文件的嵌套键值
    [4]. OS X 的一些技巧汇总
    [5]. osx - Icon? file on OS X desktop - Super User
    [6]. How to change the icon of file in MacOS in Objective-C? - Stack Overflow
    [7]. Changing icon of package created by package maker - Stack Overflow
    [8]. osx - Manipulate Mac OS X file icons from Automator or command-line - Super User

    相关文章

      网友评论

      • 鸭梨山大哎:建议写写popclip插件
      • f61ba0670166:学习了
      • chuchur:看了你这图,感觉又不想换了, 换了更丑。
      • 躲猫_007:感觉还没系统默认的好看
      • 孤单f北半球:为什么只更换了部分图标?难道需要重启一下?
        孤单f北半球:@Uri 诶奇怪啊,我明明关闭了SIP还是没用了,如果博主有时间的话测试一下哦,真的是非常喜欢博主的作品呢~ :+1:
        Uri:@孤单f北半球 对于OS X 10.11(El Capitan)以上的,有SIP保护,root也没权限替换系统App,关于如何关闭SIP在README里有说明。
        孤单f北半球:@孤单f北半球 @孤单f北半球 [*] Replace the thirdpart app icon ...
        [*] Replace the default system icon ...
        [*] - This is NOT support now
        [*] done
        第三步好像没执行成功?!
      • 十一岁的加重:的确好看多了
        Uri:@十一岁的加重 本君刚好在刷简书嘛=_=
        十一岁的加重: @Uri 回复的这么快,简书人气很旺啊
        Uri:@十一岁的加重 😁
      • Uri:@4cd329ce7967 呃,不一定会,这个我不确定也没试过
      • 4cd329ce7967:@Uri 如果系统升级后这些替换还会存在么?
      • Uri:@4cd329ce7967 亲测可以哟
      • 4cd329ce7967:10.10的能使用这个么?
      • Uri:@某寒归来 我把10.9的图标加到新的主题里面去了,你可以更新下哈 :relieved:
      • Uri:@yilufeng0 哈哈,之所以选这套扁平图标,就是感觉简洁明了浑然一体,比较合本人的胃口啦。 :grin:
      • yilufeng0:感觉处理后,各应用自己的独特风格就不是那么明显了
      • 某寒归来:@Uri 非常感谢!!! :heart:
      • Uri:@某寒归来 木有耶,我帮你找找哈,找到的话我会加到新的图标主题里。真找不到的话就只能从10.9的镜像里提取啦。
      • 某寒归来:博主有 10.9 系统的图标吗?找了好久。
      • Uri:@南栀倾寒 好的。各种欢迎提bug。
      • Uri:@南栀倾寒 能,-r 选项
      • Uri:@lifution 系统自带的都有,但是第三方App只覆盖了少数几个(以后尽量会提供更多的),目前在Themes文件夹你可以自己补充
      • 南栀倾寒:发现问题 如果我没有安装你安装的那些软件 中途会更换失败 你可以加个判断
      • 南栀倾寒:能还原不

      本文标题:Iconista——Mac下最炫酷的主题图标美化工具

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