2012-04-04

exifの解像度を変更してInDesignに貼り込む

 XMLInDesignに流し込む時、画像の大きさが大きすぎるとページ上に表示すらできずにオーバーフローしてしまいます。これだと変更するだけでもたいへんですね。かといって、すべての画像をきちんと計算してPhotosho上で解像度を整えるのもめんどいです。*1
 通常、PhotoshopやWebブラウザでは、画像の内部的な解像度をちゃんと読み取るのが普通です。しかし、InDesignではexif情報の中に解像度があるとそちらを優先的に使って等倍貼り込みしてくれます。

 ということで、ピクセル数の閾値以上はページ内に収まるようにexifの解像度(X ResolutionとY Resolution)を変更するスクリプトです。変更といっても詐称みたいなもので、内部情報は書き換えていません。おうち使いなので危険度高めです。

#!/usr/bin/ruby
# -*- coding: utf-8 -*-

# change_resolution.rb
# 2012-04-02
# 設定したピクセル数を超えたら、解像度を上げる


require 'mini_exiftool'


##設定
defult_res = 96.0 #デフォルト解像度
x_lim = 1000 #横幅のピクセルリミット
y_lim = 400 #高さのピクセルリミット


#設定の型を浮動小数点に
defult_res = defult_res.to_f
x_lim = x_lim.to_f
y_lim = y_lim.to_f

##ループ
my_file_count_total = ARGV.length
my_file_count_succeed = 0 #成功ファイル数
ARGV.each do |my_file|
	tmp_f = MiniExiftool.new(my_file)
	tmp_f_width = tmp_f['ImageWidth'].to_f
	next if tmp_f_width === nil#幅がなければ次へ
	tmp_f_height = tmp_f['ImageHeight'].to_f
	tmp_f_xres = tmp_f['XResolution'].to_f
	tmp_f_xres = defult_res if tmp_f_xres === 0.0 #X Resolutionが空ならデフォルト解像度にする
	
	tmp_xres = tmp_yres = 0.0
	if tmp_f_width > x_lim then
		tmp_xres = ((tmp_f_width / x_lim) * tmp_f_xres * 1000).round / 1000.0
	end
	if tmp_f_height > y_lim then
		tmp_yres = ((tmp_f_height / y_lim) * tmp_f_xres * 1000).round / 1000.0
	end
	
	#解像度のセット
	set_res = [tmp_xres, tmp_yres].max
	if set_res > tmp_f_xres then
		tmp_f['XResolution'] = set_res
		tmp_f['YResolution'] = set_res
		tmp_f.save
		my_file_count_succeed += 1
	end
end

puts "Total Files: #{my_file_count_total}"
puts "Changed Files: #{my_file_count_succeed}"

 これの閾値を決めるためのバブルチャートだったりします。

*1:Photoshop上で計算するっていう定石ももちろんあります^^

2012-04-01

たくさんの画像の大きさをバブルチャートでだいたい把握する

たくさんの画像を扱わなければならない時、だいたいどんな大きさの画像が含まれているか確認しておきたいですよね。バグルチャートでぱっと見られたら便利かな、と思って書いてみました。

バブルチャートは横軸が幅(Image Width)、縦軸が高さ(Image Height)、それぞれ丸の大きさがファイル数を表しています。表はすべてのファイルのピクセル数と解像度が一覧でき、カラムごとにソートできるようになっています。
やってることは至って簡単です。rubyからExifToolexifを得てHTML出力です。バブルチャートはjqPlot、表のカラムソートはTablesorterを使っています。どちらもjQueryのプラグインです。適宜ファイルパスなどを変えてお使いください。

#!/usr/bin/ruby
# -*- coding: utf-8 -*-

# pixels_statistical_chart.rb
# 2012-04-01

require 'mini_exiftool'

dot_size = 1 #バブルチャートの最小ドットサイズ

##exifデータの多重配列を得る(数字はString)
data_list = []
ARGV.each do |my_file|
	tmp_f = MiniExiftool.new(my_file)
	tmp_f_width = tmp_f['ImageWidth']
	tmp_f_height = tmp_f['ImageHeight']
	next if tmp_f_width === nil#幅がなければ次へ
	data_list.push([
		tmp_f['FileName'], 
		tmp_f_width.to_s, 
		tmp_f_height.to_s, 
		(tmp_f_width * tmp_f_height).to_s,
		tmp_f['XResolution'].to_s
	])

end


#同じサイズの画像の出現回数をカウント
count_hash = Hash.new(0)
data_list.each{|d_list|
	count_hash[d_list[1] + ',' + d_list[2]] += dot_size
}


#count_hashからチャート用データを生成
chart_data =[]
count_hash.each{|key, value|
	chart_data.push("[#{key},#{value}]")
}
chart_data = chart_data.join(',')


#data_listからtable用データを生成
table_data = ''
data_list.each{|item|
	table_data += "\t\t\t<tr>\n"
	item.each{|child_item|
		table_data += "\t\t\t\t<td>#{child_item}</td>\n"
	}
	table_data += "\t\t\t</tr>\n"
}


#ヒアドキュメントでHTML出力
print <<ENDHTML
<!DOCTYPE html>
<html lang="ja">
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
		<meta http-equiv="Content-Script-Type" content="text/javascript" />
		<title>pixels_statistical_chart</title>
		<script language="javascript" type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
		<script language="javascript" type="text/javascript" src="dist/jquery.jqplot.min.js"></script>
		<script language="javascript" type="text/javascript" src="dist/plugins/jqplot.bubbleRenderer.min.js"></script>
		<script language="javascript" type="text/javascript" src="__jquery.tablesorter/jquery.tablesorter.js"></script>
		<link rel="stylesheet" type="text/css" href="main.css" />
		<link rel="stylesheet" type="text/css" href="dist/jquery.jqplot.min.css" />
		<link rel="stylesheet" type="text/css" href="__jquery.tablesorter/themes/blue/style.css" />
		
		<script>
