Make YUNIO Your Git Repo

http://www.yun.io/ 一个云存储同步空间,有Mac的客户端,虽然是QT写的,但是功能还OK。
可以将云存储空间挂载到本地的一个目录。
这些云存储空间其实可以用来作为自己的远程Git仓库

1
2
3
4
5
6
7
8
#在YUNIO的目录中创建一个bare的git库,作为远程git库
cd /Users/Luke/YUNIO/Projects/
mkdir bookhelper.git
cd bookhelper.git/
git init --bare
#在原项目的本地git库中添加远程仓库,并提交
git remote add yunio /Users/Luke/YUNIO/Projects/bookhelper.git
git push yunio master

iPhone中Png图片格式的研究

有时候我们看到一个App,想看看他的一些界面是如何实现的,这个时候需要查看一下它的图片资源,不过iOS的png图片编译后一般的图片阅读器都是没法查看的,本文将告诉的原因和转换出原图的方法(得安装XCode)。

ipa 解压,将png相关文件夹拷贝出来,在命令行下使用/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/pngcrush -revert-iphone-optimizations xxx.png yyy.png

我们都知道一个编译好的iPhone app 其中的png图片一般普通的图片阅读器是无法直接读取的,这是因为XCode在编译的过程中,将图片进行了优化,实际上它已经不是一个png图片了。
这边有一些apple iPhone png自己格式的一些说明
http://iphonedevwiki.net/index.php/CgBI_file_format

在Png数据中,我们最关心的莫过于png的数据块,其中包含了png每一个像素的信息,当然了为了减少存储空间,这些像素信息都是压缩保存的。而且是使用zlib进行压缩的,压缩后 包含zlib header 信息,还有由于解压验证的crc信息。
而iPhone的CgBI格式的png则将原始的png图片作如下变化:

  1. 增加一个新的关键块 CgBI Chunk 四个字节
  2. zlib的header和CRC信息全部从IDAT中移除
  3. 红蓝交换,每一个像素(RGBA)中的R和B进行调换变成BGRA ,解压后每一个像素有四个字节组成,也就是将每一个像素的 第一个字节和第三个字节调换
  4. 透明像素处理 Premultiplied Alpha ,这个的意思是为了图像加载变得更快,预先将Alpha的信息乘到像素的颜色信息中去,这样后期计算的时候就可以减少CPU或者GPU计算了

把一个正常的PNG图片优化成iPhone 的png图片格式可以使用XCode自带的工具 /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/pngcrush -iphone
还有一个第三方的开源工具也可以
https://github.com/DHowett/pincrush

如果你想把一个经过优化后的图片还原成普通图片阅读器可以查看的png图片,就是对上面的过程进行反向处理。
现在可以找到的第三方的转换的一般有如下几个
ipin.py(Python版本) http://www.axelbrz.com.ar/?mod=iphone-png-images-normalizer
iPhonePNG(C版本) http://www.newsfirerss.com/blog/?p=176

经过本人测试,上面的这种第三方的额转换工具都没有对alpha相关的做任何处理,也可以是别的原因,有一些图片转换后的结果和原始图片还是有些出入的。
原图(Flip Board中的一个按钮背景图):

编译后如果使用第三方的python或者C版本的代码来转换,转换后的图片都是这样的,感觉边角的像素有点问题,不过大部分情况下 ,图片都是ok的

我尝试通过修改第三方的代码,想将Premultiplied Alpha 还原过去,但是还是存在各种问题,最终没有结果。
只能最终采用XCode自带的工具进行转换 /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/pngcrush -revert-iphone-optimizations 1.png 2.png
这个pngcrush是apple改自开源的pngcrush 只可惜苹果修改后的版本却没有开源出来。

为了避免每次都需要在命令行中进行操作,你可以通过automator新建一个shell的service

1
2
3
4
5
6
for path in "$@"
do
mv "$path" "$path".tmp
/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/pngcrush -revert-iphone-optimizations "$path".tmp "$path"
rm "$path".tmp
done

当然你可以修改脚本,并可以作用于文件和文件夹,对目标进行判断,文件夹则递归文件夹中的png文件进行逐个处理。

SWATCH 计时器的使用

一般Swatch手表的计时都是采用所谓的三针计时方式:一个是秒针,一个是分针,另外一个是1/10秒针,当开始计时时,秒针开始计时,走到一圈时即是一分,分针就计为1分,当终止计时时,1/10秒针计算的是1/10秒的时间。所以三针计时方式可以精确到1/10秒。

今天刚拿到上图中的这块表,完全搞不定如何计时。最大的误解就在于那个最长的秒针。尼玛这个最长的秒针不是手表本身的秒针,而是计时的秒针的啊,这完全违反一般的认识啊!!!! 而下方的小圆盘中的不停走动的秒针才是表的正真的秒针啊!!!

左上方是用于计分钟的,一格是一分,右上方是记1/10秒的,一格是1/10秒。而中间的这个最大的秒针是计时用的秒针。
表的右侧有三个功能按钮,在计时归零的状态下,按一下最上方的按钮,最大的秒针开始走动,代表开始计时,再按一下暂停计时,这个时候,1/10秒的地方就会显示对应的10分之几秒,然后再按上方的按钮则继续计时,再按暂停计时。在暂停的时候按下下方的按钮,则进行计时归零。如果归零有偏位,则可以通过拔开中间的按钮一档,然后按上方或者下方的按钮进行秒针和1/10秒的归零位置调整。

说实话,swatch计时功能使用最大的障碍就是使用最大的秒针来作为计时用的秒针(而一般人的认识中这个大指针是表的秒针)。

浅谈Runloop

还记得以前用C写p2p聊天程序的时候,都会写一个循环,不断的去侦听某个端口是否有消息,如果有则接受处理,或者监测着缓冲区是否有数据,如果有则发送出去。 也就是说,这种程序不是运行一次就可以关闭了,而是需要一直运行下去的。这样的程序有web容器,桌面程序等待。 其实Runloop就是这种循环的抽象,用来管理代码的执行。在线程的Runloop中,只有执行完当前的任务后,才可以等待执行下一个任务。

把一个公司比作一个运行着的程序(进程),每一个人都是一个线程,你就在循环的运行着,每天处理着事件。
需要处理的任务数较多,就会进去你的任务队列,一个个的按次序做完,有时候你做完了就空闲了,处于等待状态。
1.你的老板会指派一些任务给你做,这个便是线程之间的消息传递。
2.有一些任务可能是定时的,每隔一定的时间你就需要做一下,当然有时候可能某一个定时任务的时间点到了,但是你的手头上正在处理另一个事情,这个时候可能需要等这个事情处理完了在处理定时任务了。所以在Cocoa中Timer的定时执行并不能保证实时。