其实很多成功的互联网产品想法都源自于大家自身的生活,就拿我身边的例子来说吧。

在读书的时候,我也想过用 Excel 来记录一下自己读过哪些书、这些书的 ISDN 号、以及简单地记录一下自己的读后感,可是我为什么没有想到把它做成一个网站呢?做成一个网站供大家使用的话,就成了豆瓣了。

Reder it later 这个东西,也是大家肯定平时都有想到的。以前我看网页,感到某篇东西有点意思但是一时半会却没空看完的时候,就直接留在浏览器里不关闭;下次打开浏览器时再看,可是,却一直架不住经常调试程序的时候浏览器崩溃了,那些需要继续阅读的内容也找不回来了。类似我这种情况的人海了去了,可是,有几个人能想到做一个 Read It Later 这样的应用呢?

在以前自己每天坐公交车从琶洲过的时候,想到风景这么好,为什么不能每天拍一张天气图片保存下来、分享给别人看看呢?可是,我为什么没有想到多走一步,发动大家来把所有的天气图片收集起来实时分享,而这个功能,恰恰就是墨迹天气在做的事情。

类似的例子总是有很多,这也是为什么别人能成功的原因。生活中从来不缺乏需求,缺乏的是创造需求的能力,缺乏的是挖掘瞬间灵感的能力,以及缺乏那些行动起来把想法做出来的人。

(0) Comments    Read More   
Posted on 31-08-2013
Filed Under (技术) by waterlin

今天查了一下,自己的博客已经写了有五百多篇了,这里面的文章,大部分以技术内容为主,兼谈一些商业、文化上的看法,历时将近六年的积累。写博最初的目的,是想把自己碰到的技术细节记下来作为资料,以方便日后查阅,后来也陆续地写了一些零散的随笔。

自己的日常工作是搞开发,时间也蛮紧张的,业余时间也十分有限,那我是如何在繁忙的工作中,抽时间整理自己的观点写成博文呢?这篇就简单讲一下我自己写博客过程中素材收集、整理、加工的步骤与方法,并且简单说一下 org2blog 工具的使用方法。

第一步也是最重要的一步:如何积累写作素材

素材简而言之,就是你想说什么、你想写什么内容,类似于记者想要报道新闻时的选题。

素材的积累,没有什么捷径可走。平时看到什么感兴趣的,记下来;平时想到啥点子,记下来:《点子的形成》详细论述了这一环节的方法论。在这里,对于搞技术的,素材积累还有一个特定的环境,即你碰到一个需要解决的问题,在尝试解决过程中,你的解决思路与想法、查阅的资料、与别人的讨论,均可以作为素材记录下来。

素材的搜集,需要有一个好工具。传统的笔记方法,就是使用纸和笔,对文件进行标记,对一些想法记录下来。但是纸质的东西,容易丢失和遗忘,也不方便事后整理。就我个人来说,我喜欢用 Emacs 的 Org Mode 来搜集素材,新开一个主题,然后把所有找到的内容、材料往里一扔,不时的回去看一眼,提醒自己是否有遗忘、有没有新发现、有没有激发新的想法。对于技术内容写作者来说,使用一个电子化的素材整理工具,对工作效率会有大大的提高,尤其是在需要插入示例代码、数据、图表的时候,电子化的资料整理方式显得尤其方便。

第二步:如何让素材快速写成文并发布出去

积累素材到想法成熟的时候,就要开始进行文章编写。这个时候,我就喜欢用 Emacs 编辑器,谁叫这个是神用的编辑器呢?

最早以前我是先在 org mode 里把文章修改好,然后用命令 C-u M-x org-export-region-as-html 把这一段 org 语法标记的内容发布成 html 内容,然后通过其它的博客发布工具如 Zoudry 等发布到 WordPress 系统上。

可是,这样有几个问题:

  1. 在拷贝内容到 Zoundry 里时,无法同步拷贝图片,图片依然需要手动贴过去。我也有尝试过把图片放到一台图片服务器上,然后再在 org 文件里链接这个图片服务器的图片地址,可是试了几次后,就果断放弃了,这样实在是太麻烦。
  2. 该操作依然略显麻烦,并且还有 Zoundry 与 org 文件信息同步的问题,其它修改操作也比较麻烦,也不方便从 org 里追踪已经发布的信息,比如该博客地址、标签等。

