ActionScript3で一度loadした画像をキャッシュとして扱うのにハマった

Flash的にはインスタンスの複製とでもいうのだろうけど、こういう独自の呼び方はなかなか覚えられない傾向があるで覚える気もない(だから覚えないんだろうけど)。
ライブラリに最初から埋め込んである画像はクラスとして書き出しておけばnew hoge(0,0);とかでいくらでも表示を量産できるんだけど、Loaderでloadした画像で同じことをしようとしてはまった。
いろいろ端折ってるけど、たとえばこういう使い方

var loaderObj:Object = new Object(); // グローバルに宣言

var bm:Bitmap = Bitmap( loader.content ); // loadした内容をbmへ
loaderObj[ 'huga' ] = loader.content; // loadの内容をオブジェクトに入れて

var bm2:Bitmap = Bitmap( loaderObj[ 'huga'] ); // 他の関数から呼んでみる


実際に有効なのはbm2のみ。
オブジェクトに丸ごと放り込みさえすれば後は使い放題なのかと思いきや、1対1の関係らしい。
「actionScript3 loader」をググってヒットしたページを順番に眺めていたらヒントがあった。
Loaderではなく、bmを見に行けばいいらしい。

var bm:Bitmap = Bitmap( loader.content ); // loadした対象をbmへ
loaderObj[ 'huga' ] = bm; // loadの内容ではなくbmをオブジェクトに入れて

var bm2:Bitmap = Bitmap( loaderObj[ 'huga' ].bitmapData ); // 他の関数から呼んでみる


ここまで書いておいて、もしかすると?と思って書き直してみた。

var bm:Bitmap = Bitmap( loader.content ); // loadした対象をbmへ
loaderObj[ 'huga' ] = Bitmap( loader.content ); // loadの内容ではなBitmapの・・・(なんて呼び方?キャストではないしオブジェクトの変換?)をオブジェクトに入れて

var bm2:Bitmap = Bitmap( loaderObj[ 'huga' ].bitmapData ); // 他の関数から呼んでみる


リファレンス眺めてもこの挙動につながる箇所を見つけられなかったけど、とりあえずBitmapとしてオブジェクトに入れておけば、自由に扱えるらしいことが分かった。
BitmapでLoaderの何らかの制限から開放されているといったところか。
「Loaderはファイルを読むためのオブジェクト」とあるので、それ以外の用法は制限されるのか、一度Bitmapにすればその制限から開放されて通常の(期待した)使用ができるのか。
loaderObj[ ‘huga’ ]自体の型には何も違いはないのだけれど。
Loaderだから何々ができないという書き方がどこにもない(探した中では)のが悲しい。

ちなみに、clone()なしでも表示は量産できるだけど、オリジナルをnullにするとかどうにかすると道連れになるかどうかとかなのかもしれないけど、今のとこ必要ないので気にしないことにする。オブジェクトに入れたものが何者なのかこんがらがったままだし。

PHPのGDで文字を描く

PHPで画像を扱うにはGDが楽なのですが、文字を書こうとすると思ったポイントで描画されません。
おそらくDPIを設定しないとだめなのでしょうが、PHPのリファレンスを探しても見つかりませんでした。
仕方がないのでいろいろ値をとりながら調べてみると、96dpiということが判明。
webではなくアプリケーション向けに72dpiで画像を生成するには以下のような手順となった。
ちなみに画像からはみ出にくいように調整もしてある。

$fontSize = 72;
$dpi = 96;
$margin = $fontSize / 8;
$baseline = $fontSize + $margin;
$size = $fontSize + $margin * 2;

$image = imagecreatetruecolor( $size, $size );

imageantialias( $image, true );
imagealphablending( $image, false );
imageSaveAlpha( $image, true );

$fillcolor = imagecolorallocatealpha( $image, 0, 0, 0, 127 );
imagefill( $image, 0, 0, $fillcolor );

$black = imagecolorallocate( $image, 0, 0, 0 );

$text = mb_convert_encoding( "あ", 'utf8' );
$font = 'xxxx.otf'; // 適当に置き換えて
imagettftext( $image, $fontSize/$dpi*$fontSize, 0, 0, $baseline, $black, $font, $text );

imagepng( $image, 'output.png', 9 );
imagedestroy( $image );

印刷も考えるとEPSで描いてから画像にするのが一番確実だけど、imagemagic(正確にはghostscript)を経由するのも面倒だしこうなった。

