用 Face.com API 处理肖像照

之前某天, 我接了个任务: 把用户上传的照片(全身或者半身照)做处理, 输出一张从头到肩的肖像. 一开始我觉得很难, 因为高等数学什么的早就还给老师了. 但后来一想, “Not to re-invent the wheel”, 找个现成的脸部识别 API 不就可以了吗.

于是开始 Google “face detection”. 结果之中, 来自 face.com 的 API 帮我搞定了这个任务. 顺便把一个批处理的 ruby 程序贴上, 尽管写的很丑.

require 'rubygems'
require 'net/http'
require 'rest_client'
require 'json'

ratio = 2.0
photos = Dir.glob File.join("photos", "*.jpg")
photos.each { |photo| puts photo

    res = RestClient.post( 'http://api.face.com/faces/detect.json',
      :api_key => 'your api key',
      :api_secret => 'your api secret',
      :filename => File.new(photo, 'rb')
    )
    filename = File.basename(photo)
    dirname = File.dirname(photo)
    thumb_name = dirname + '/thumbs/100x120_' + filename
    #puts res
    result = JSON.parse res
    #puts result['status']
    if result['status'] == 'success'
        width = result['photos'][0]['width']
        height = result['photos'][0]['height']
        tag_width = (result['photos'][0]['tags'][0]['width'] * width / 100).to_i
        center_x = (result['photos'][0]['tags'][0]['center']['x'] * width / 100).to_i
        center_y = (result['photos'][0]['tags'][0]['center']['y'] * height / 100).to_i
        portrait_left = ( center_x - ( tag_width / 2 * ratio )).to_i
        portrait_left = 0 if portrait_left < 0
        portrait_top = ( center_y - ( tag_width / 2 * ratio )).to_i
        portrait_top = 0 if portrait_top < 0
        portrait_width = ( tag_width * ratio ).to_i
        portrait_height = ( portrait_width * 1.2 ).to_i
        puts portrait_left, portrait_top, portrait_width, portrait_height

        `convert -crop '#{portrait_width}x#{portrait_height}+#{portrait_left}+#{portrait_top}' -resize '100x120' '#{photo}' '#{thumb_name}'`
    end
}

处理结果:

另外还有个传闻: facebook.com 要收购 face.com. 我心里想, 那把 book.com 也收了吧? 😀

一键完成淘宝/Ebay商品图片的批量制作

参考链接: http://www.imagemagick.org/script/command-line-processing.php#geometry
相关文章: http://raynix.info/archives/1098
前提, Linux环境, Gnome桌面, 支持 Nautilus Shell Script, 安装了 ImageMagick.

貌似Ebay和淘宝一样, 商品图片都是要正方形的. 虽然有很多图片工具可以批量处理图片, 我还是喜欢直接在 Nautilus 文件管理器里面通过多选+右键一次完成商品图片的处理. 对于没耐心的朋友, 请直接把下面的代码另存为 ~/.gnome2/nautilus-scripts/your-script-name.sh 并给与运行权限, 就可以了.

#!/bin/bash
#Multiple selection support!
for param in "$@"
do
	#Check if it's a file
	if [ -f "$param" ]
	then

		#get directory
		dir=`dirname "$param"`
		filename=`basename "$param" '.jpg'`
		#Check if it's a jpg or jpeg file
		if echo $param |grep -E -q -i "\.jpg|jpeg|gif|png$"
		then
			convert -resize '1024x1024^' -crop '1024x1024-0+0' -gravity Center \
			-font Arial -pointsize 28 \
			-draw "fill black text 350,450 'raynix 2012' \
			fill white text 348,448 'raynix 2012'" \
			"$param" "$dir/1kpx-sqr-$filename.jpg"
		else
			continue
		fi
	else
		echo "Is this an image?"
	fi
done

简要解释一下:

  • -resize ‘1024×1024^’ 是按照较短的一边对图片进行等比例缩放, 当然, 照片一般都很大, 所以大多数情况下应该是等比例缩小, 让较小的一边缩小到1024px. 这样对于横拍或者竖拍的照片就都有效了.
  • -crop ‘1024×1024-0+0’ -gravity Center 作用是在图片中心切出 1024x1024px 的正方形区域
  • 其它部分就是加签名和生成新文件名了, 不是必须的.

示例原图以及生成图:

利用Gnome Shell Script一键缩图, MKII

对于初作的升级, 现在缩图脚本支持多选择了: 在文件管理器当中选择多个图片, 点击右键, 在Scripts下选择执行脚本就可以了!

附脚本:

#!/bin/bash
#Multiple selection support!
for param in "$@"
do
	#Check if it's a file
	if [ -f "$param" ]
	then

		#get directory
		dir=`dirname "$param"`
		#Check if it's a jpg or jpeg file
		if echo $param |grep -q ".jpg" || echo $param |grep -q ".jpeg" || echo $param |grep -q ".gif" || echo $param |grep -q ".png"
		then
			convert -resize 1024x1024 "$param" "$dir/1024px-$param"
		else
			continue
		fi
	else
		echo "Is this an image?"
	fi
done

[email protected], 其实是把全部参数作为一个list来使用的, 非常方便. 😀

UPDATE1: 用regexp重写一下扩展名判断部分
regexp参考链接: Regular Expressions In grep

#!/bin/bash
#Multiple selection support!
for param in "$@"
do
	#Check if it's a file
	if [ -f "$param" ]
	then

		#get directory
		dir=`dirname "$param"`
		#Check if it's a jpg or jpeg file
		if echo $param |grep -E -q "\.jpg|jpeg|png|gif$"
		then
			convert -resize 1024x1024 "$param" "$dir/1024px-$param"
		else
			continue
		fi
	else
		echo "Is this an image?"
	fi
done