所以,我希望是在 Org 里直接编辑好,一键发布,不用再使用额外的工具了。

终于,我找到了我理想的发布工具。用 org2blog 的 subtree 发布功能,刚好可以实现我的上述需求,从 Emacs 里维护 WordPress 博客。

org2blog 针对 Org 全文发布的几个简单命令:

  • M-x org2blog/wp-post-buffer ,发布当前 Org 文件为博客草稿,这个步骤还是很有必要的,发布成草稿后,再仔细检查一下你的文章写得有没有问题。
  • C-u M-x org2blog/wp-post-buffer ,把整篇文章发布成博客,即上一条命令是预览,而这条命令是正式发布。

如果只想把当前 Org 里的子条目(subtree)发布成博客,则可以使用下述命令:

  • M-x org2blog/wp-post-subtree 发布该条目成草稿,包括该条目下面的所有子条目。
  • C-u M-x org2blog/wp-post-subtree 把该条目发布成正式文章,包括该条目下面的所有子条目。
  • 当需要修改 WordPress 上已发布的文章时,直接编译该 Org 条目,然后重新使用上面的命令发布即可。

如果需要添加一个 tags 给这个博文,则需要在这个 subtree 上添加 tags,同时可以在 drawer 里设置好其它属性。

我喜欢把单个的文章都放到同一个 org 文件里来发布,每次只需要发布一条 * 的顶级条目即可。这样,避免在很多情况下,使用单个文件来存放一个文章,使得目录里的内容过于松散而造成不好管理的问题。

另外,当写了很多的笔记与文章后,这个文件就开始会变得很宠大了。这个时候,我就会再新建一个文件,又重零开始发布文章。也就是说,定期把过去写完的文件存档,修改为只读模式,这样就方便整理数据,避免不经意间的错误修改。

使用 org2blog 来写博客的好处就是,Wordpress 上有一个备份,你的本地电脑里也有一份原始数据的备份,并且这份数据是文本数据,你可以方便地转换成任何格式(如 PDF)。通过这种万能方式,除了可以很方便地保存数据,还可以用这些数据来进行再生产。

额外提示一下:在 M-x org2blog/wp-post-subtree 时,会登陆一个博客,当你写好了另一篇博客文章并需要发布到另外一个博客时,默认情况下,依然会是前一个博客的登陆状态。这个时候,你可以使用 M-x org2blog/wp-logout 来注销之前的登陆状态。

第三步(也是永远不会结束的一步),定期回顾

不管你使用何种方法整理素材,使用何种工具来发布博客,有一件事情,你一定要经常做的:定期回顾你已经写好的文章。你定期抽一点时间,来翻阅一下你之前写的文章,会得到很多的灵感,你会觉得某一些问题,原本应该讲得更清楚更透彻一些,有一些问题需要再补充一下最新的进展,甚至于有一些内容你可以形成一个系列文章,等等。

学无止境,如果能把你学到的东西完整、清晰的表述出来,那将是掌握了该内容的最佳表现。一个内容,如果你连说都说不清楚,你敢说你弄懂了吗?所以,尽量尝试着严谨地表达你的观点,这是一个让自己学习的过程,也是一个与别人分享的过程。

(1) Comment    Read More   
Posted on 31-08-2013
Filed Under (技术) by waterlin

在很多应用中,经常会直接把图片的二进制数据进行交换,比如说利用 socket 通信传送图片二进制数据,或者直接用内存数据库(例如 Redis)来传递图片二进制数据。

这个时候,当你的应用程序读到内存里的二进制图片数据时,怎么样直接转为 OpenCV 可以使用的图片格式呢,答案是用 cv::imdecode 这个函数:

std::vector<char> data(lpData, size);
cv::Mat image = cv::imdecode(cv::Mat(data), 1);

IplImage qImg;
qImg = IplImage(image); // cv::Mat -> IplImage

即先构造一个 char 字符串序列的 vector,用来存储图片的二进制数据,然后再转为 cv::Mat 成为可以被 cv::imdecode 使用的数据格式,然后直接类型转换为 IplImage 数据格式。

同样,如果你需要把 IplImage 或 cv::Mat 压缩并写到一段内存块里时,就需要使用 cv::imencode 这个函数,使用方法类似。