ActionScript3のthisに悶え苦しんだ

Javascriptがそれなりに使いこなせれば、ActionScript2も特に問題がなかったわけですが、今頃になっていじり始めたActionScript3(以下AS3)で悶え苦しみました。
イベントやシンボルの扱いが変わったことも、調べさえすれば特に問題にならず、着実に開発は進んでいたのですが・・・
さて、行き詰ったのが「this」の扱い。
いままでは、とにかく「オレオレ!」でよかったので、イベントに関数を宛がってやれば、関数からオブジェクトをごにょるのはとても簡単でした。
が、AS3ではなぜか常にグローバル?なオブジェクト(実在してないっぽいのだが)になってしまう。

for( var i = 0; i < 10; i ++ ){
    var mc:Object = new mcHoge();
    mc.name = 'hoge' + i;
    mc.addEventListener(
        MouseEvent.MOUSE_OVER,
        editPointAnchorMouseOverHandler
    );
    function editPointAnchorMouseOverHandler(evt:MouseEvent):void{
        trace(this.name);
    }
    obj.addChild( mc );
}


いままではこんな感じで(AS3用にイベントを書いてあるよ)thisを追跡できたのに、AS3ではできない。
マウスが乗っかるとundefinedとなる。
ちなみにobjはStageとかで読み替えてみて。
いろいろ調べてもどうでもいいウンチク(もちろん大事なのだが)ばかりで、AS3の解説本の著者がグダグダ語っていたりするがよく見ればAdobeの例文のままで悲しい思いをするだけで実例がない。「ActionScript3 this global」とかでググってもだめっぽい。
本当はクラスにすればいいんだろうけど、別ファイルにしなければならないらしい?
同じファイルの中でパッケージ宣言できないのは厳しい。
使いまわさなくても都合上クラスが便利なこともある(性格にはクラスであるべきことのほうが多いのだが)のにファイル分けなきゃいけないの?
と、それたところで軌道修正。

結局のところ、別に関数を用意して、その中でオブジェクトを作ってやって戻り値もオブジェクトにすれば、擬似的にパッケージ化できることが判明。OOPを実装したはずのAS3のコンパイラが関数をどう扱っているのかなぞである。
結局はこうなった。

for( var i = 0; i < 10; i ++ ){
    var mc:Object = fuga( i );
    obj.addChild( mc );
}
function fuga( i:int ):Object {
    var mc:Object = new mcHoge();
    mc.name = 'hoge' + i;
    mc.addEventListener(
        MouseEvent.MOUSE_OVER,
        editPointAnchorMouseOverHandler
    );
    function editPointAnchorMouseOverHandler(evt:MouseEvent):void{
        trace(this.name);
    }
    return mc;
}


実質、関数をオブジェクトと定義しているわけだが、関数は関数しか宣言できないのでオブジェクト・・・あれ?
もしかしてこう書けばいい?
var mc:Object = function( i:int ):Object{ var mc:Object = new mcHoge(); [省略]; return mc; }
とすると強制型変換に失敗したと怒られた。
理屈ではこれでいいはずなのに、なんでだろ?
まぁ、初めたばかりだし、AS3の書き方に慣れてからまた考えよう。

Net::Amazonをインストールしてみる

Windowの場合、CPANではNOT OKがでるけど、ppmで簡単に追加できた。

Linux(CentOS)の場合、cpanではNOT OKが大量に出て、個別にモジュールを入れていっても、開発系のライブラリがほとんど入ってないためか、それぞれがNOT OKになってしまう。
結局yumから1つづつ入れていくことになった。
perl-XML-DOM
perl-DIgest-SHA
libxml2
libxml2-devel
Sys-Syslog
perl-Log-Log4perl
んだけど、ログに関するライブラリが入らない。
よくよく見ればCPANの起動時にBundle::CPANを入れろと書いてあるではないか。そういうことならと入れてみる。
何事もなく無事に終了し、Net::Amazonも難なく入った。
結局何が問題なのかって、Bundle::CPANを入れてなかったことだけが問題だったのかもしれない。

InternetExplorer8でJavaScriptのimageオブジェクトの挙動が怪しい

FLASHに頼らずJavaScriptで画像なとを扱うツールをこさえているのですが、IE7では問題なかったものがIE8でおかしくなっている。
IE8に搭載されているIE7互換モードでもだめ、どうやら純粋なIE7のレンダリングエンジンではないようだ。
問題となっているのは、非同期でimageを読んで表示を更新するものだけど、imageオブジェクトでcompleteがtrueになっているにもかかわらずwidthとheightの値が更新されていない。FirefoxやOpera、safariではもちろん正常に機能する。だめなのはIE8のみ。IE7を信じて調整を行って損した。
これからは絶対にIEを信じることはないだろう・・・

