デジタルフォトフレームを簡易モニターとして使う(美女暦+天気予報)


前回美女暦をフォトフ レームに表示する方法を紹介しました。
そこで、今回は、美女暦に天気予報を追加して表示する方法を紹介します。

【STEP1】パッケージのインストール

前回までのパッケージに加え、以下のパッケージをインストールします。

$ sudo apt-get install python-imaging
$ sudo apt-get install python-scipy

【STEP2】pythonスクリプト

使用するスクリプトは以下のとおりです。
getDominantColor()関数で配色全体の印象を支配する色(ドミナントカラー)を求め、それによって フォントの色を決めていますが
手間が掛かった割りに、うまくいっていないです。
地域コードは名古屋(230010)になっています。
このページで地域を選ぶと 「http://weather.livedoor.com/area/forecast/XXXXXX」のURLが表示されるので
最後の数字6桁が地域コードです。

#! /usr/bin/env python
# -*- coding:utf-8 -*-
import os
import sys
import shutil
import json
import urllib3
import csv
import subprocess
import fnmatch
import datetime
import struct
import Image
import scipy
import scipy.misc
import scipy.cluster

NUM_CLUSTERS = 5

def getDominantColor(image):
#    print 'reading image'
#    im = Image.open('image.jpg')
#    im = Image.open('/tmp/image01.jpg')
    im = Image.open(image)
    im = im.resize((150, 150))      # optional, to reduce time
    ar = scipy.misc.fromimage(im)
    shape = ar.shape
    ar = ar.reshape(scipy.product(shape[:2]), shape[2])

#    print 'finding clusters'
    codes, dist = scipy.cluster.vq.kmeans(ar, NUM_CLUSTERS)
#    print 'cluster centres:\n', codes

    vecs, dist = scipy.cluster.vq.vq(ar, codes)         # assign codes
    counts, bins = scipy.histogram(vecs, len(codes))    # count occurrences

    index_max = scipy.argmax(counts)                    # find most frequent
    peak = codes[index_max]
    colour = ''.join(chr(c) for c in peak).encode('hex')
#    print 'most frequent is %s (#%s)' % (peak, colour)
    return peak.tolist()

def makeRGB(code):
    return 'rgb({0:d},{1:d},{2:d})'.format(code[0],code[1],code[2])

def delImages( path ):
#    print fnmatch.filter(os.listdir(path), 'image*.jpg')
    flist=fnmatch.filter(os.listdir(path), 'image*.jpg')
#    print len(flist)
    for file in flist :
        delfile = path + "/" + file
#        print 'delImages>'+delfile
        os.remove(delfile)

if __name__ == '__main__':
    CurDir=sys.argv[0]
#    print 'CurDir>'+CurDir
    DirName=os.path.dirname(CurDir)
#    print 'DirName>'+DirName
    if not DirName:
        DirName="."
    shell_file=DirName+"/convert.sh"
#    print 'shell_file>'+shell_file
    csv_file='/tmp/param.csv'

#天気情報取得
    city='230010' # 名古屋
#    city='130010' # 東京
#    city='270000' # 大阪
    url = 'http://weather.livedoor.com/forecast/webservice/json/v1?city={0:s}'.format(city)
    http = urllib3.PoolManager()
    resp = http.request('GET', url)
    data = json.loads(resp.data.decode('utf-8'))
#    print data
#   print(json.dumps(data, sort_keys=True, indent=4))

#日付と地域
#    print(data['publicTime'][0:10])
#    print(data['title'])
    csv0=data['publicTime'][0:10]
    csv0=csv0+' '+data['title']

#今日の天気
#    print(data['forecasts'][0]['dateLabel'])
#    print(data['forecasts'][0]['telop'])
    csv1=data['forecasts'][0]['dateLabel']
    csv1=csv1+' '+data['forecasts'][0]['telop']

#明日の天気
#    print(data['forecasts'][1]['dateLabel'])
#    print(data['forecasts'][1]['telop'])
    csv2=data['forecasts'][1]['dateLabel']
    csv2=csv2+' '+data['forecasts'][1]['telop']

#明後日の天気(無い時がある)
    wk1 = datetime.datetime.now() + datetime.timedelta(days=+2)
    wk2 = '%s' % ( wk1.strftime( '%Y-%m-%d' ) )
#    print 'wk2>'+wk2
    if wk2 in json.dumps(data, sort_keys=True, indent=4):
#        print(data['forecasts'][2]['dateLabel'])
#        print(data['forecasts'][2]['telop'])
        csv3=data['forecasts'][2]['dateLabel']
        csv3=csv3+' '+data['forecasts'][2]['telop']
    else:
        csv3=" "

#CSVファイル作成
    fd=open(csv_file,'w')
    writer = csv.writer(fd)
    csvdata=[csv0.encode('utf-8'),csv1.encode('utf-8'),csv2.encode('utf-8'),csv3.encode('utf-8')]
    writer.writerow(csvdata)
    fd.close()

    in_path="/tmp"
    out_path="/tmp/out"
    if not os.path.exists(out_path):
        os.mkdir(out_path)
    else:
        delImages(out_path)

#イメージ処理開始
#    print fnmatch.filter(os.listdir(in_path), 'image*.jpg')
    flist=fnmatch.filter(os.listdir(in_path), 'image*.jpg')
    for file in flist :
        in_file = in_path + "/" + file
