2009年5月26日火曜日

C++: ストリームの出力先をファイルや標準出力に切り替える

このブログ記事をはてなブックマークに追加

C++のストリームの出力先を任意にファイルや標準出力に切り替えたいときがたまにある。しかし、その度に標準出力ストリームやファイルストリームを定義し直して使うのは面倒だし、効率が悪い。

そんな時は、以下のコードで示す方法で切り替えると楽だ。2~3行で変更できる。さらに、ostreamのポインタでストリームを保持しておけば動的な切り替えも簡単だ。

以下、ソースコード。

#include <iostream> #include <fstream> using namespace std; int main() { // coutの出力バッファをofstreamのバッファに変更する方法. // 最後にcoutの出力バッファを元に戻すこと. streambuf* last = cout.rdbuf(); ofstream ofs("test01.txt", ios_base::out); cout.rdbuf(ofs.rdbuf()); cout << "test01 to file" << endl; ofs.close(); cout.rdbuf(last); // ostreamのインスタンス作成時にストリームの出力バッファを指定する方法. ofs.open("test02.txt", ios_base::out); ostream out1(cout.rdbuf()); ostream out2(ofs.rdbuf()); out1 << "test02 to stdout" << endl; out2 << "test02 to file" << endl; ofs.close(); // ostreamのポインタを使ってnewでインスタンスを作成する方法. // これなら必要時に動的にストリームを変更できる. ostream* o; o = new iostream(cout.rdbuf()); *o << "test03 to stdout" << endl; delete o; o = new ofstream("test03.txt", ios_base::out); *o << "test03 to file" << endl; delete o; return 0; }

続きを読む...

2009年5月18日月曜日

Python: URL短縮サービスbit.lyのAPIを使ってみた

このブログ記事をはてなブックマークに追加

最近、TwitterがTinyURLを捨ててbit.lyを採用したらしい。そんなこともあって、URL短縮サービスに興味がわいたので、以前にGoogle App Engineで作成したTwitter送信機能付きメッセージボードで書き込んだURLをbit.lyで短縮して送信できるようにしてみた。今まではURLを含む投稿はTwitterに送信しないようにしていた。以下にbit.lyのAPIをPythonを使ってどのように利用すればよいか書いてみる。

まずは、bit.lyで無料アカウントを取得する。これでAPI Keyが貰えるので、bit.lyのAPIを利用できるようになる。次に、bit.ly APIの解説を参考にしながら、APIを使ってみる。URLの短縮も展開も簡単だ。JSONでもXMLでも利用できるが、今回はsimplejsonを使ってJSONを利用している。

詳しくは最後にソースコードを付けたのでそれを読んで欲しい。因みにソースコード中の赤字で示した部分がアカウント名とAPI Keyになる。コード中のアカウントはbit.lyのデモ用なので、自分のアカウントと置き換えて欲しい。使い方は、

bitly_test.py URL

とすればよい。URLが短縮URLなら展開され、通常のURLなら短縮URLが表示される。

また、Google App Engineで利用する場合は、simplejsonを

from django.utils import simplejson

として呼び出し、urllib2.urlopenをurlfetch.fetchに変更すればよい。

bitly_test.py

#!/usr/bin/env python import sys, os, re, urllib, urllib2 import simplejson apiurl = "http://api.bit.ly/%s?version=2.0.1&%s=%s&login=bitlyapidemo&apiKey=R_0da49e0a9118ff35f52f629d2d71bf07" api_index = { "shorten": "longUrl", "expand": "shortUrl" } info_index = { "shorten": "shortUrl", "expand": "longUrl" } def is_error(url, url_info): return url_info["statusCode"] != "OK" or (url_info["results"][url].has_key("statusCode") and url_info["results"][url]["statusCode"] != "OK") def bitly(url, api): url_data = urllib2.urlopen(apiurl % (api, api_index[api], urllib.quote(url))).read() url_info = simplejson.loads(url_data) if api == "expand": url = url.replace("http://bit.ly/", "") if is_error(url, url_info): return "" return url_info["results"][url][info_index[api]] def main(args): if len(args) < 2: print >>sys.stderr, "Usage: %s url" % os.path.basename(args[0]) sys.exit(1) url = args[1] if url.lower().split(":")[0] not in ("http", "https", "ftp"): url = "http://" + url bitly_url = "" if re.match(r"http://bit.ly/", url) and not re.search("[^a-z^A-Z^0-9]", url.replace("http://bit.ly/", "")): bitly_url = bitly(url, "expand") if not bitly_url: bitly_url = bitly(url, "shorten") print bitly_url if __name__ == "__main__": main(sys.argv)

続きを読む...

2009年5月15日金曜日

Python: 複数の画像ファイルを余白を埋めるように貼り付ける

このブログ記事をはてなブックマークに追加

何か面白いコードが書きたいなぁ、と思ってPython+PILで複数の画像ファイルを適当に余白を埋めるようにキャンバスに貼り付けるプログラムを書いてみたけどあまり面白くなかった。それでもせっかく書いたので一応公開する。

まず、入力した画像ファイルすべての面積を取得して、その面積と出力画像の面積の比を求める。すべての入力画像に対して、その比から大きさを変更する。これで入力画像の面積の総和と出力画像の面積が等しくなる。次に、入力画像を面積の大きい順にソートし、入力画像一つ一つと出力画像を重ね合わせ、もっとも余白との一致が大きい場所を見つける。その場所に入力画像を貼り付ける。貼り付ける際、全体の余白を少なくするために画像の大きさをランダムに1.2~1.5倍に拡大している。すべての入力画像を貼り付ければ完了だ。

