カテゴリー : 2006年 7月

imagerotate の小数から整数への変換仕様


imagerotate の結果を計算で出したいなと思い次のコードで検証してみました。

<?php
// 対象の画像のサイズ。
$sw = 1000;
$sh = 2000;
// 実測用に画像生成
$im = imagecreatetruecolor($sw,$sh);
for($deg = -360; $deg <= 360; $deg +=15){
   $rad = deg2rad($deg); // 三角関数はラジアンを取るので角度をラジアンに変換
   // 回転後のサイズ計算(四捨五入)
   $w = round(abs($sw * cos($rad)) + abs($sh * sin($rad)));
   $h = round(abs($sw * sin($rad)) + abs($sh * cos($rad)));
   // 実際に回転させた時のサイズ
   $im_t =imagerotate($im, $deg, -1);
   $rw = imagesx($im_t);
   $rh = imagesy($im_t);
   imagedestroy($im_t);
   // 比較
   if($w != $rw || $h != $rh){
     echo “$deg: calc($w, $h) != real($rw, $rh) “.”\n”;
   }
}
?>

結果:

-330: calc(1866, 2232) != real(1867, 2233)
-315: calc(2121, 2121) != real(2122, 2122)
-300: calc(2232, 1866) != real(2233, 1867)
-240: calc(2232, 1866) != real(2233, 1867)
-225: calc(2121, 2121) != real(2122, 2122)
-210: calc(1866, 2232) != real(1867, 2233)
-150: calc(1866, 2232) != real(1867, 2233)
-135: calc(2121, 2121) != real(2122, 2122)
-120: calc(2232, 1866) != real(2233, 1867)
-60: calc(2232, 1866) != real(2233, 1867)
-45: calc(2121, 2121) != real(2122, 2122)
-30: calc(1866, 2232) != real(1867, 2233)
30: calc(1866, 2232) != real(1867, 2233)
45: calc(2121, 2121) != real(2122, 2122)
60: calc(2232, 1866) != real(2233, 1867)
120: calc(2232, 1866) != real(2233, 1867)
135: calc(2121, 2121) != real(2122, 2122)
150: calc(1866, 2232) != real(1867, 2233)
210: calc(1866, 2232) != real(1867, 2233)
225: calc(2121, 2121) != real(2122, 2122)
240: calc(2232, 1866) != real(2233, 1867)
300: calc(2232, 1866) != real(2233, 1867)
315: calc(2121, 2121) != real(2122, 2122)
330: calc(1866, 2232) != real(1867, 2233)

この結果から判断して、
imagerotate では内部的に ceil で繰り上げにしているようなので
単純に round -> ceil にかえてみたところ、
結果は次のようになりました。

-360: calc(1001, 2001) != real(1000, 2000)
-270: calc(2001, 1001) != real(2000, 1000)
-180: calc(1001, 2001) != real(1000, 2000)
-90: calc(2000, 1001) != real(2000, 1000)

PHP の float の特性(*1)が悪さをしているのか、切り上げ処理で GD の結果と食い違いができてしまったようです。
ということで次のようにすれば完全に一致しました。

<?php
// 回転後のサイズ計算(imagerotate 互換の切り上げ)
$fw = abs($sw * cos($rad)) + abs($sh * sin($rad));
$w = ceil(“$fw”); // 一度文字列にする
$fh = abs($sw * sin($rad)) + abs($sh * cos($rad));
$h = ceil(“$fh”); // 同上

 
 *1: PHP の float は有効桁数を超えると表示上その部分が見えなくなります。

$f = 1 + 1E-13;
echo “$f\n”; // 1 が表示される
if($f > 1){
    echo “$f > 1\n”; // 1 > 1 が表示される。
}
echo sprintf(“%.15f”, $f).”\n”; // 1.000000000000100 が表示される

LoadVars – 外部テキスト読み込みクラス


- Loadvars(livedocs)
 
例1:

var user = new LoadVars();
user.onLoad = function(success){
  if(success){
    trace(“名前: ” + this.name);
    trace(“年齢: ” + this.age);
    trace(“職業: ” + this.job);
    play(); // 読み終ったら次のフレームに。
  }else{
    trace(“失敗”);
    return;
  }
}
user.load(“user.txt”); // 中身は name=John&age=24&job=Fireman とする
stop();

例2(任意書式のテキストデータを読む):
CSV データ等を読む場合は LoadVars.onData() を使います。

var mesLoader = new LoadVars();
_global.message = ”;
mesLoader.onData = function(src){
   if(src == undefined){
      trace(“失敗”);
      return;
   }
   _global.message = src;
   play();
}
mesLoader.load(“message.txt”); // 中身は Hello, world! など任意。
stop();

参考:
- LoadVarsでテキストファイルを読み込む

Ethereal,Tethereal が FreeBSD の ports から消えてた


ローカルの ports で探してみて、net/ethereal にあったはずの Ethereal が見付からなくてアレッ!?と思って公式の cvsweb をあたって見たところ
次のように書いてました。
 
http://www.jp.freebsd.org/cgi/cvsweb.cgi/ports/net/ethereal/Attic/Makefile?hideattic=0

FILE REMOVED
 
Add wireshark and tshark after repocopies from ethereal and tethereal
respectively. Wireshark is a rename of ethereal after the principal
developer moved companies and lost the Ethereal copyright.
 
Messenger, don’t shoot!
 
Now the ethereal binary is called wireshark, the tethereal binary is
called tshark, and idl2eth is now idl2wrs. All other binaries have
kept the same name.
 
In addition to this name change, I have also changed the PREFIX from X11BASE
to LOCALBASE.

 
Ethereal(CUI 版: TEthereal) は主要な開発者が会社を辞めて商標権を失って wireshark(CUI 版: tshark) という別の名前で存続する事になった、ということです。
 