(0) Comments    Read More   
Posted on 31-08-2013
Filed Under (技术) by waterlin

如果你用 cvSaveImage 直接把 cv::Mat 数据保存为图片,则有可能有下列问题:

OpenCV Error: Bad argument (Unknown array type) in cvarrToMat, file /home/water/soft/OpenCV-2.3.1/modules/core/src/matrix.cpp, line 646
terminate called after throwing an instance of 'cv::Exception'
  what():  /home/water/soft/OpenCV-2.3.1/modules/core/src/matrix.cpp:646: error: (-5) Unknown array type in function cvarrToMat

这个时候,可以先把 cv::Mat 转为 IplImage 再用 cvSaveImage 来保存,直接用 IplImage 可以直接强制类型转 cv::Mat 为 IplImage 数据类型。

下面这段代码示例,是从硬盘里读取一个图片文件的二进制数据为 cv::Mat 数据结构,然后再转为 IplImage 数据结构并保存为新的图片文件。

const char* filename = "./testImages/12.jpg";

std::ifstream file(filename);
std::vector<char> data;

file >> std::noskipws;
std::copy(std::istream_iterator<char>(file), std::istream_iterator<char>(), std::back_inserter(data));


cv::Mat matrixJprg = cv::imdecode(cv::Mat(data), 1);
IplImage qImg;
qImg = IplImage(matrixJprg); // cv::Mat -> IplImage

cvSaveImage("./out.jpg", &qImg);

当然,其实还有更简单的方法:

cv::Mat image = GetImageBuff();//获取 cv::Mat 数据,根据实际业务编写
cv::imwrite("test.jpg", image);
(0) Comments    Read More   
Posted on 16-08-2013
Filed Under (技术) by waterlin

这两天在写 Qt 代码时,用 QPixmap 的 load 或是 loadFromData 方法来从图片文件里导入 Jpeg 图像数据,结果在 debug 版本下可以正确导入图像,可是在 release 版本下却没有办法导入图像。

这个时候,原因多半是 Qt 不支持这个图像格式,可以用下面的代码来检查当前的 Qt 版本支持的图像格式种类,并检查里面是否支持 JPEG 图像格式。

QString fileFormats = "";
/* Get all inputformats */
for (int i = 0; i < QImageReader::supportedImageFormats().count(); i++) {
        fileFormats += "*."; /* Insert wildcard */
        fileFormats
                        += QString(QImageReader::supportedImageFormats().at(i)).toLower(); /* Insert the format */
        fileFormats += " "; /* Insert a space */
}

从结果可以看出,当前的 Release 版本的确是不支持 Jpeg 图像格式。是由什么原因造成的这个现象呢?

这里情况比较特殊:并不是 Qt 不支持这个图像格式,而是需要在 release 版本里包括这个解码库。即把 qjpeg4.dll 链接库拷贝成 release 目录下的

imageformats/qjpeg4.dll

文件。你只需要让 Release 版本的可执行文件,可以正确找到该编码库链接库即可。请注意当你打包成安装文件进行安装时,一定要注意把该链接库安装到目录 imageformats 下,否则依然无法正确使用。

类似的问题,同样会存在于字符集编码等其它插件里:当你使用了指定的字符集编码时,则同样需要打包类似的库。例如,对于简体中文来说,需要把 qcncodecs4.dll 打包安装成

/codecs/qcncodecs4.dll

文件。

(0) Comments    Read More   
Posted on 16-08-2013
Filed Under (文化) by waterlin

最近得益于多看电子书的大力发展,可以在 Kindle 上看类似《激荡三十年》这些好书了。随身带着一本 Kindle,想看啥就看啥,坐地铁或是等人的时候,都可以拿出来翻翻。

再简单说说看完《激荡三十年》的感受吧,用一句话来形容,就是多么苦逼的民营企业!这里的民营企业,不是狭义的民营企业,还包括一些非垄断的国有企业、集体经济实体,这些团体从本质上来说,和民营企业并没有太大区别。这些实体经济在创业的过程中,并没有得到太多政策上的眷顾,而是被政府采取自生自灭的态势,但是一旦企业创业成功走在了通往胜利的道路上时,上级主管部门或是税务部门或是工商部门或是质检部门或是某个部门,就开始就来管你关注你,目的是啥,就是看你赚钱了眼红要来分一笔。