ここの画像はフリー画像素材EyesPicに置いてあった植物写真の22枚を貼り付けてみたものだ。プログラムの使い方は、

place_pictures.py 出力画像ファイル 複数の入力画像ファイル...

のようにする。例えば、同じディレクトリにあるすべてのJPEGファイルをimage.jpgに貼り付ける場合、以下のようにすればよい。因みにデフォルトでは600×800ピクセルの大きさの画像となっている。コード内のXSIZE, YSIZEを指定することで自由に変更できる。

place_pictures.py image.jpg *.jpg

以下にソースコードを示す。

place_pictures.py

#!/usr/bin/env python import sys, os, glob, math, random, Image IMAGE_EXT = (".jpg", ".jpeg", ".jpe", ".png", ".bmp", ".gif", ".tif", ".tiff") IMAGE_XSIZE, IMAGE_YSIZE = 600, 800 def place_pictures(files, img_file): area = 0 sorted_files = [] for f in files: if f[-4:].lower() in IMAGE_EXT: im = Image.open(f) width, height = im.size a = width * height sorted_files.append((a, f)) area += a sorted_files.sort(reverse=True) files = map(lambda x: x[1], sorted_files) rate = math.sqrt(IMAGE_XSIZE * IMAGE_YSIZE / float(area)) new_im = Image.new("RGB", (IMAGE_XSIZE, IMAGE_YSIZE), (0, 0, 0)) for f in files: if os.path.splitext(f)[1].lower() in IMAGE_EXT: im = Image.open(f) rnd = random.uniform(1.2, 1.5) width, height = map(lambda x: int(x * rate * rnd), im.size) im = im.resize((width, height)) max_area_rate = 1.0 max_npixel = 0 paste_x, paste_y = random.randint(0, IMAGE_XSIZE - width), random.randint(0, IMAGE_YSIZE - height) mx = (IMAGE_XSIZE - (IMAGE_XSIZE / width + 1) * width) / 2 my = (IMAGE_YSIZE - (IMAGE_YSIZE / height + 1) * height) / 2 for rx in range(mx, IMAGE_XSIZE, width / 3): for ry in range(my, IMAGE_YSIZE, height / 3): rx1 = rx if rx >= 0 else 0 ry1 = ry if ry >= 0 else 0 rx2 = rx + width if rx + width < IMAGE_XSIZE else IMAGE_XSIZE ry2 = ry + height if ry + height < IMAGE_YSIZE else IMAGE_YSIZE crop_im = new_im.crop((rx1, ry1, rx2, ry2)) s = crop_im.tostring() npixel = len(s) area_rate = sum(map(lambda x: 0 if ord(x) == 0 else 1, s)) / float(npixel) if max_area_rate > area_rate or (max_area_rate == area_rate and max_npixel < npixel): max_area_rate = area_rate max_npixel = npixel paste_x, paste_y = rx, ry new_im.paste(im, (paste_x, paste_y)) new_im.save(img_file) new_im.show() def main(args): if len(args) < 3: print >>sys.stderr, "Usage: %s output-image-file image-files..." % os.path.basename(args[0]) sys.exit(1) files = [] img_file = args[1] for arg in args[2:]: files.extend(glob.glob(arg)) place_pictures(files, img_file) if __name__ == "__main__": main(sys.argv)

続きを読む...

2009年5月7日木曜日

NW-X1060を購入

このブログ記事をはてなブックマークに追加

プログラミングをしているときに一つ気になることがある。それはPCから出るノイズだ。特に自分は職場でも自宅でも周りを数台のPCに囲まれているのでその音も馬鹿にならない。聞いているうちに何となく慣れてしまうのだが、常に耳に届くノイズは少なからずストレスになっているような気もするのだ。それもあって、ノイズキャンセリングヘッドフォンは複数所有している。

最近、デジタルノイズキャンセリング機能を有したSonyのウォークマンNW-X1060が発売されたことを知った。フラグシップモデルらしい。高性能ノイズキャンセリング機能と聞くと食指が動く。しかも、無音のままノイズキャンセリング機能だけを働かせることができるらしい。今回もそれが大きな動機となって購入してしまった。

所有しているノイズキャンセリングヘッドフォンは、BOSEのQuietComfort2、SennheiserのPXC300、SonyのMDR-NC22など。ほかにも安物のノイズキャンセリングヘッドホンがあったりする。今回はデジタルノイズキャンセリングと云うこともあり、それらと比べてもなかなかの性能を発揮しているようだ。自分の周りのPC環境で使うと、それまでうるさかったノイズがすぅーっと消えるのが心地よい。

コーディングしているときに使ってみたが、音質が良く、長時間の使用でも聴き疲れがないのがいい。今までのものは耳が疲れてしまってコーディングなどの作業に集中ができなくなったりしたが、今回のものは疲れにくいようだ。それと、電車通勤時に動画を視聴するのにも便利。画面は小さいけどね。でも、かさばらないし、有機ELなので画質はかなり良い。

欠点としては、やはり付属のソフトウェア(SonicStage)が使いにくいことと、本体にストラップがつけられないので胸ポケットなどに入れて使うしかないこと。別売りの専用ケースを使えば良いそうだが、このぐらいは初めから付けて欲しかった。SonicStageは相変わらずだ。ソフトウェアの使い勝手が良くなるだけでだいぶ印象も変わるだろうに。NW-X1060自体の使い勝手はまあこんなものか? 特に比較する対象も持っていないので何ともいえない。

結論としては、思ったよりも音が良く、聴き疲れもしないし、デジタルノイズキャンセリングも効果があり、購入して良かったという感想。まあ、音の聞こえ方や好みは人それぞれだと思うので、気になる人は実際に店などで実機を手にとってみるのが良いかも。

続きを読む...