ということで ports を改めて見ると、 net/wireshark, net/wireshark-lite, net/tshark, net/tshark-lite が増えてました。
 
Wireshark の公式サイトは http://wireshark.org/ で、
現在、Ethereal 0.99 から更新された Wireshark 0.99.2 がリリースされています。
 
参考:
- 「Ethereal」は「Wireshark」に飲み込まれるのか?(ITpro)
- Wireshark 公式サイト
- Ethereal 公式サイト

FreeMind で作ったマインドマップを Flash で表示する


Flash Browser
.mm ファイルを表示する、Flash で作られたビューワ。
これを使うと、こんな感じになります。
 
公式ドキュメントでもこれが利用されています。

Ethereal – TCP の生のデータを保存する


Follow TCP Stream を使えば生の TCP ストリームデータを取得可能です。
 
例えば、HTTP で画像を取得して、その画像をファイルとして保存したい場合は
次のようにします。
 
1. HTTP/1.1 200 OK などの HTTP レスポンスパケットを選んで右クリック→Follow TCP Stream を選択
2. Follow TCP stream ウィンドウが開いたら、右下の Raw をチェック
3. Save As をボタンをクリック
4. 保存先を指定して保存(保存例: http_gif.dat|rs/http_gif.dat)
5. バイナリエディタを開き、0D 0A 0D 0A 以前(HTTP Header)を削除し、拡張子変更(変更例: 画像)
 
追記:
(2006-07-27)同日の別トピックに書きましたが、Ethereal は複製版が Wireshark として独立し、そちらが更新されています。

画像や PDF, 動画を SWF に変換する


- swftools (ports: graphics/swftools)
以下のツールを提供する GPL のコレクションパッケ−ジです。

PDF2SWF – PDF から SWF への変換
SWFCombine – 複数の SWF を 1つの SWF でラップして結合する。
SWFStrings – SWF 中の文字列を読み取る
SWFDump – SWF のさまざまな情報を得る
JPEG2SWF – JPEG 画像から SWF への変換
PNG2SWF – PNG 画像から SWF への変換
GIF2SWF – GIF 画像から SWF への変換
WAV2SWF – WAV 音声から SWF への変換
AVI2SWF – AVI 動画から SWF への変換
Font2SWF – TTF, Type1 フォントファイルから SWF への変換
SWFBBox –
SWFC – SWF コンパイラ(スクリプトから生成)
SWFExtract – SWF 中のムービークリップ、音声、画像などの抽出
 
RFXSWF Library – 素材を含む, SWF 作成用のライブラリ

 
以下は jpeg2swf の利用例です。

# src フォルダの全ての JPEG をフレームレート 3fps の
# SWF ムービーに変換して out.swf として保存する( -z は圧縮オプション)。
jpeg2swf -r 3 -z -o out.swf src/*.jpg

αチャンネルを画像から取り出す


convert drawn.png -channel matte -separate +matte matte.png

これで、drawn.png のαチャンネル(透過度)だけをモノクロで取得した画像を得ることができます。
参考:
http://www.cit.gu.edu.au/~anthony/graphics/imagick6/channels/#matte
情報元:
http://blawat2015.no-ip.com/~mieki256/diary/0623.html

RPM をインストールせずに展開する


rpm2cpio foo.rpm | cpio -uid

ImageMagick の convert で半透明な PNG を扱う


PNG はRGBとともにα値を保持しているので、半透明色というのも指定することが可能です。

# a.gif の白(#FFFFFF)を半透明(50%=0×80)にし、b.png として保存(入力の形式は任意ですが、出力は png 必須です)。
convert a.gif -fill “#FFFFFF80″ -opaque “#FFFFFF00″ b.png
# 半透明になったか確認のため背景画像 bg.jpg の上に b.png を重ね、
# c.jpg として保存する(背景、出力の画像形式は任意です)。
convert -compose over bg.jpg b.png c.jpg

参考:
- convert コマンドのオプションについては昨日の記事([2006-07-24])を参照。
- PNGについては JEvaHz Messages 1320-1331 を参考にしました。

PNGの透明化は大別して2種類の指定方法があり、色深度などにより厳密には
4種類のフォーマットがあります。
 
1.αチャンネルを用いる場合(Color type = 4 or 6)
  (8bit,16bit grayscale / 24bit,48bit color)
 RGB値もしくはgrayscale値に加え、ピクセル毎にα値(透明度)を保持。
 α値の深度は色深度と同じ。
 
2.tRNS(=transparency) chunkを用いる場合
  a.1,2,4,8bit indexed colorの場合(Color type = 3)
   個々のカラーに対し、8bitの深度の透明度を指定できる。
  b.1,2,4,8,16bit grayscale の場合 (Color type = 0)
   ある一つのgrayscale levelに対し、1bitの深度の透明度を指定できる。
  c.24/48bit colorの場合(Color type = 2)
   ある一つの色に対し、1bitの深度の透明度を指定できる。
 
(中略)
 
また、PNGの仕様によると透明化は必須ではないらしいので、
実装にばらつきがでるのはやむを得ないでしょう。
部分的な対応もOKだそうで…。

- PNG Programming Resources

指定した色を別の色に置き換える


 

convert source.gif -fill dest_color -opaque src_color dest.jpg

source.gif の、 src_color という色を dest_color という色に置き換えて dest.jpg として保存します。

例:
convert source.gif -fill “#FF0000″ -opaque “#FFFFFF” result.jpg

真っ白で塗られている箇所を、真っ赤に塗りつぶします。
 
用途として、GIF,PNG などの透過対応形式からJPG,BMPなどの透過非対応形式に変換する場合の、透過色の置き換えなどに使えます。
 
参考:
convert -opaque
convert -fill