#        print 'in_file>'+in_file
        out_file = out_path + "/" + file
#        print 'out_file>'+out_file
#
#イメージの近似色を求める
        args=['convert','-crop','1500x400+50+50',in_file,out_file]
        subprocess.call(args)
        dominant=getDominantColor(out_file)
#        print 'out_file dominant>'+str(dominant)
       
#フォントの色を決定
        maxpos=max(enumerate(dominant), key=lambda dominant: dominant[1])[0]
#        print maxpos
        fill_color='rgb(255,255,255)' #white
        if dominant[0]>100 and dominant[1]>100 and dominant[2]>100:
            fill_color='rgb(0,0,0)' #black
        elif maxpos==0 and dominant[maxpos]>60:
            fill_color='rgb(0,255,255)' #cyan
        elif maxpos==1 and dominant[maxpos]>60:
            fill_color='rgb(255,0,0)' #red
        elif maxpos==2 and dominant[maxpos]>60:
            fill_color='rgb(255,0,255)' #pink

#フォントの色を固定色にする場合はこちらを有効にする
#        fill_color='rgb(0,0,0)' #black
#        fill_color='rgb(255,255,255)' #white

#文字編集
#        print 'in_file>'+in_file
#        print 'out_file>'+out_file
#        print 'fill_color>'+fill_color
        args=[shell_file,csv_file,in_file,out_file,fill_color]
        subprocess.call(args)

上記スクリプトの最後で、subprocess.call(args)により、以下のスクリプト(convert.sh)を呼び出しています。
フォント名(/usr/share/fonts/truetype/kochi/kochi-mincho.ttf) は適当に変更してください。

#!/bin/bash
if [ $# -lt 4 ]; then
    echo "USAGE:${0} param_file input_file output_file fill_color"
    exit
fi

ParamFile=$1
#echo "ParamFile="${ParamFile}
InputFile=$2
#echo "InputFile="${InputFile}
OutputFile=$3
#echo "OutputFile="${OutputFile}
FillColor=$4
#echo "FillColor="${FillColor}

#Read Parameter File
col0=`cat ${ParamFile} | cut -d , -f 1`
col1=`cat ${ParamFile} | cut -d , -f 2`
col2=`cat ${ParamFile} | cut -d , -f 3`
col3=`cat ${ParamFile} | cut -d , -f 4`
#echo ${col0}","${col1}","${col2}","${col3}

#Text Insert to Jpeg File
convert -font /usr/share/fonts/truetype/kochi/kochi-mincho.ttf -pointsize 60 -fill $FillColor -draw "text 100,100 '${col0}'" $InputFile $OutputFile

convert -font /usr/share/fonts/truetype/kochi/kochi-mincho.ttf -pointsize 60 -fill $FillColor -draw "text 100,200 '${col1}'" $OutputFile $OutputFile

convert -font /usr/share/fonts/truetype/kochi/kochi-mincho.ttf -pointsize 60 -fill $FillColor -draw "text 100,300 '${col2}'" $OutputFile $OutputFile

convert -font /usr/share/fonts/truetype/kochi/kochi-mincho.ttf -pointsize 60 -fill $FillColor -draw "text 100,400 '${col3}'" $OutputFile $OutputFile


【STEP3】pythonスクリプトの実行

上記のスクリプトを「ConvertImages.py」の名前で保存し、前回のスクリプトに続けて実行てください。

$ python /home/pi/bijyo/SaveImages.py
$ python /home/pi/bijyo/ConvertImages.py

イメージファイルが「/tmp/out/image***.jpg」に保存されます。
保存されたイメージファイルをフォトフレーム側にダウンロードしてやれば、フォトフレームに天気予報付きの美女暦を表示することができます。

フォトフレームへの表示は以下の様になります。







【STEP4】全体のシェルスクリプト

全体のシェルスクリプトは以下の様になります。
赤字の部分が前回からの変更点です。

#!/bin/bash
#
#Imageのダウンロード
python /home/pi/bijyo/SaveImages.py
python /home/pi/bijyo/ConvertImages.py
 
#USB-SWのON
sudo sh -c "echo 15 > /sys/class/gpio/export"
sudo sh -c "echo out > /sys/class/gpio/gpio15/direction"
sudo sh -c "echo 1 > /sys/class/gpio/gpio15/value"

#SD Cardのマウント
#deviceは各自の環境に合わせて変更してください
device="/dev/sdb1"
dfcnt=0
while [ $dfcnt -eq 0 ]
do
  sudo mount -t vfat ${device} /mnt/sdcard
  dfcnt=`df | grep -c /mnt/sdcard`
  sleep 10
done

#SD Card内のImageファイルを全て削除
files=`find /mnt/sdcard -name "*.jpg" -print`
if test -n "$files" ; then
    sudo rm /mnt/sdcard/*.jpg
fi

#新しいImageファイルをコピー
sudo cp /tmp/out/*.jpg /mnt/sdcard/
sync
sync
sync

#SD Cardのアンマウント
sudo umount -l ${device}
sleep 5

#USB-SWのOFF
sudo sh -c "echo 0 > /sys/class/gpio/gpio15/value"
sudo sh -c "echo 15 > /sys/class/gpio/unexport"