ActivePerlがモジュールのインストール周りで進化していた

新しいマシンが調達できたので、Windowsを載せかえる作業をしています。
このマシンはクローラとして使うのでサーバやスクリプト等のインストールを行う必要があります。
Perlga使えないとどうしようもないので、真っ先にActivePerlをインストールするわけですが、そういえば5.10になったなと思いながら作業を進めていると、CPANを起動したらMinGWというコンパイラを入れろというメッセージが。
5.8まではこういう表示もなく、手作業でMicrosoftからwin32cのソフトを入れていました。
MinGWというものが何かは良くわかっていませんが、Cのコンパイラであることに違いないでしょう。
そしてCPANでコンパイラが必要なモジュールを入れるときに勝手に探してきてインストールまで行ってくれました。
これはかなり楽になりましたね~

追記)プロンプトからのcpanのインストールコマンドがcpan モジュール名になってますね。
cpan install モジュール名を入れたら怒られました。

プリンタを買いました

パソコンの使い始めといえばN88-BASICとか、MS-DOS5.0AHとか、Window3.1とかの世代なのですが、PC-9821Xa/7Eを手に入れて以来、それなりに周辺機器には手を出してきました。
その中で今まで手に入れていないメジャーな機器にMOとプリンタがありましたが、ついにプリンタを買うことにしました。
プリンタはずっと欲しかったのですが、携帯のデジカメで済ますのがほとんど。

とはいえ、最近のサービスは領収書など自分で印刷しろってのが多く、ファミマTカードの請求書も印刷のみなのでこれはいよいよ買うしかないと、重い腰を上げたのです。
頻繁に使うわけではなく、インクジェットだと起動時のクリーニングでインク代が馬鹿にならないらしいので、思い切ってレーザーを選択することに。
デザインとか使い勝手とか考えて、結局ブラザーのHL-2140にしました。
買ったのは楽天の店で12000を切る安さ。
ポイントを使って1万ちょいで手に入れました。

di:ブラザー 新品送料無料!A4 モノクロレーザープリンタージャスティオ HL-2140メーカー保証…

実際に使ってみても、特に問題ありません。
レーザなので電気を食うのはわかっていましたが、電圧が不安定になるのか、電磁波の影響かわかりませんが、起動時と印刷時に部屋の蛍光灯がちらつくぐらいで、思っていたよりも静かだし、いい買い物をしたのではないかと思ってます。
トナーセーブモードがあるのですが、印刷ごとに設定品ければならないのでちょっと面倒です。
どうやら、初期状態は固定なようで、印刷のジョブごとに再設定が必要なのは調整して欲しいところです。

PHPにPEAR::SOAPをインストールする

CentOS5.3での話です。
SOAPが必要になったのでPEARからインストールすることにしました。
PHP5ではあらかじめ用意されているみたいだけど、公式にすらまともな解説がないのであきらめました。
pear install SOAP-beta
Did not download optional dependencies: pear/Mail, pear/Mail_Mime, pear/Net_DIME, use –alldeps to download automatically
pear/SOAP requires PEAR Installer (version >= 1.5.4), installed version is 1.4.9
pear/SOAP can optionally use package “pear/Mail”
pear/SOAP can optionally use package “pear/Mail_Mime”
pear/SOAP can optionally use package “pear/Net_DIME”
No valid packages found
install failed
どうやら、インストーラーが古いのと、いろいろと足らないものがあるので–alldepsスイッチをつけろとのこと。

