页面

2009/05/11

DIY 一个用于生成桌面墙纸的“网络相机”

en 写了一个 python 脚本——WebCam,区区百十行代码,实现了从网络或本地目录抓取多幅图片并随机拼合到一起,所生成的图片可以作为漂亮的桌面墙纸。这个脚本程序虽然不是非常智能,但是它可以作为一个 python 编程示例供初学者借鉴。您也可以尝试做一个 Lua 或 Ruby 版本

这个脚本的全部代码如下:

#! /usr/bin/env python

# Copyright 2009 by Benjamin Fogle
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .

import sys
import os
import os.path
import urllib2
import tempfile
import math

# Constants. Change these to customize the script
# In ksh: CONFIG_FILE=$HOME/lectures/examples/LEC-05/webcam_config
CONFIG_FILE=os.getenv('HOME') + '/.webcam_config'
TARGET=os.getenv('HOME') + '/Pictures/Wallpapers/webcam.jpg'
SCREEN_X = 1024
SCREEN_Y = 768

def GetTiles(num_images):
"""Returns a tuple (N,M) representing the tile grid"""
# This algorithm could be much improved
tile = math.ceil(math.sqrt(N))
return (tile, tile)

def GetImageSize(N, M):
"""Returns a the max size of each image based on the screen size
and the tile grid"
""
global SCREEN_X
global SCREEN_Y
ImgX = SCREEN_X / N
ImgY = SCREEN_Y / M
return (ImgX, ImgY)

def CopyFile(src_fp, dest_fp):
"""Copy a file intelligently"""
data = src_fp.read(49152) # Copy 48k at a time
while data:
dest_fp.write(data)
data = src_fp.read(49152)
# Note: shutils.copyfileobj does this too.

if len(sys.argv) != 1:
print "Usage: %s" % (sys.argv[0])
print
print "Config file is located in %s" % CONFIG_FILE
sys.exit(1)

# Make sure the config file is readable and that it is a regular file
# There is a better way to do this that we will learn later.
if not os.access(CONFIG_FILE, os.R_OK) or not os.path.isfile(CONFIG_FILE):
print "Error: %s could not be opened!" % CONFIG_FILE
sys.exit(2)

urls = [] # Url to download from. Read from config file
captions = [] # Captions for each image. Read from config file
filenames = [] # Temporary file names

config_fp = open(CONFIG_FILE, 'r')
line = config_fp.readline()
N=0
while line:
params = line.split(":::")
urls.append(params[0].strip())
captions.append(params[1].strip())
line = config_fp.readline()
N+=1
config_fp.close()


# Download each url. This is how to iterate over mutliple lists at once
for url, caption in zip(urls, captions):
url_fp = urllib2.urlopen(url)
# The following two lines are the preffered way to open a temporary
# file.
fd, name = tempfile.mkstemp()
img_fp = os.fdopen(fd, 'w')
filenames.append(name)
CopyFile(url_fp, img_fp)
url_fp.close()
img_fp.close() # The data won't appear in img_fp until it's closed
# Use the ImageMagick suite from the shell to add a caption
os.system("convert '%s' -set comment '%s' '%s'" % \
(name, caption, name))

# Figure out the parameters
tilex, tiley = GetTiles(N)
imgx, imgy = GetImageSize(tilex, tiley)

# Use ImageMagick again to assemble the wallpaper
cmd = "montage -geometry %dx%d \
-tile %dx%d \
-set caption '%%c' \
-pointsize 32 \
-size %dx%d \
-texture plasma: \
+polaroid \
-background black "
% (imgx, imgy, tilex, tiley,
SCREEN_X, SCREEN_Y)

# Add each image file to the command string
for filename in filenames:
cmd += '"%s" ' % filename

# Add the output file to the command string and execute
cmd += TARGET
os.system(cmd)

# Cleanup
for filename in filenames:
os.unlink(filename) # In ksh: rm $filename

要运行该脚本,需要您的系统中已经安装 imagemagick(一般 GNU/Linux 会默认为您安装该软件包)。

首先将上述代码复制到 webcam 文件并保存;然后,为该文件的添加可执行权限:

$ chmod +x webcam

在使用该脚本之前,需要将所要获取图片的地址信息写入 .webcam_config 文件,例如:

$ nbsp;nbsp;nbsp;nbsp;echo "file:///home/garfileo/Winter.jpg ::: 冬天" >> $HOME/.webcam_config
$ echo "http://www.51766.com/bbs/photo/1127887493353.jpg ::: 昌平∙白虎涧" >>$HOME/.webcam_config
$ echo "http://tw.mjjq.com/pic/20070530/20070530043314558.jpg ::: 赤水" >>$HOME/.webcam_config
$ echo "file:///home/garfileo/MY-Moutain.jpg ::: 明月山" >> $HOME/.webcam_config

然后,只需要执行 webcam 脚本,便可以在 $HOME/Pictures/Wallpapers 目录(若无该目录,请自行创建)中生成合成图片。上面向 .webcam_config 文件写入的四幅图地址,第一幅与第四幅图位于我的本地目录,而其它两幅均来自网络。每幅图片的地址后面均尾随 ":::" 符号,它是用来间隔图片地址与图片标签名的。这些图片的合成效果如下:

按照上述步骤正确操作,最终可以得到合成图片。不过,如果图片标签名是中文的话,那么最终的合成图中每幅小图的标签应该是一串问号或乱码。这是因为 webcam 脚本是通过调用 imagemagick 图片处理工具箱中的 montage 程序实现图片合成的,如果在图片中使用了中文标签名,那么需要设定中文字体方能在合成图中正确显示中文。要解决这个问题,需要在 webcam 脚本中找到以下代码段:

...... ......

# Use ImageMagick again to assemble the wallpaper

cmd = "montage -geometry %dx%d \
-tile %dx%d \
-set caption '%%c' \
-pointsize 32 \
...... ......

然后在其中添加字体设置代码:

...... ......

# Use ImageMagick again to assemble the wallpaper
cmd = "montage -geometry %dx%d \
-font /usr/share/fonts/winfonts/msyh.ttf \
-tile %dx%d \
-set caption '%%c' \
-pointsize 32 \
...... ......

这样,这个问题便解决了。

来自:http://www.linuxgem.org/posts/8167

没有评论:

发表评论