jQuery( function() {
    jQuery . jqplot(
        'jqPlot-chart',
        [
            [ #{chart_data} ]
        ],
        {
            title: {
                text: 'ピクセル分布',
                show: true,
                fontFamily: 'sans-serif',
                fontSize: '20px',
                textAlign: 'center',
                textColor: '#704D22',
            },
            seriesDefaults: {
                renderer: jQuery . jqplot . BubbleRenderer,
            }
        }
    );
} );
		</script>

		<script>
$(document).ready(function() 
    { 
        $("#myTable").tablesorter(); 
    } 
); 
		</script>
	</head>
	<body>
		<div id="jqPlot-chart" style="height: 500px; width: 500px;"></div>
		<table id="myTable" class="tablesorter" cellspacing="1">
		<thead> 
			<tr>
				<th>ファイル名</th>
				<th>幅(x pixcel)</th>
				<th>高さ(y pixcel)</th>
				<th>総ピクセル数(pixcel)</th>
				<th>解像度</th>
				</tr>
		</thead> 
		<tbody> 
#{table_data}
		</tbody> 
		</table>

	</body>
</html>
ENDHTML
2012-03-10

特定のTweet引用時の正書法

英語論文で特定のツイート引用時の正書法について書かれているブログ記事を拝見しました。
英語論文におけるツイートの正しい引用のしかた[MLAスタイル]:エディテック:ITmedia オルタナティブ・ブログ

この正書法に則るために、なんどもコピペするのがめんどい人のためのrubyスクリプト(要nokogiri)

#!/usr/bin/ruby
# -*- coding: utf-8 -*-

require "open-uri"
require 'nokogiri'

if ARGV.length != 1 then
  puts "Error: No parameter."
  exit
end

my_uri = ARGV[0].dup #パラメータは.dupしないと変更できない。
if my_uri =~ %r{^https://twitter.com/.+/status/\d+$} then
  my_uri.sub!(%r{^https://twitter.com/#!/}, "https://twitter.com/")
else
  puts "Error: Is not Twitter-uri."
  exit
end


#XHTMLのパース
doc = Nokogiri::HTML(open(my_uri))

#XPathで各エレメントから文字列を取り出す
my_fullname = doc.search('div[@class="full-name"]').text.to_s#ユーザーフルネーム
my_id = doc.search('meta[@name="page-user-screen_name"]').attribute('content').to_s#ユーザーID
my_entry_content = doc.search('span[@class="entry-content"]').text.to_s#エントリー内容
my_time = doc.search('span[@class="published timestamp"]').attribute('data').to_s#エントリー時間
my_time.sub!(/^{time:'(.+)'\}/) {$1}


#書式にあわせてprint
print "#{my_fullname} (@#{my_id}). “#{my_entry_content}” #{my_time}. Tweet.\n#{my_uri}\n"

パーマリンクを指定して実行すると、こんな感じになります。
f:id:seuzo:20120310173443p:image
本当はTwitter APIでとってくればXMLでより正確にtextを取れるのかもしれないけど、とりあえずclass名とかで取れています。まあ、日付をパースしなおして日本時間にしてもいいかな。
もし万が一、ちゃんと使う人がいるようだったら -j オプションで日本語引用風にするとか考えます。
とりあえず。

2012-02-19

ReVIEWドキュメント中に使われている要素をカウントする

ReVIEWドキュメントの中にどんな要素が、どれくらい含まれているのか数えます。

#!/usr/bin/ruby
# -*- coding: utf-8 -*-

#カウント用ハッシュの初期値0
my_count = Hash.new(0)

while line = ARGF.gets
  #多くのブロック要素
  if line =~ /^(\/\/.+?)[\[\{]/ then
  my_count[$1] += 1
  
  #見出し
  elsif line =~ /^(={1,5}) / then
    tmp_key = $1 + "h" + $1.length.to_s
    my_count[tmp_key] += 1
  
  #コラム
  elsif line =~ /^(===[column])/ then
    my_count[$1] += 1
  
  #箇条書き
  elsif line =~ /^ (\*+) / then
    tmp_key = $1 + " ul(" + $1.length.to_s + ")"
    my_count[tmp_key] += 1
  
  #箇条番号
  elsif line =~ /^[1-9][0-9]?\. / then
    my_count["ol"] += 1
  
  #用語リスト
  elsif line =~ /^: / then
    my_count[": dl"] += 1
  
  #コメントは出力する
  elsif line =~ /^(\#@\# |\#@warn).+/ then
    puts "comment(#{ARGF.filename}:#{ARGF.file.lineno}) : #{$&}"
  
  end
  
  #インライン要素
  line.scan(/@<.+?>/).each {|elem|
    my_count[elem] += 1
  }
end


#項目名でソートして出力
my_count.sort.each{|key,val|
  puts "#{key} : #{val}"
}

こんなかんじで出力されるはず。

comment(hoge.re:123) : #@# ------------------------------------------
* ul(1) : 16
//emlist : 76
//indepimage : 211
//table : 43
====h4 : 13
===h3 : 24
==h2 : 35
=h1 : 9
@<b> : 344
@<code> : 7
@<icon> : 2
@<kw> : 154