pear install --alldeps SOAP-beta
pear/SOAP requires PEAR Installer (version >= 1.5.4), installed version is 1.4.9
pear/Mail_Mime requires PEAR Installer (version >= 1.6.0), installed version is 1.4.9
pear/Mail_mimeDecode requires PEAR Installer (version >= 1.6.0), installed version is 1.4.9
pear/Mail_mimeDecode requires package "pear/Mail_Mime" (version >= 1.4.0, excluded versions: 1.4.0)
downloading Mail-1.2.0b2.tgz ...
Starting to download Mail-1.2.0b2.tgz (21,972 bytes)
........done: 21,972 bytes
downloading Net_DIME-1.0.1.tgz ...
Starting to download Net_DIME-1.0.1.tgz (7,535 bytes)
...done: 7,535 bytes
downloading Net_SMTP-1.3.3.tgz ...
Starting to download Net_SMTP-1.3.3.tgz (10,944 bytes)
...done: 10,944 bytes
downloading Auth_SASL-1.0.3.tgz ...
Starting to download Auth_SASL-1.0.3.tgz (5,724 bytes)
...done: 5,724 bytes
install ok: channel://pear.php.net/Auth_SASL-1.0.3
install ok: channel://pear.php.net/Net_SMTP-1.3.3
install ok: channel://pear.php.net/Net_DIME-1.0.1
install ok: channel://pear.php.net/Mail-1.2.0b2


まだ何か文句を言っているので、PEARをアップグレードしてみる

pear upgrade PEAR
downloading PEAR-1.9.0.tgz ...
Starting to download PEAR-1.9.0.tgz (291,634 bytes)
.............................................................done: 291,634 bytes
upgrade ok: channel://pear.php.net/PEAR-1.9.0
PEAR: Optional feature webinstaller available (PEAR's web-based installer)
PEAR: Optional feature gtkinstaller available (PEAR's PHP-GTK-based installer)
PEAR: Optional feature gtk2installer available (PEAR's PHP-GTK2-based installer)
To install use "pear install pear/PEAR#featurename"


もう一度SOAPを入れなおしてみる

pear install -f --alldeps SOAP-beta
WARNING: "pear/HTTP_Request" is deprecated in favor of "pear/HTTP_Request2"
downloading SOAP-0.12.0.tgz ...
Starting to download SOAP-0.12.0.tgz (71,233 bytes)
.................done: 71,233 bytes
install ok: channel://pear.php.net/SOAP-0.12.0


まだしつこく何か言ってるけど、疲れたので放置。

PHPのPEARで覚書

CENTOS5.3での話です。
PEARをアップグレードしようとすると以下のように怒られました。

pear upgrade PEAR
WARNING: channel "pear.php.net" has updated its protocols, use "channel-update pear.php.net" to update
pear/Archive_Tar requires PEAR Installer (version >= 1.5.4), installed version is 1.4.9
pear/PEAR dependency package "pear/Archive_Tar" installed version 1.3.1 is not the recommended version 1.3.3, but may be compatible, use --force to install
No valid packages found
upgrade failed


PEARが古いのと、Archive_Tarが古いといわれてしまいました。

pear channel-update pear.php.net
Retrieving channel.xml from remote server
Update of Channel "pear.php.net" succeeded


まずPEARを更新して、

pear upgrade pear/Archive_Tar
pear/Archive_Tar requires PEAR Installer (version >= 1.5.4), installed version is 1.4.9
No valid packages found
upgrade failed


あれ、失敗?

pear install -f pear/Archive_Tar
warning: pear/Archive_Tar requires PEAR Installer (version >= 1.5.4), installed version is 1.4.9
downloading Archive_Tar-1.3.3.tgz ...
Starting to download Archive_Tar-1.3.3.tgz (18,119 bytes)
......done: 18,119 bytes
install ok: channel://pear.php.net/Archive_Tar-1.3.3


強引にねじ込みました。

RGBをCMYKに変換する

結論から言うと失敗作というか、最小値と最大とのみを考慮して作られた式です。
はっきりいって使い物になりませんが、フリーソフトではつかっちゃっているようです。
動作確認用に作ったものなので、細かいエラーチェックは抜きです。

#===============================================================================
# RGB => CMYK(cmyが同じ値の場合kに割り振る)
#-------------------------------------------------------------------------------
sub rgb2cmyk {

	my $rgb = shift;
	$rgb =~ /^#?(..)(..)(..)$/;
	my %color = (
		'r' => hex( $1 ),
		'g' => hex( $2 ),
		'b' => hex( $3 ),
	);

	$color{'c'} = 1 - ( $color{'r'} / 255 );
	$color{'m'} = 1 - ( $color{'g'} / 255 );
	$color{'y'} = 1 - ( $color{'b'} / 255 );
	$color{'k'} = 0;
	if(
		   $color{'c'} == $color{'m'}
		|| $color{'m'} == $color{'k'}
	){
		$color{'k'} = $color{'c'};
		$color{'c'} = $color{'m'} = $color{'y'} = 0;
	}

	return %color;

}

結局、色を絞って変換テーブルを自作することになりましたけどね。