mieki256's diary



2006/02/20(月) [n年前の日記]

#5 [iappli][prog] Perlで、iアプリのスクラッチパッドに置くためのデータを作成するスクリプトを作成

gif画像を連結して一つのファイルにする。それをスクラッチパッドに格納して、スクラッチパッドから画像データを読むことで、逐一サーバから画像を取得しないで済むようにする。らしい。 *1

_Perl表技集 を参考に。
_文字列の連結
_ファイルサイズ取得
_ファイルを一文字列として読み込む
_ディレクトリ内のファイル一覧
_ディレクトリ存在確認
を見ながら作業。ありがたや。

こんな感じかしら。 :

まだ、iアプリ側で読んで確認してないのでバグってる可能性大だけど。とりあえずこういう感じでやればいいのかなと。

(2006/02/24追記。ちと下のはバグってます。)
#!/usr/bin/perl
#
# imgjoin.pl
#
# 指定フォルダ内のgif画像を連結して1つのファイルにする。
#
# usage : perl imgjoin.pl DIR_NAME OUTPUT_FILENAME
# 
# 出力ファイルの先頭には、ヘッダーが入る。
#
# 2byte     ファイル数
# 4byte     1ファイル目 : ファイル実データまでのオフセット
# 4byte     1ファイル目 : ファイル実データのサイズ
# 4byte     2ファイル目 : ファイル実データまでのオフセット
# 4byte     2ファイル目 : ファイル実データのサイズ
#    ...
#
# OUTPUT_FILENAME は拡張子なしで指定。
# (スクリプト中で、.pak .txt 等を付け足してファイル名を決めてる)
#
# ActivePerl-5.8.7.815-MSWin32-x86-211909 で動作確認。
#
# by mieki256
# 2006/02/20 0.01 とりあえず作成。

use strict;

my $ext ="gif";             # 処理する拡張子
my $outdir = "./bin";       # 出力先のディレクトリ名 (最後の '/' は不要)
my $pakext = ".pak";        # パックしたデータファイルの拡張子
my $lstext = ".txt";        # データ順の定義部分を出力する際の拡張子


if ( $#ARGV != 1 ) {
    die "引数が異常です。 : $!";
}

my $dir = $ARGV[0];         # 指定ディレクトリ名を得る
my $outfname = $ARGV[1];    # 出力ファイル名を得る

if ( -d $dir ) {
    print " ... Found Directory : $dir \n";
} else {
    die "Not Found $dir :";
}

# ----------------------------------------
# ファイルリスト取得
my @list = ();
opendir DH, $dir or die "$dir : $!";
while (my $file = readdir DH) {
    next if $file =~ /^\.{1,2}$/;   # '.' '..' をスキップ
    if ( $file =~ /\.$ext$/i ) {
        push(@list,$file);
    }
}
closedir DH;

if ( $#list < 0 ) {
    die "Not Found .$ext file. : $!";
}

my @sortlist = sort {$a cmp $b} @list;
my @sizelist = ();

# ----------------------------------------
# ファイルサイズ取得
foreach my $f (@sortlist) {
    my $size = -s "$dir/$f";
    print "found $f : size $size\n";
    push(@sizelist, $size);
}
my $binsize = 0;
foreach my $s (@sizelist) {
    $binsize += $s;
}

print " ... ", $#sortlist+1," files. : size = $binsize\n";

# ----------------------------------------
# 結合データ作成

# ヘッダ作成
my $wrdata = pack("n", ($#sizelist + 1) );  # ファイル数
my $offset = 4 + (($#sizelist + 1) * 8);    # 最初のファイルのオフセット
foreach my $size (@sizelist) {
    $wrdata .= pack( "N", $offset);         # オフセット
    $wrdata .= pack( "N", $size );          # ファイルサイズ
    $offset += $size;
}

# ファイルデータ結合
foreach my $f (@sortlist) {
    open(FH, "$dir/$f") || die $!;
    binmode FH;
    my $data;
    {
        local $/ = undef;
        $data = <FH>;
        $wrdata .= $data;
    }
    close(FH);
}

# 結合したデータをファイルに出力
open(OUT,"> $outdir/$outfname$pakext") || die $!;
binmode OUT;
print OUT $wrdata;
close OUT;

print " ... write $outdir/$outfname : length = ", length $wrdata, "\n";


# ついでに、.java 内で使う、定義部分のファイルを出力しておく
# (出力ディレクトリがちと違うので注意。)

open(OUTLST,"> $dir/$outfname$lstext") || die $!;
my $c = 0;
foreach my $f (@sortlist) {
    $f =~ tr/[a-z]/[A-Z]/;
    $f =~ tr/\./_/;
    $f =~ /(.*)_GIF/;
    my $p = $1;
    print OUTLST "\tprivate final int IMG_$p = $c;\t// ", $sizelist[$c],"\n";
    $c++;
}
print OUTLST "\tprivate final int IMG_NUM_MAX = ", $c - 1, ";\n";
close(OUTLST);

exit 0;


本来、java でやったほうが勉強になるのかもしれんけど…。

_2php : DoJa HttpConnection :

2006/02/24追記。バグってた。 :

ヘッダ部分のアドレス算出が2バイト多い。ファイル数を当初4バイトで収めてたのを忘れてた。
# ヘッダ作成
 ...
my $offset = 4 + (($#sizelist + 1) * 8);    # 最初のファイルのオフセット
を、
# ヘッダ作成
 ...
my $offset = 2 + (($#sizelist + 1) * 8);    # 最初のファイルのオフセット
に修正すれば、期待通りの結果を出力してくれるはず。

iモード端末は機種によって通信サイズ制限があるらしい。もしかするとこのままじゃ使えない可能性大。

*1: アプリ本体の .jar に画像等を含ませることもできるけど、アプリ用の容量は10K〜30KByteと少ないので、あっという間に容量オーバーしてしまう。

以上です。

過去ログ表示

Prev - 2006/02 - Next
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project