从古到今,商人在中国的地位就显得比较弱势。在古代,重农抑商,导致了严重的官本位思想,商人的地位和官老爷比起来,显得更差。之所以清代捐官盛行,有钱人捐官图的啥,就是图个和官老爷能略微平起平坐的权利。在当今中国,在私有财产并没有清晰保护的前提下,商人要赚到钱,需要突破的困难并不比古代少,需要捕捉商机、需要在自由竞争的环境里搏杀出头;成为业内领头羊后,还需要小心翼翼地款待政府相关部门,否则政府态度来个一百八度大转弯,你就前功尽弃了。枪在别人手上,要管你还不简单?

联想到之前广东总工会出的通知,企业需要上缴工资总额的2%作为工会费用,真是替这些没爹又没娘的民营企业叫苦。政府说要怎么收你的税就收你的税,其它的部门还可以随意就发布公告说要交这钱那钱的,所有的政策都没有一个论证与讨论的过程(就算有程序上的合法性,你也懂的,中国特色的过场)。或许,我可以把这个特色,归结为中国有钱人没有太多社会责任感的一个原因了。就这样,你叫这些人怎么爱国?你叫这些老百姓怎么爱国?就这样的环境,你让这些商人如何安心投钱长线投资产业升级知识强国,你如何让商人抛却不安全感而把财富留在这里?

纵观任何国家的历史,都是一部经济与权力斗争的历史,而在中国持续到现在的几千年里,无疑是绝对的权力占了上风!在中国,不跟着党走搞自己的产业,也许就是一条不归路~~

(0) Comments    Read More   
Posted on 16-08-2013
Filed Under (文化) by waterlin

这段时间,网上有一件热议的事情:广东省总工会表示,工会经费要统一实行地税代收,缴费单位按上月全部职工工资总额的2%计算缴交工会经费。

广东省总工会和广东省地方税务局在7月17日共同下发的《关于工会经费的公告》(下称《公告》)称,“为规范和加强工会经费收缴管理,维护职工合法权益”,根据《广东省工会经费收缴管理暂行办法》,从2013年7月起,广东省总工会经费(含工会建会筹备金)统一实行地税代收。

我算一个码农,也就是一个工人,这事也算和我密切相关,不得不说一说自己的看法。

这个政策的解读,有两个重点。第一个是工资总额的2%作为工会经费上缴,第二个是由地税代收。

第一个解读,作为工资总额的2%,数目多不多?这些钱收起来去干什么?所有这些,都没有听到广东省总工会的一个合法说法。工资总额的2%不少了,由老板出,老板心疼企业负担加重;由员工出,员工愿意么?

肯定有人会说,这钱反正是公司出,和工人没关系。你也不想想,企业的盈利总额就那么多,交给政府的多了,给员工的自然就少了,老板不可能自己少赚一点帮你交工会会费吧?这钱肯定还是羊毛出在羊身上,吃亏的还是工人自己。

第二个解读,由地税代收。据报道,这笔工会费是与公司的报税捆绑在一起的。这意味着,倘若公司没有缴纳工会费,将无法在缴税上进行申报。我不知道以前是不是也有缴纳工会会费,估计之前也有要收,只是因为总工会的权力有限,很难从企业收上这一笔钱来;现在由地税代收,收缴力度加大,看你还敢不交么?流氓并不可怕,可怕的是流氓盯上你了。由地税代收,在我看来,可以简单直接粗暴地划一个等号:广东省的个人所得税增加了2%。

退一步说,就算工会真有为员工谋福利,这笔钱交了也值了。可是,红十字会的前车在这里,你能保证这钱花的用途和收的用途能对得上?

工会真要想给工人谋福利,就要允许这钱有交和不交的自由。如果我不要工会的保护,能否不交这笔钱了?如果不管良民们愿意不愿意,都强制要你交工会会费,这和黑社会收取保护费有啥区别?

再说个题外话:从广东收工会会费这事看得出,政府想收钱的时候,直接出一个通告就可以了,7月出8月就可以收钱了,也不用提交人大审批财政审批政府审批。可是天天吵着说要取消社保医保双轨制、机关事业企业平等,结果改革、反复研究、讨论了5年,还没有一点进展。你说,政府是有效率还是没效率呢?

(0) Comments    Read More