把png转成ico的方法
如果你有个32×32的png图片,想转成ico,那就很简单了,直接:
|
1 |
convert x.png x.ico |
convert真的是简单地可怕啊~
当然,如果你是在windows下面,那你也可以用这个命令行工具.用法也有说明了,我就不多说了.
PS:以上方法也可以用于生成 favicon.ico
如果你有个32×32的png图片,想转成ico,那就很简单了,直接:
|
1 |
convert x.png x.ico |
convert真的是简单地可怕啊~
当然,如果你是在windows下面,那你也可以用这个命令行工具.用法也有说明了,我就不多说了.
PS:以上方法也可以用于生成 favicon.ico
序: 恩,这个确实挺折腾的,几乎一个下午都在搞py2exe,加上晚上又搞了一会儿,总算勉强让gmbox的exe可执行文件运行起来了…
首先,为什么要折腾py2exe呢? 其实就是为了那个gmbox,在设计之初,我就让它打算跨平台支持windows的.为此我也折腾过windows的python运行环境.但是如果那样的话,有windows的朋友要用gmbox,就必须安装python、GTK+库、PyCairo、PyGObject和PyGTK,这可不是一般的烦.所以有市场就会有需求,像我这样的问题我肯定不是第一个遇到的.于是就有了py2exe.
py2exe实际上是python distutils的一个扩展,使用py2exe,你必需有一个windows的环境,安装了python和你程序用到的依赖包(例如gmbox的pygtk等),也就是说,在这个”开发环境”你要能够运行起你的程序,然后下载py2exe,安装到python的lib目录下,就可以用来生成目标exe文件了,以后你只要把生成的东西复制到其他windows的机器,就可以脱离python运行环境和库的依赖了.是不是很爽呢?
虽说网上都说py2exe用起来很简单,但是我还是折腾了不少时间,可能是因为gmbox比较特殊:同时有CLI和GUI,有图标和数据文件,有自己的lib库等,当然更可能是因为我太菜了…嘿嘿..
不管怎么说,在这里记一下折腾的步骤,也许可以让后人少走点弯路:
当然,由于包含了一堆的运行环境,生成的dist目录将会是比较巨大的,现在的gmbox的exe居然有18M多,嘿嘿,应该还有优化和压缩的空间,改天再研究了~
写之前那篇blog的时候,我还是刚用上开源驱动.但是怎么试性能都上不去:
xorg.conf 也改了很多次,把 /etc/make.conf 里的 VIDEO_CARDS 改成 radeon 和 radeonhd 都试过,mesa xorg-server也来回编译过好几次,包括1.6的xorg-server,但是 glxgears 始终只有100FPS左右(fglrx的时候可以到2500+).而且,更可恶的是开compiz不是没边框就是直接白屏…
后来,查看 Xorg.0.log ,发现里面有这么几行:
|
1 2 3 4 5 6 7 |
drmOpenDevice: node name is /dev/dri/card0 drmOpenDevice: open result is -1, (No such device or address) drmOpenDevice: open result is -1, (No such device or address) drmOpenDevice: Open failed [drm] failed to load kernel module "radeon" (EE) RADEON(0): [dri] RADEONDRIGetVersion failed to open the DRM [dri] Disabling DRI. |
这种/dev/xxx的东西,马上就想到了是内核的原因,后面wd告诉我说要打开这个内核选项: Device Drivers -> Graphics support -> Direct Rendering Manager (XFree86 4.1.0 and higher DRI support) 并选中下面的A卡模块.
马上重新编译了内核,再启动,果然那几行错误没有了, glxgears 已经到 1100FPS 以上了.开compiz也正常了,整体感觉还是比较流畅的.
先就这样用着吧,不折腾了~目前我的情况是:
|
1 2 3 4 5 6 7 |
Mobility Radeon X1700 (RV535) VIDEO_CARDS="radeonhd" sys-kernel/gentoo-sources-2.6.30-r1 media-libs/mesa-7.4.2 x11-base/xorg-server-1.6.1.901-r3 x11-drivers/xf86-video-radeonhd-1.2.5 x11-wm/compiz-0.8.2-r2 |
之前我的A卡(Mobility Radeon X1700)一直都用得是闭源驱动,3D性能也还可以,glxgears可以跑到2500左右.
但是自从换上2.6.30的内核,fglrx就再也加载不成功了,不管是fglrx9.3还是9.5,都有问题,试了很多方法都没有成功,而且官方也已经把我的r535芯片归于”不支持”的行列了,ATI这么无情地把06年上市的卡给抛弃了,实在是让人气氛又无奈.
好在A卡还可以选择开源驱动,于是emerge了一个 xf86-video-ati ,倒是可以用了,但是glxgears只有100了…而且开compiz还是个白屏.可能是我的xorg.conf没有配置好吧,先睡觉了,明天再来配置…
前天介绍了linux进程间通信──消息队列,由于消息队列是linux内核提供的功能,所以理所当然地,C语言用起来最为方便:直接include一个sys/msg.h就可以了,所以之前的文章,我也是用C语言来做演示的.
那么我喜欢的Python能不能用IPC呢?能不能像C一样用消息队列呢?
其实,Python的内置模块里,并没有对IPC的支持,但是好在python的可扩展性超强,我们可以用swig来为python增加一个IPC模块.方法如下:
下载这个tar包(修改自这里),解压到任意目录,得到 ipc.h ipc.i Makefile 3个文件,如果你不是用的python2.6,需要修改一下 Makefile 里的路径(python3系列未测试).然后
|
1 |
make && make install |
这样,你就可以在python里 import ipc模块了.
还是贴示例代码,保存为ipc_msg.py,并加可执行权限:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
#!/usr/bin/env python import sys,ipc if len(sys.argv)==5 and sys.argv[3][0]=='s': ipc_key=int(sys.argv[1]) msg_id = ipc.msgget(ipc_key,0666|ipc.IPC_CREAT) if 0 > msg_id: sys.exit(1) mbuf = ipc.msgbuf() mbuf.mtype = int(sys.argv[2]) mbuf.mtext = sys.argv[4] if 0 > ipc.msgsnd(msg_id,mbuf,len(mbuf.mtext),0): sys.exit(3) print 'Send Success.' elif len(sys.argv)==4 and sys.argv[3][0]=='r': ipc_key=int(sys.argv[1]) mbuf = ipc.msgbuf() msg_id = ipc.msgget(ipc_key,0666) if 0 > msg_id: sys.exit(1) msg_len=ipc.msgrcv(msg_id,mbuf,2048,int(sys.argv[2]),ipc.IPC_NOWAIT) if 0 > msg_len: print 'No message received.' sys.exit(3) else: print 'Recv Success.(%d bytes):'% msg_len print mbuf.mtext elif len(sys.argv)==3 and sys.argv[2][0]=='c': ipc_key=int(sys.argv[1]) id_dsp = ipc.msqid_ds() msg_id = ipc.msgget(ipc_key,0666) if 0 > msg_id: sys.exit(1) if 0 > ipc.msgctl(msg_id,ipc.IPC_RMID,id_dsp): sys.exit(2) else: print "usage: \n%s key type s message --to send message\n\ %s key type r --to receive\n\ %s key c --to clear queue"\ %(sys.argv[0],sys.argv[0],sys.argv[0]) |
运行结果:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
lily@LLY:~/test/ipc$ ipcs -q ------ Message Queues -------- key msqid owner perms used-bytes messages lily@LLY:~/test/ipc$ ./ipc_msg.py 1 2 s abc Send Success. lily@LLY:~/test/ipc$ ipcs -q ------ Message Queues -------- key msqid owner perms used-bytes messages 0x00000001 65536 lily 666 3 1 lily@LLY:~/test/ipc$ ./ipc_msg.py 1 2 r Recv Success.(3 bytes): abc lily@LLY:~/test/ipc$ ipcs -q ------ Message Queues -------- key msqid owner perms used-bytes messages 0x00000001 65536 lily 666 0 0 lily@LLY:~/test/ipc$ ./ipc_msg.py 1 c lily@LLY:~/test/ipc$ ipcs -q ------ Message Queues -------- key msqid owner perms used-bytes messages lily@LLY:~/test/ipc$ |
怎么样?和之前的C语言版本一模一样吧?
昨天sync,发现有 sys-kernel/gentoo-sources-2.6.30 可用了,我没忍住,就升级上去了,其他的倒是没啥感觉,就是加载不了fglrx了…
虽然ati-drivers在我修改了一下ebuild以后,已经成功安装上去了,fglrx.ko也生成了,但是却加载不了,导致compiz不能用了.
modprobe fglrx的时候,提示:
FATAL: Error inserting fglrx (/lib/modules/2.6.30-gentoo-lly/video/fglrx.ko): Unknown symbol in module, or unknown parameter (see dmesg)
然后,dmesg里有这样两行:
fglrx: Unknown symbol flush_tlb_page
fglrx: Unknown symbol pci_enable_msi
应该是内核做了该动了.不知道有没有针对2.6.30的patch…不然,难道我要去用开源驱动了?
PS: 今天又发现了 sys-kernel/gentoo-sources-2.6.30-r1 orz…
linux自古以来就是一个多任务多用户的操作系统,所以linux的进程间通信(Inter-Process Communication──IPC)就显得非常重要了。
IPC是一种标准的Unix通讯机制,目前有以下几种通讯方式:管道(Pipe)、信号量(Semaphore)、互斥体(Mutex)、共享内存(Shared Memory)和消息队列(Message Queue),当然也有其他的方式,比如文件系统和dbus等。
今天我就来介绍一种简单实用的进程间通信方式:消息队列(Message Queue)。
首先说说消息队列的优缺点:
1.消息队列只适用于单台主机的进程间通信,如果是不同主机,需要用socket等其他方式,也就不属于IPC的范畴了。
2.消息队列可以实现异步通信,这似乎是优点,但说是它缺点也是可以的:通讯往往不是实时的。
3.消息队列有大小限制,通常只用于小数据量的发送。系统对用户的大小限制可以通过 ulimit -q 命令进行查询。
4.消息队列可以实现阻塞调用和非阻塞调用。
5.实现简单,且可移植性好。
下面通过一个实例来进行说明,以下文件保存成 ipc_msg.c:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/msg.h> int main(int argc, char *argv[]){ int ipc_key,msg_id,msg_len; long mtype; void * mbuf; if(argc==5 && argv[3][0]=='s'){ ipc_key=atoi(argv[1]); mtype=atol(argv[2]); msg_len=strlen(argv[4]); if ( 0>(msg_id=msgget(ipc_key, 0666|IPC_CREAT)))return 1; if ( NULL==(mbuf=malloc(msg_len+sizeof(long)+1)) )return 2; memcpy(mbuf, (void *)&mtype, sizeof(long) ); memcpy(mbuf+sizeof(long), (void *)argv[4], msg_len ); if ( 0>msgsnd(msg_id, (struct msgbuf *)mbuf, msg_len, 0) )return 3; printf("Send Success.n"); }else if(argc==4 && argv[3][0]=='r'){ ipc_key=atoi(argv[1]); mtype=atol(argv[2]); if ( 0>(msg_id=msgget(ipc_key, 0666)))return 1; if ( NULL==(mbuf=malloc(4096)) )return 2; if ( 0>(msg_len=msgrcv(msg_id,(struct msgbuf *)mbuf, 4000, mtype, IPC_NOWAIT))){ printf("No message received.n"); return 3; } printf("Recv Success.(%d bytes):n",msg_len); printf("%sn",(char *)(mbuf+sizeof(long))); }else if(argc==3 && argv[2][0]=='c'){ ipc_key=atoi(argv[1]); if ( 0>(msg_id=msgget(ipc_key, 0666)))return 1; if ( 0>msgctl(msg_id,IPC_RMID,(struct msqid_ds *)mbuf) )return 2; }else{ printf("usage:" "%s key type s message --to send messagen" "%s key type r --to receiven" "%s key c --to clear queuen" ,argv[0],argv[0],argv[0]); } return 0; } |
以上程序,实现了发数据到消息队列和从消息队列收取数据的功能。
第一个参数需要是一个整形数值,表示消息队列的Key;
第二个参数是一个长整形的数值,表示消息的Type,Key+Type 可以唯一确定一个先进先出的消息队列。
第三个参数如果是‘s’则把第四个参数发到指定消息队列,如果是‘r’则从指定消息队列收取消息,并打印。
另外,如果第二个参数是‘c’,则把Key对应的队列删除。
让我们来运行一下试试:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
$ gcc -o ipc_msg ipc_msg.c #编译 $ ipcs -q ------ Message Queues -------- key msqid owner perms used-bytes messages #一开始系统中没有消息队列。 $ ./ipc_msg 1 2 s abc Send Success. #发送了一个内容为abc的消息 $ ipcs -q ------ Message Queues -------- key msqid owner perms used-bytes messages 0x00000001 262144 lily 666 3 1 #发送了一个消息以后,队列里有消息了,key是1,有3个字节。 $ ./ipc_msg 1 2 r Recv Success.(3 bytes): abc #从消息队列成功收到消息了。 $ ipcs -q ------ Message Queues -------- key msqid owner perms used-bytes messages 0x00000001 262144 lily 666 0 0 #收完以后,空的消息队列仍然存在,不会自动消失。 $ ./ipc_msg 1 c #删除队列 $ ipcs -q ------ Message Queues -------- key msqid owner perms used-bytes messages #成功删除了,回到原始状态。 |
本文以GNU自由文档许可证发表.
lmgtfy 这几个字母放在一起,估计没几个人能看出是什么意思,其实它就是 Let me google it for you 的缩写.
http://lmgtfy.com/ 就是这样一个简单而好玩的网站: 比如,如果有人论坛里问 li2z 是什么?然后你不是很想回答,想让他自己去google,你就可以给他这个链接,相信他一看就会明白了,哈哈.当然你还可以用网站内置的tinyurl接口实现url的压缩等.
网站的主人显然是个web2.0爱好者,因此,你还可以follow网站的twitter,或者观看实时搜索直播不过..真的是实时的么?
几天前,据说微软要派人到我们公司查盗版系统(我就奇怪了,我们公司又不大,怎么就被盯上了呢?)…
哈哈,这对我倒是没啥大的影响,因为我平时都是用linux工作的.
但是我还是有装着个一个XP的,虽然很少用,基本上就是偶尔打几盘游戏.那我到底是删了XP还是留着呢?
干脆就让我来做个试验吧:我把XP的系统分区(NTFS格式)mount上,把windows目录和ntldr、NTDETECT.COM等记个文件都tar成了一个包…并删掉了,Documents and Setting和Program Files等几个目录换个名字.但是保留分区不动.
这样应该查不出的我windows了吧~
但是,几天过去了,也没看到微软的人来,看来又是忽悠忽悠咱老百姓的,今天我把那些文件都恢复了,tar包也解开,grub项加回去,再试着启动XP,居然还真能启动,哈哈~牛了~
不过有这么几个问题:
tar以后,删除再恢复的文件,丢失了 只读/隐藏 等属性.
tar完删除windows目录的时候,会有少数文件删不掉.可以mv改个名字,忽略掉.
这样以后的系统稳定性未知,没事还是别瞎试验了.
呃…在这个举国上下都非常紧张的敏感时期,很多博主(指目前还没被墙掉的博主)肯定都想说点啥而不敢说吧?
受lerosua之前用base64来写博文的启发,本文来探讨一个更加方便的加密方法.
lerosua的方法,缺点比较明显,就是对阅读者不够友好,linux用户还可以很方便地复制文字来base64 -d,win用户基本上都要打开一个在线解码base64的网站来解码了.于是我就想能不能把解码的功能放在同一个页面里,用户只需按一下按钮即可看到真实内容.
下面是演示:
点击查看全文 »