自由研究「画像:重さVSサイズ」
tyranoscriptで、処理がのっそりします。
原因はわかっています。
動作に必要なpng画像が2500*5400pxの2.70Mだからです。
ちな現在のパソコンは3Dビルドができる化け物スペックです。
最適解は
「必要最小限のサイズに抑えて、重さも最低限にする」
なのはわかり切ってるのですが、どちらがより効率的なのか検証します。
合わせてどうぞ
環境説明
tyranoscriptV522a(2023/12/19)
縦長の着せ替えゲーム(W720H1280)
ウィンドウ表示では動作に支障なし
フルスクリーンで軽微なラグ
モニターを縦長にしてフルスクリーンで多大な処理落ち(最悪フリーズ)
コード解説
キャラ差分機能でheight="&1280*2" width="&594*2"の特大画像を表示
[glink]のexp自体にstyle.jsのc関数を発動する仕組み
ボタンを押すことで表情と服装が変化する。
[chara_config]設定と#で、変更後に画像が跳ねる。
main.ks
[chara_new name="hoge" storage="_chara/hoge/transparent.png" ]
;b_hair
[chara_layer name="hoge" part="b_hair" id="b_hair" storage="_chara/hoge/b_hair/b_hair.png" zindex="1" ]
[chara_layer name="hoge" part="b_hair" id="none" storage="none" zindex="1" ]
;body
[chara_layer name="hoge" part="body" id="body0" storage="_chara/hoge/body/body0.png" zindex="2" ]
[chara_layer name="hoge" part="body" id="body1" storage="_chara/hoge/body/body1.png" zindex="2" ]
[chara_layer name="hoge" part="body" id="none" storage="none" zindex="2" ]
;neck
[chara_layer name="hoge" part="neck" id="neck" storage="_chara/hoge/neck/neck.png" zindex="3" ]
[chara_layer name="hoge" part="neck" id="none" storage="none" zindex="3" ]
;s_hair
[chara_layer name="hoge" part="s_hair" id="s_hair" storage="_chara/hoge/s_hair/s_hair.png" zindex="4" ]
[chara_layer name="hoge" part="s_hair" id="none" storage="none" zindex="4" ]
;head
[chara_layer name="hoge" part="head" id="head" storage="_chara/hoge/head/head.png" zindex="5" ]
[chara_layer name="hoge" part="head" id="none" storage="none" zindex="5" ]
;face
[chara_layer name="hoge" part="face" id="nml" storage="_chara/hoge/face/nml.png" zindex="6" ]
[chara_layer name="hoge" part="face" id="ang" storage="_chara/hoge/face/ang.png" zindex="6" ]
[chara_layer name="hoge" part="face" id="ejy" storage="_chara/hoge/face/ejy.png" zindex="6" ]
[chara_layer name="hoge" part="face" id="sad" storage="_chara/hoge/face/sad.png" zindex="6" ]
[chara_layer name="hoge" part="face" id="tre" storage="_chara/hoge/face/tre.png" zindex="6" ]
[chara_layer name="hoge" part="face" id="unq" storage="_chara/hoge/face/unq.png" zindex="6" ]
[chara_layer name="hoge" part="face" id="wow" storage="_chara/hoge/face/wow.png" zindex="6" ]
[chara_layer name="hoge" part="face" id="none" storage="none" zindex="6" ]
;op
[chara_layer name="hoge" part="op" id="spear" storage="_chara/hoge/op/spear.png" zindex="7" ]
[chara_layer name="hoge" part="op" id="none" storage="none" zindex="7" ]
;===
[loadjs storage="../scenario/script.js" ]
[chara_config talk_anim="up"]
[chara_show name="hoge" height="&1280*2" width="&594*2" top="-200" ]
;===
[glink x="10" y="&100+50*0" text="装備2に変更" target="*done" exp="c('body','body1');tf.bd=1;"]
[glink x="500" y="&100+50*0" text="基本" target="*done" exp="c('face','nml');"]
[glink x="500" y="&100+50*1" text="怒り" target="*done" exp="c('face','ang');"]
[glink x="500" y="&100+50*2" text="楽し" target="*done" exp="c('face','ejy');"]
[glink x="500" y="&100+50*3" text="悲し" target="*done" exp="c('face','sad');"]
[glink x="500" y="&100+50*4" text="照れ" target="*done" exp="c('face','tre');"]
[glink x="500" y="&100+50*5" text="唯一" target="*done" exp="c('face','unq');"]
[glink x="500" y="&100+50*6" text="驚き" target="*done" exp="c('face','wow');"]
[s ]
;===
*done
[stop_keyconfig]
[cm ]
#hoge
[glink x="10" y="&100+50*0" text="装備2に変更" target="*done" cm="true" exp="c('body','body1');tf.bd=1;" cond="tf.bd!=1" ]
[glink x="10" y="&100+50*0" text="装備1に変更" target="*done" cm="true" exp="c('body','body0');tf.bd=0;" cond="tf.bd!=0" ]
[glink x="500" y="&100+50*0" text="基本" target="*done" exp="c('face','nml');"]
[glink x="500" y="&100+50*1" text="怒り" target="*done" exp="c('face','ang');"]
[glink x="500" y="&100+50*2" text="楽し" target="*done" exp="c('face','ejy');"]
[glink x="500" y="&100+50*3" text="悲し" target="*done" exp="c('face','sad');"]
[glink x="500" y="&100+50*4" text="照れ" target="*done" exp="c('face','tre');"]
[glink x="500" y="&100+50*5" text="唯一" target="*done" exp="c('face','unq');"]
[glink x="500" y="&100+50*6" text="驚き" target="*done" exp="c('face','wow');"]
[start_keyconfig]
[s ]
script.js
function c(part,nm){
switch (true){
case part=='op':
tyrano.plugin.kag.ftag.startTag("chara_part", {name:"hoge",op:nm,time:"50",wait:true} );
break;
case part=='body':
tyrano.plugin.kag.ftag.startTag("chara_part", {name:"hoge",body:nm,time:"50",wait:true} );
break;
case part=='face':
tyrano.plugin.kag.ftag.startTag("chara_part", {name:"hoge",face:nm,time:"50",wait:true} );
break;
case part=='b_hair':
tyrano.plugin.kag.ftag.startTag("chara_part", {name:"hoge",b_hair:nm,time:"50",wait:true} );
break;
case part=='co':
tyrano.plugin.kag.ftag.startTag("chara_part", {name:"hoge",co:nm,time:"50",wait:true} );
break;
};
}
なお、必要最低限までコードを簡略化した。
[glink]じゃなくて[button]だとこんな長い必要はないです。
計測方法
performance.now()で計測します。
[glink]のexpに加えて、[s]直前で計測します。
main.ks
略
[glink 略 exp="tf.st= performance.now();c('body','body1');tf.bd=1;" cond="tf.bd!=1" ]
[glink 略 exp="tf.st= performance.now();c('body','body0');tf.bd=0;" cond="tf.bd!=0" ]
略
[iscript ]
tf.gl= performance.now()
;alertでも可
console.log(tf.gl-tf.st);
[endscript ]
[s ]
計測結果
2500*5400pxの2.70M(初期)
ウィンドウサイズ
中央値(10回計測):23.0075
フル(横)
中央値(10回計測):23.2375
フル(縦)
中央値(10回計測):187.425
なお、計測後に跳ねるアニメと服の変更アニメが走ったので
それを含めるとまったく正確ではないです。縦は体感10000msぐらい。
[wait]や[wa]でアニメーション終了まで無理やり伸ばしましたが大して変化はないです。
サイズ1/2(1200*2700,890kb)
表示させているサイズは1/2でも補えるので1/2にリサイズして計測します。
ウィンドウサイズ
中央値(10回計測):22.41(-0.597500002)
フル(横)
中央値(10回計測):21.29(-1.947500001)
フル(縦)
中央値(10回計測):21.9325(-165.4925)
同じく計測後に跳ねるアニメと変更アニメが走っていますが。
アニメの遅延はほぼ感じません。縦でも500msないぐらい。
重さ1/6.4(2500*5400px,430kb)
png-8(254色)で書き出してみます。
ウィンドウサイズ
中央値(10回計測):23.93999999(+0.932499992)
フル(横)
中央値(10回計測):24.595(+1.357500005)
フル(縦)
中央値(10回計測):166.4525(-20.9725)
計測後の処理が初期と変わらず。
なんなら初期より遅い傾向があり、半透明部分が白にしたので見た目も悪いです。アニメーションの遅延も初期と同じぐらい。
結論
画像のサイズが描写時間に大いに関係があることがわかりました。
分かり切っていたことですが、やってみると面白いですね。
とかく、画像の解像度をなるべく抑えましょう。
おまけ
画像を必要半分サイズで、[chara_show]で2倍サイズにする。
1/4(630*1360px,290kb)
ウィンドウサイズ
中央値(10回計測):21.6(-1.4075,+21.0025)
フル(横)
中央値(10回計測):23.385(+0.147500003,+21.4375)
フル(縦)
中央値(10回計測):24.1725(-163.2525,-141.32)
初期と、サイズ1/2の結果と比べています。
縦型ゲームなので縦フルサイズが最も大きく画像が表示されます。
より大きく表示されるほど、処理時間のブレが大きいです。
ということで
「必要最小限のサイズに抑えて、重さも最低限にする」
の裏付けでした。
最終的に低スぺパソコンや、スマホなどの環境で試して調整は必要でしょうけども。
おわり。