HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2021
0612
ペルミーパレットカラー変更28解決


ペルミー

リンク

2021/6/12(Sat) 15:40:36|NO.93024

初めて投稿いたします。HSPをやってきて、調べても実装方法にたどり着けないものがあるので質問しに参りました。

画像のカラーを、パレットで変更したいのです。
格闘ゲームのキャラクターにあるような複数のカラーを変えられるような処理をしたいと考えています。
これができれば用意する画像の枚数が減るので大変重宝します。

どのような方法を用いたらいいか糸口さえもつかめておらず、不躾な質問となってしまい大変申し訳ありません。
ご存じの方、手ほどきいただければと存じます。



この記事に返信する


ねんねこ

リンク

2021/6/13(Sun) 17:22:05|NO.93029

こういうことでしょうか?

dialog "",32,""//色変更ダイアログ color ginfo_r,ginfo_g,ginfo_b:boxf//colorで色取得、boxfで背景色変更
サンプルコードをダウンロードできるようにしました↓
https://f.easyuploader.app/20210613171835_63544b53.zip



ねんねこ

リンク

2021/6/13(Sun) 18:13:14|NO.93030

すみません、私の技術では背景色しか変えられません。



youdai

リンク

2021/6/13(Sun) 18:29:39|NO.93032

HSP3で256色パレットモードを扱うモジュールには、HSPDXFIXがあります。
以前はHSP3フルパッケージに同梱されていたのですが、
HSPDXFIXが扱うDirectDrawの環境が古くなったため、
同梱されなくなったという経緯があります。

HSPDXFIX
http://www.hspdx.net/software/

ちなみに動作させるためには、MSVCR71.DLLも必要です。
同サイトで配布されています。

Windows10ではパレットフェード機能が機能していないのですが、
フェード処理はHSP3スクリプトでも制御できるので問題ないと思います。

ちなみに標準HSP3でも256色パレットモードはscreenで指定すれば可能なのですが、
画像処理したい場合は低速なのでおすすめしません。

HSPDXFIXは今のDishのスクリプトの構造の大本になったものだと思います。
非常に扱いやすい良いモジュールだと思います。

Windows10で256色モードのアプリケーションを正常に動作させたい場合、
256色互換モードでアプリケーションを起動させないといけません。
作品を配布したい場合は、Readme等に記述するといいでしょう。



Dirp

リンク

2021/6/13(Sun) 20:44:39|NO.93035

Dripです。

ペルミーさん、こんにちは。
パレットモードでキャラクターの色合いを変更するテクニックは理解すればフルカラーモードで同一の処理をするよりもシンプルで簡潔に書くことができます。
今回はパレットモードの利用方法がわからないとのことでしたので、簡潔さとわかりやすさを最重視したパレットモードを利用したサンプルスクリプトを以下に用意いたしましたので参考にされてください。

screen 0,256,256,1 //パレットモードで画面を初期化 //★ここでパレットの色を設定しています。★ //IDの後に赤、緑、青の色コードが続いていますので、色々いじって変化を確認してみましょう。 palette 0, 200,255,200 //ID:0 背景の色 palette 1, 32,32,32 //ID:1 主線の色 palette 2, 255,255,100, 1 //ID:2 顔の色 //↑顔の色を指定した際に、最後の第五パラメータに1を指定することでここまでのパレットの変更を適用します。 //palette命令の羅列の最後の第五パラメータに1を指定することを忘れないようにしてください。 //指定を忘れるとパレットの変更が反映されません。 //以下、パレットを利用した画像の描画処理です fs=200 //顔の大きさ mgn=30 //左上の余白 palcolor 0 //背景の色を選択 boxf //背景を塗りつぶす palcolor 2 //顔の色を選択 circle mgn,mgn,mgn+fs,mgn+fs //顔を塗る palcolor 1 //主線の色を選択 circle mgn,mgn,mgn+fs,mgn+fs,0 //輪郭を描く //お目目を描く circle mgn+fs/4,mgn+fs/4 , mgn+fs/4+fs/10,mgn+fs/4+fs/5 circle mgn+fs*3/4,mgn+fs/4 , mgn+fs*3/4-fs/10,mgn+fs/4+fs/5 //口を描く circle mgn+fs/4,mgn+fs/2 , mgn+fs*3/4,mgn+fs/2+fs/3 //上唇を肌の色で消す palcolor 2:circle mgn+fs/4,mgn+fs/2-fs/20 , mgn+fs*3/4,mgn+fs/2+fs/3-fs/20
勿論画像ファイルからもイメージを読み込むことができますので最下部に記載させていただいたスレッドの私のサンプルもご確認いただければと思います。

どういうわけだかHSP界隈ではパレットモードに関する間違った情報を散見します。
youdaiさんの投稿には幾つか誤解を招く表現が含まれている気がしますのでご注意ください。

>HSP3で256色パレットモードを扱うモジュールには、HSPDXFIXがあります。

筆頭にこのような一文がありますが、パレットモードは通常、モジュールやプラグインを使用せず標準機能から利用が可能です。
特別な理由がない限り、パレットモードを使うために拡張プラグイン探す必要はありません。

>ちなみに動作させるためには、MSVCR71.DLLも必要です。
>同サイトで配布されています。

外部プラグインを使用しない限りこちらも不要なのでダウンロードの必要はありません。

>ちなみに標準HSP3でも256色パレットモードはscreenで指定すれば可能なのですが、
>画像処理したい場合は低速なのでおすすめしません。

パレットモードを使用した場合、通常の利用方法であれば描画はフルカラーモードより高速になります。
動作速度・描画速度両面の改善を検討されている場合、パレットモードを利用する優位性はかなり高いです。

>HSPDXFIXは今のDishのスクリプトの構造の大本になったものだと思います。
>非常に扱いやすい良いモジュールだと思います。

DirectXを介してディスプレイを256色モードで初期化しハードウェアに直接256色モードでの描画を実行する旧来の(主に90年代に盛んに利用されていた)方法は現代ではあまり一般的ではありません。
ハードウェアの互換性等を配慮し、現代においてこのような利用方法は可能であれば避けるようにしてください。

>Windows10で256色モードのアプリケーションを正常に動作させたい場合、
>256色互換モードでアプリケーションを起動させないといけません。
>作品を配布したい場合は、Readme等に記述するといいでしょう。

パレットモードを使用したアプリケーションをWindows10で実行する場合は通常通り実行して問題ありません。
互換モードにする必要はなく、むしろ256色モードで起動するとディスプレイの表示全体が256色となり正常に機能しなくなる恐れがあります。
恐らくこの一文は旧来のDirectXを用いた256色描画のアプリケーションへの処置と思われますが、HSPの標準機能からパレットモードを利用する場合は関係ありません。
ご注意ください。


パレットモードの基本的な利用方法やパレットモードでどのような事が実現できるのか、本当に動作が高速化するのかなどを確認できる投稿が過去にありますので以下のスレッドの私の書き込みも参考にされてみてください。

http://hsp.tv/play/pforum.php?mode=pastwch&num=88004

ちなみに
「●パレットモードとフルカラーモードを連携させるサンプル」がペルミーさんの仰るキャラクターの部分的な色変えに関するサンプルになります。
「●よりシンプルなサンプル」というサンプルが256色モードの画像の読み込みサンプルです。
パレットモードで画像を読み込む際にありがちなトラブルも踏まえたサンプルですので参考になるかと思います。
もし互換性を配慮しつつ色変えキャラクターをDirectXで動かしたい…というような場合はまた別のアイデアを投入する必要もあるのですが…まず一度パレットモードの扱いに慣れてみてください。



youdai

リンク

2021/6/14(Mon) 12:37:01|NO.93039

自分がHSPDXFIXを勧めた理由は動作パフォーマンスが標準HSP3の256色モードより軽いからです。
DirectDrawはVRAMを用いる一方、HSP3標準の256色モードはメインメモリを用いたはずです。
HSP3標準の256色モードでシューティングやアクションゲームで大量のオブジェクトを出そうとした場合、
この要素がネックとなる可能性が高いです。
画像処理の部分をHSPCL32N等で処理しない限り、
DirectDrawと比較して標準HSP3で描画している限り高速化は見込めないのではないでしょうか?

ただ、互換性についてはDripさんの言う通り、サポートしないグラフィックボードがあります。
互換性を最大限に気にする場合なら、質問の趣旨とは外れてしまいますがパレットモードはありませんがDISHが良いと思います。
これは動作パフォーマンスの面で申し分ないと思います。

Dripさんと自分の意見の違いは何を重視しているかの違いだと思います。
別にDripさんを批判しているわけでも、間違っていると思っているわけでもありません。



Dirp

リンク

2021/6/14(Mon) 18:27:04|NO.93040

こんにちは。

youdaiさん

>Dripさんと自分の意見の違いは何を重視しているかの違いだと思います。

重視というか私は質問の意図をそのまま読み取ったに過ぎないのですが、ペルミーさんの質問は格闘ゲームのキャラクターの色違いを作成するような処理をスクリプトで行い、画像(色違い分の)ファイルを削減したいがその方法がわからない…という趣旨ですよね。
youdaiさんの動作の高速化や旧拡張プラグインの利用、VRAMの話題等は質問の趣旨から離れて行っている気がしています。
Dishをお勧め…というのはもう意味がわからないのですが、Dishでどのように画像ファイルを減らしつつ色変えキャラクターを扱うのでしょうか…?
もしDishを用いた良いアイデアがあれば、hsptvフォルダの画像素材を用いた簡単なDishの部分的な色変えサンプルスクリプトをご提示いただき説明されたほうがyoudaiさんの考えも伝わり易いと思います。



youdai

リンク

2021/6/15(Tue) 07:55:54|NO.93041

>Dishをお勧め…というのはもう意味がわからないのですが、Dishでどのように画像ファイルを減らしつつ色変えキャラクターを扱うのでしょうか…?
動作パフォーマンスと共に互換性も重視した場合、色変えを諦めてDISHを使った方がゲームとしては良いだろうというアドバイスとして書きました。
Dripさんは私の本文を多く誤解されています。
Dripさんとこれ以上議論しても質問の趣旨から離れていくし、そもそも何の意味もないので止めましょう。



窓月らら

リンク

2021/6/15(Tue) 17:56:02|NO.93042

横から。
パレットの操作とは違うのですが、HSP3Dishには gmulcolor命令というものがあります。
制限はありますが、いちおう同一の画像素材を元に色を変えることは可能です。
参考までに、ヘルプを参照してください。



Drip

リンク

2021/6/15(Tue) 19:07:06|NO.93046

こんにちは。Dripです。

>動作パフォーマンスと共に互換性も重視した場合、色変えを諦めてDISHを使った方がゲームとしては良いだろうというアドバイスとして書きました。

色変えについて話しているのにパフォーマンスを重要視して色変えを諦めてDishを使う…というのは主目的と副次目的が逆転してしまっているように思えるのですが、
そもそもDishでも最良のパフォーマンスを維持しながら部分的な色変え描画は可能になりましたから、それを諦めたほうがゲームとしては良いだろう…というのもあまり良いアドバイスではないと思います。
今回はパレットについての理解を深めていただいた上で、最終的にどのような手法で作品制作をされたいかはペルミーさんの意向次第ですので、もし特定のシステムでの実装方法がどうしてもわからないという時にはまた質問いただければ適切なアドバイスが可能かと思います。
ペルミーさんは初めての投稿とのことで、入門的にHSPの基本的なパレットの扱いを学びながら作品制作を楽しみたい…というような場合は先日の私のサンプルが参考になるかと思います。
ぜひ諦めずにがんばってください!


追伸:上の方で自分で自分の名前を書き間違えておりました。
DirpではなくDripです。失礼しました〜^^;



youdai

リンク

2021/6/15(Tue) 19:09:21|NO.93047

>そもそもDishでも最良のパフォーマンスを維持しながら部分的な色変え描画は可能になりましたから、それを諦めたほうがゲームとしては良いだろう…というのもあまり良いアドバイスではないと思います。
パレットモードの構造と同等の色変化による色変えを諦める、という意味です。
通常の方法での色変えを諦めろ、という意味ではありません。



kou

リンク

2021/6/15(Tue) 23:01:52|NO.93048

ペルミーさんは、画像を読み込んで、パレットを変えて、
動かして描画がしたいという事ですかね?
こんなサンプルどうでしょうか。

パレットの上でキーボードのr,g,bを押しながら
マウスホイールを動かしてみてください。
※サンプルがドット絵じゃないので、変化が微妙ですが、
 25番パレットが分かりやすいかも
 画像をお好きな256色のbmpのドット絵に変えてみてください。
 フリーソフトだとEDEGとかで作れます。

格闘ゲーム楽しいですよね。

#include "hsp3util.as" fileName = dir_exe+"\\sample\\game\\face.bmp" // 適当にサンプル画像から、ドット絵の方が分かりやすいかも // ゲーム全体で256に収めパレット番号を合わせる事 //例 0~15:背景, 16~31:1Pキャラ, 32~47:2Pキャラ, 48~63:エフェクト など buffer 1,,,screen_palette //パレットモードでバッファに読み込み bmppalette fileName // パレット読み込み picload fileName,1 // 画像読み込み screen 0,512,256,screen_palette // メイン画面 bmppalette fileName // パレット読み込み *MAIN redraw 1 : await 16 : redraw 0 : palcolor 255 : boxf gosub *PIC_PAL gosub *DRAW_PAL gosub *DRAW_CH goto *MAIN *PIC_PAL // 分かりやすいよう動的に色変え // 選択 if mousex < 256 && mousey < 256 { palNum = mousex/16 + mousey/16*16 } palcolor palNum // 色変え getkey keyR, 82 : getkey keyG, 71 : getkey keyB, 66 wheel = mousew if wheel != 0 { r = ginfo_r : g = ginfo_g : b = ginfo_b if keyR { r = limit(r+wheel, 0, 255) } if keyG { g = limit(g+wheel, 0, 255) } if keyB { b = limit(b+wheel, 0, 255) } palette palNum, r, g, b, 1 } title strf("パレット:%d -> R:%d, G:%d, B:%d", palNum, ginfo_r, ginfo_g, ginfo_b) return *DRAW_PAL // パレット描画 repeat 16 : y = cnt repeat 16 : x = cnt palcolor x+y*16 px = x*16 : py = y*16 boxf px, py, px+16, py+16 loop loop return *DRAW_CH // キャラ描画 gmode 2, 64,64 pos 384, 128 : grotate 1, 0,0, sin(r)/8, 128,128 : r=0.1+r return



ペルミー

リンク

2021/6/17(Thu) 21:11:32|NO.93051

すみません、皆様のおかげで出来たと思って一度解決扱いにしたのですが、さらなる問題が出てしまい、もう一度質問に参りました。

画像1を用意し、それをedgeで色違いにした画像2をも用意し、
画像2の256色に画像1のパレットをすげかえる…ということがしたいのですが、どうやら近似色を巻き込んでしまう?ことがあるようなのです…

ソースはこのような感じです

dim pcolor,256,3 screen 0,640,480 screen 1,,,1 bmppalette 画像1 screen 2,,,1 bmppalette 画像2 repeat 256 palcolor cnt pcolor(cnt,0) = ginfo_r pcolor(cnt,1) = ginfo_g pcolor(cnt,2) = ginfo_b loop gsel 1 repeat 256 palette cnt,pcolor(cnt,0),pcolor(cnt,1),pcolor(cnt,2),1 loop gsel 0 pos 0,0 : gmode 0 gcopy 1,0,0,640,480

このようにしています。
概ね動くのですが、時々近い色がパレットに残っている場合、対応する番号の色で置き換えられるはずがうまくいかないことがあります。
palcolorでパレットの番号で指定していますから、そのようなことはあるはずがないと思うのですが…
よろしければご教示願えませんでしょうか。



ペルミー

リンク

2021/6/17(Thu) 21:13:20|NO.93052

追記
bmppalette 画像1
の下に
picload 画像1
が抜けておりました。



kou

リンク

2021/6/17(Thu) 22:39:01|NO.93053

私のテストだと問題が再現できなかったのですが、
screen2から値を取らず、直接パレットを置き換えてみてもダメそうでしょうか?


#include "hsp3util.as" screen 0,640,480 screen 1,,,1 bmppalette "EDGE1.bmp" picload "EDGE1.bmp", 1 bmppalette "EDGE2.bmp" //パレット置き換え用の画像 //redraw 1 gsel 0 pos 0,0 : gmode 0 gcopy 1,0,0,640,480



ペルミー

リンク

2021/6/18(Fri) 02:44:12|NO.93055

ああ、できました!ありがとうございました!
bmppaletteのタイミングがちょっとややこしいですね…これを挟む場所を変えてみたら思い通りに動きました。
皆様本当にありがとうございました。お陰様で作りたいものが作れそうです。重ねてお礼申し上げます。



Drip

リンク

2021/6/18(Fri) 02:45:49|NO.93056

こんにちは。

ペルミーさん

>概ね動くのですが、時々近い色がパレットに残っている場合、対応する番号の色で置き換えられるはずがうまくいかないことがあります。

恐らくこれはパレットモードで混乱しやすいポイントです。
ご指摘の通り、HSPでは256色モードのbufferへ画像を読み込む際にパレットIDをそのままロードせず、bufferで定義されたパレットの近似色へのパレット再割り当てが行われてしまうという仕様があります。
しかも一致するパレットカラーがあったとしても、別のパレットに非常に似た色が存在する場合、必ずしも最も近い色に設定されない可能性がある事にも注意を払う必要があるのです。
kouさんとペルミーさんでは共通の画像で実験していないため、kouさんは同じ症状を確認できなかった可能性が考えられます。
パレットモードを扱っている際、もしも目的のパレットに別のパレットIDが割り当てられてしまう…というような場合は似たような色がパレットに存在していないか再確認してみてください!

追伸:
ご提示されたスクリプトではpalette命令の第五パラメータが常時1のようですが、最後の1回だけ1になるように工夫してみてください。
また、パレット定義後に新たにbufferを生成した場合、以前のパレットを継承して生成されるので、同じパレットを持つバッファの場合は都度パレットを読み込む必要はありません。
ちなみに、ファイルからの画像読み込みではなく、パレットバッファ→パレットバッファへの画像コピーにおいて、gmode 1またはgmode 2を指定した場合は近似色の再割り当ては発生せず、パレットの単純コピーが行われます(コピー先のパレットカラーが全く違っていても画素のパレットIDがそのままトレースされます)。
参考にしていただければ幸いです。



Drip

リンク

2021/6/18(Fri) 02:48:11|NO.93057

あらら…文章を修正したらペルミーさんと返信の順序が入れ替わってしまいました^^;
失礼しました〜



ペルミー

リンク

2021/6/18(Fri) 02:50:36|NO.93058

Dripさん

kouさんの書いてくださったものを参考にしてみたらこの現象はいちおう収まったのですが(画像の方を変更すること無くして)、
今回はこの現象を何かしら解決できたと考えてよいのではないかと思っているところです。
しかしDripさんの仰っしゃりようだとこれはHSPの仕様の問題で、画像の方で気をつけることでしか対処のしづらいものという旨であるように読み取れます。
この現象の解決の鍵としては、何がいちばん大事なことだったのでしょうか?



Drip

リンク

2021/6/18(Fri) 03:44:56|NO.93060

度々失礼します。

ペルミーさん

一先ず問題が解決したようで良かったです。

>これはHSPの仕様の問題で、画像の方で気をつけることでしか対処のしづらいものという旨であるように読み取れます。
>この現象の解決の鍵としては、何がいちばん大事なことだったのでしょうか?

ペルミーさんが使用されている画像とスクリプトでテストしてみないことには問題の原因を断言することができないのですが、近似色がパレットに存在する場合、picloadやgmode 0によるコピーでは厳格なパレットIDのコピーが行われない可能性を常に意識する必要があります。(これは私の見立てですので、今回の問題とは無関係の可能性も有り得る事をご了承願います。)
例えば以下のスクリプトでは同じ画像のコピーを行っているのに結果が変わってしまいます。

//性質の違うコピー元の画面を2つ生成 screen 2,256,256:title "フルカラーモード" gradf 0,0,256,256,0,$000000,$FFFFFF color 255,0,0:pos 0,110:mes "コピー元(ID:2):\nフルカラーモード" screen 3,256,256,1,ginfo(4),ginfo(5)+256:title "パレットモード" repeat 256:palcolor cnt:line cnt,256,cnt,0:loop pos 0,110:mes "コピー元(ID:3):\nパレットモード" //※ちなみにパレットモードではデフォルトで綺麗なグレースケールがデフォルトのパレットになっています。 //コピー先の画面 screen 0,640,480,1,ginfo(4)+280,ginfo(5)-256:title "この画面は パレットモード!" gmode 0,256,100:gcopy 2,0,0 pos 10,110:mes "フルカラースクリーン → パレットスクリーン コピー時\nパレットIDの割り当てが厳密でないため、低品質なグラデーションになってませんか?" pos 0,200 //↓この行を有効にするとグラデーションの最初が赤くなる。でも次の行のgmode 1をgmode 0にすると近似色コピーのため赤くならない ;repeat 100:palette cnt,255,0,0,(cnt=99):loop gmode 1,256,100:gcopy 3,0,0 pos 10,310:mes "パレットスクリーン → パレットスクリーン コピー時\ngmode 1(2)でコピーすれば厳密なパレットコピーが行われます!綺麗ですね!"

私もpicloadやcelload使用時、厳密なパレットの割り当てによる読み込みモードも用意して欲しいと思ってはいるのですが、残念ながら今のところHSPでは対応されないみたいです。
またパレットモードを扱う場合、どのパレットがどういう意味を成すのか、自分でしっかり管理しながらスクリプトを書かないと、あとから大混乱することになってしまいます。
HSPで使用するかどうかに関係なく、256色画像をパレットモードで扱う場合はパレットの管理を徹底して行ってください。
ちなみに、上記のサンプルでも単に最後のgmode 1をgmode 0で近似色コピーを行った場合、一見綺麗なグラデーションにはなるのですが、この場合はフルカラー→パレットへのコピー時とはちょっと異なるロジックで近似色の割り当てが行われているようです。
色々試しながら問題の原因を探ってみてください!



Drip

リンク

2021/6/18(Fri) 04:18:15|NO.93061

色々書いてしまいましたが、今回はbmppaletteの配置を変えたら解決したとのことですので、単にパレットの割り当てタイミングが失敗していただけという線が濃厚かもしれません^^;
bmppalette命令はHSPのcommonフォルダのhsp3util.as内で定義されている命令ですので、自前でpaletteを定義するのと何ら違うものではありません。
もし興味がありましたらhsp3util.asを実際に覗いてみてください。



MIZUSHIKI

リンク

2021/6/18(Fri) 06:56:37|NO.93062

Dripさん
>近似色がパレットに存在する場合、picloadやgmode 0によるコピーでは厳格なパレットIDのコピーが行われない可能性を常に意識する必要があります。

それは フルカラー(1677万色) → パレットモード(256色) に変換しているから起こるのではないでしょうか?


ペルミーさんもEDGEで用意したであろう8bitBMP画像を読み込む場合は、

 パレットモード(8bitBMP読込) → パレットモード(もしくはフルカラーウィンドウ先でもOK)

になるため特別に何かを意識することなくパレットの色変え等の管理ができるのではないでしょうか。


8bitBMPと24bitBMPのグラデーション画像を用いて実験してみました。
以下2つのファイルをダウンロードしてから実行してください。
http://suwa.pupu.jp/data/24bit_gure.bmp
http://suwa.pupu.jp/data/8bit_gure.bmp
(リンクを右クリック>名前を付けて画像を保存)


#include "hsp3util.as" //性質の違うコピー元の画面を2つ生成 screen 2,256,256:title "フルカラーモード" //gradf 0,0,256,256,0,$000000,$FFFFFF ; ←元の描画スクリプトをコメントアウトして picload "24bit_gure.bmp",1 ; ←24bit(フルカラー)グレーグラデーション画像のロードに差し替え color 255,0,0:pos 0,110:mes "コピー元(ID:2):\nフルカラーモード - 24bitBMP読み込み" screen 3,256,256,1,ginfo(4),ginfo(5)+256:title "パレットモード" //repeat 256:palcolor cnt:line cnt,256,cnt,0:loop ; ← 元の描画スクリプトをコメントアウトして bmppalette "8bit_gure.bmp" ; ← 一応パレット情報も読み込み picload "8bit_gure.bmp",1 ; ← 8bit(256色)グレーグラデーション画像のロードに差し替え pos 0,110:mes "コピー元(ID:3):\nパレットモード - 8bitBMP読み込み" //※ちなみにパレットモードではデフォルトで綺麗なグレースケールがデフォルトのパレットになっています。 //コピー先の画面 screen 0,640,480,1,ginfo(4)+280,ginfo(5)-256:title "この画面は パレットモード!" gmode 0,256,100:gcopy 2,0,0 pos 10,110:mes "フルカラースクリーン → パレットスクリーン コピー時\nパレットIDの割り当てが厳密でないため、低品質なグラデーションになってませんか?" mes "(24bitBMP読み込み)" pos 0,200 //↓この行を有効にするとグラデーションの最初が赤くなる。でも次の行のgmode 1をgmode 0にすると近似色コピーのため赤くならない ;repeat 100:palette cnt,255,0,0,(cnt=99):loop gmode 1,256,100:gcopy 3,0,0 pos 10,310:mes "パレットスクリーン → パレットスクリーン コピー時\ngmode 1(2)でコピーすれば厳密なパレットコピーが行われます!綺麗ですね!" mes "(8bitBMP読み込み)" mes "" objsize 250 button "試しに100番パレットだけ赤にする", *irokae stop *irokae palette 100,255,0,0,1 redraw 1 stop
グラデーションも問題なさそうに見えます。
試しに100番だけ赤にしてみても(下のパレ→パレは)1pxだけの赤い線になりました。

※ 8bitBMPになっているかの確認は、エクスプローラで ファイルを右クリック>プロパティ>詳細>ビットの深さ で分かります。
  (詳細表示にして カラムを右クリック>ビットの深さを追加 すると一覧で見れます。)

オマケ

#module #deffunc gifpalette str file //gif版のpalette情報読み込み exist file :if strsize<780 :return sdim a,781 : bload file,a,780 b=2 : repeat (peek(a,10)>>5)&7 : b*=2 : loop repeat b : palette cnt,peek(a,13+cnt*3),peek(a,14+cnt*3),peek(a,15+cnt*3), (cnt==b-1) : loop return #global



Drip

リンク

2021/6/18(Fri) 19:14:27|NO.93064

こんにちは。

MIZUSHIKIさん

>それは フルカラー(1677万色) → パレットモード(256色) に変換しているから起こるのではないでしょうか?

いいえ、画像ファイルと同一のパレットを持つバッファ上でも厳格なパレットIDの割り当てが行われない場合があります。

画像ファイル上では別々のパレットIDなのに若いパレットIDに古いパレットIDと同一の色を持つパレットが存在する場合では、画像を読み込んだ際に古いパレットIDは若いパレットIDに再割り当てされてしまいます。(パレットモードのバッファに同一のパレットを持つ256色のbmpファイルを読み込んだ場合でもです。)
なので例えば若いパレットIDに空の背景、古いパレットIDにセーラー服のキャラクターの色を置いて描いていた場合、空の水色とセーラー服の水色が一致してしまい、セーラー服の色替えを行おうとしても色が変わらない(あるいはパレット変更時に別の物の色が同時に変わってしまう)…という現象が発生してしまうのです。

またHSPはパレットモードのバッファに256色png画像をロードできないという問題をかかえています。
これを回避するために、一旦256色png画像ファイルをフルカラーのバッファにロードした上で、その画像をパレットモードのバッファにgmode 0で転送するというやり方を執らざるを得ないのですが、パレットモードのバッファにはpngファイルと同一のパレットがあるのだから大丈夫だろう…と油断していると近似色の割り当てが不正確なために意図せずパレットIDが狂ってしまう、という状況が発生してしまいます。
一見すると今回は関係無さそうですが、ペルミーさんの提示されたスクリプトは画像ファイルが不確定で、256色モードとフルカラーモードが共存し、全てのパレットを事前に変数にコピーして自前で割り当てようとする操作があったこと、

>概ね動くのですが、時々近い色がパレットに残っている場合、対応する番号の色で置き換えられるはずがうまくいかないことがあります。

という一文からも、上記のようなパレットIDの意図せぬ割り当てがどこかで発生してしまった状況が考えられました。
(私の前回の説明文では画像読み込み時の説明が的確でなく、混乱を招いてしまったかもしれません。説明が悪く申し訳ありませんでした。)

念のため、同一のパレットを持つバッファに256色画像をロードをしているのにも関わらず正しくパレットIDが割り当てられないサンプルを以下に示します。
生成される画像をドット絵エディタで見たときとHSPで表示したときの違いをご確認いただければと思います。
尚、便宜上アップローダは使いたくなかったため、素材となるbmpファイルをスクリプトからデスクトップに2枚生成してそれを読み込む仕組みにさせていただきました。(動作の整合性をWindows7、Windows10の二機で確認いたしました。)
テストを終えましたらデスクトップ上の2ファイルを手動で削除願います。

//──────────────────────────────────────────── //予めデスクトップに「paletteTestImage0.bmp」「paletteTestImage1.bmp」の2枚を作成します。 //この2枚はパレットカラーが違うだけの同一のパレットIDで模様を描いた画像データです。 //──────────────────────────────────────────── buffer 3,128,128,1 //パレットバッファ作成 //パレットID56を下地に、パレットID57〜59で円を3つ描いた画像を作成する //※近似色パレットを作成したあとから図形を描くと厳密なパレットIDの色を選択できなくなるため先に模様を描く。 palcolor 56:boxf //ID:56 下地 palcolor 57:circle 0,0,64,64 //ID:57 左上の丸 palcolor 58:circle 64,0,128,64 //ID:58 右上の丸 palcolor 59:circle 0,64,64,128 //ID:59 左下の丸 repeat 256:palette cnt,0,0,0:loop //パレットクリア //システム予約色定義 (ドット絵エディタEDGE初期パレットの配置に準拠) palette 1,128,0,0:palette 2,0,128,0:palette 3,128,128,0:palette 4,0,0,128 palette 5,128,0,128:palette 6,0,128,128:palette 7,192,192,192:palette 8,192,220,192 palette 9,166,202,240:palette 246,255,251,240:palette 247,160,160,164:palette 248,128,128,128 palette 249,255,0,0:palette 250,0,255,0:palette 251,255,255,0:palette 252,0,0,255:palette 253,255,0,255 palette 254,0,255,255:palette 255,255,255,255 //グラデーション作成 gr=255.0,255.0,179.0 , 214.0,248.0,255.0 //グラデーションの2色を定義 repeat 224 palette 16+cnt,gr(0)+(gr(3)-gr(0))*cnt/223,gr(1)+(gr(4)-gr(1))*cnt/223,gr(2)+(gr(5)-gr(2))*cnt/223 loop palette 0,0,0,0,1 //パレット更新 bmpsave dir_desktop+"\\paletteTestImage0.bmp" //近似色が沢山存在する1枚目の画像を保存する //最初に描いた画像で使用するパレットだけを見やすい色に変更して2枚目の画像を保存する palette 56,210,230,240:palette 57,200,100,100 palette 58,000,200,000:palette 59,100,100,200 ,1 bmpsave dir_desktop+"\\paletteTestImage1.bmp" //──────────────────────────────────────────── //今作成した2枚の画像を読み込んで表示テストを行います。 //──────────────────────────────────────────── #include "hsp3util.as" screen 0,800,400,1 pos 50,50 mes "2枚の画像を交互に表示します。" mes "2枚の画像はパレットの色が違うだけの同一の画像です。" mes "パレットID 56の下地にパレットID57〜59を使用した3つの丸が描かれています。" mes "palette命令で色を統一しているため、↓の画像は変化しないはずですが…?\n" repeat bmppalette dir_desktop+"\\paletteTestImage"+(cnt\2)+".bmp" //パレット適用 picload dir_desktop+"\\paletteTestImage"+(cnt\2)+".bmp",1 //画像読み込み //使用色すべてのパレットを統一する palette 56,240,140,240 //下地 palette 57,255,0,0 //左上の丸 palette 58,0,255,0 //右上の丸 palette 59,0,0,255 , 1 //左下の丸 + パレット更新 redraw 1:await 1000 //画面更新とアイドル loop

参考にしていただければ幸いです。



kou

リンク

2021/6/18(Fri) 21:00:52|NO.93066

Dripさん

うわ、ホントだ、円が消えますね。気持ち悪い挙動ですね。
先の私のテストだと、近似色との情報だったので、赤のグラデーション使ってみたのですが
一致した色が複数あると、カオスになる感じなのですかですかね。


ペルミーさん
bitマップで良ければ、自前で読み込んだ方が早いかもです。
画像の事も考慮しなくてよいので楽です。21:00 2021/06/18

#module #deffunc bmpload str _fname exist _fname :if strsize = -1 : dialog "画像ファイルがありません" : return sdim bmp, strsize : bload _fname, bmp if peek(bmp,$1c)>8 :return if wpeek(bmp,0)!$4d42 :return w = wpeek(bmp,$12) : h = wpeek(bmp,$16) mref bmscr, 67 if bmscr.3 != 1 : dialog "パレットモードで初期化しなおします",2 : if stat == 7 : return if bmscr.17 == 1 { buffer bmscr.18, w, h, 1 } else { screen bmscr.18, w, h, 1 } i=$36 repeat 256 : palette cnt,peek(bmp,i+2),peek(bmp,i+1),peek(bmp,i), cnt==255 : i+=4 : loop mref vram, 66 i=$436 repeat length(vram) : vram.cnt = lpeek(bmp, i+cnt*4) : loop redraw 1 : dim bmp,0 return #global bmpload "EDGE1.bmp"

MIZUSHIKIさんに触発されて私もオマケ
gifってそうなってるんですね勉強になりました。
※近似色問題は解決しませんが。。。

#module #deffunc pngpalette str file //png版のpalette情報読み込み(簡易版IHDR->PLTEとチャンクが並んでいる事) exist file : if strsize<$330 :return sdim a, $331 : bload file, a, $331 if wpeek(a,$18) != $0308 : return // 8bitインデックスカラーでなかったらreturn if lpeek(a,$25) != $45544C50 : return // PLTEチャンクでなかったらreturn repeat 256 : palette cnt, peek(a,$29+cnt*3), peek(a,$2A+cnt*3), peek(a,$2B+cnt*3), cnt==$FF : loop return #global #include "mod_img.as" screen 0,512,256,screen_palette // メイン画面 pngpalette "EDGE1.png" imgload "EDGE1.png"



MIZUSHIKI

リンク

2021/6/18(Fri) 21:01:38|NO.93067

Dripさん

おぉ!なるほど確かに
>画像ファイル上では別々のパレットIDなのに若いパレットIDに古いパレットIDと同一の色を持つパレットが存在する場合では、画像を読み込んだ際に古いパレットIDは若いパレットIDに再割り当てされてしまいます。
の現象が確認できました。

・paletteTestImage0.bmp
・paletteTestImage1.bmp
両者はバイナリエディタで見てもカラーパレット以外のデータは同一でした。

Image0.bmpのカラーパレットが
 ・パレット55,56,57 : R=247,G=253,B=192
 ・パレット58,59 : R=247,G=253,B=193
のため、picload後のVRAMを覗いてみると、
56と57の部分が吸われて55になっており、59も吸われて58になっている様子でした。

ということは、ペルミーさんに気を付けてもらう回避策としては、
 ・画像を作成する際に、EDGEのカラーパレットウィンドウの メニュー>パレット>検索>重複した色 を使用してもらって、重複した色のパレットがないか確認してもらう。

といったところでしょうか。

(もしくは誰か頑張れる人が、VRAMを操作して直接BMPのバイナリを貼り付けられるモジュールを生みだs



MIZUSHIKI

リンク

2021/6/18(Fri) 21:19:05|NO.93068

>(もしくは誰か頑張れる人が、VRAMを操作して直接BMPのバイナリを貼り付けられるモジュールを生みだs

投稿タッチの差で、もうkouさんがVRAM貼り付け版を生み出しちゃってますね。
確認してみましたが、

bmpload dir_desktop+"\\paletteTestImage0.bmp" //使用色すべてのパレットを統一する palette 56,240,140,240 //下地 palette 57,255,0,0 //左上の丸 palette 58,0,255,0 //右上の丸 palette 59,0,0,255 , 1 //左下の丸 + パレット更新 redraw 1 //画面更新
は問題なく機能するようです。

あとはpicloadのようにオプションでウィンドウ初期化じゃなく好きな位置に置k



kou

リンク

2021/6/19(Sat) 00:09:29|NO.93069

あっ、読み込みで使うなら愚直にループで回すより、
メモリーコピーした方が処理速度的によいですね。
※VRAMがBITMAPと同じ横4の倍数制限なのでHSPは簡単で助かる

//repeat length(vram) : vram.cnt = lpeek(bmp, i+cnt*4) : loop memcpy vram, bmp, varsize(vram), 0, $436



ペルミー

リンク

2021/6/20(Sun) 05:41:10|NO.93082

皆様詳しくありがとうございます…!
一応全部拝見したのですが、難しくて途中からついていけなくなってしまった次第です…
ありがとうございました!

kouさんのモジュールのほうが不具合が少なくなるかもしれませんね…!?機を見て導入を試してみます。



d4639

リンク

2021/7/8(Thu) 14:05:44|NO.93181

初投稿させてもらいます。似たようなことをやったことがあるので、
私も素人ですが、質問者の知りたいところはこんな感じかと思います

要点だけ

*準備

  mref ppp,69 ;このpppをbsaveしたのち編集し下のファイルにしています   sdim ppp1,256*3 ;sdimは8bitで管理できるので便利です   bload "pal1.dat",ppp1,256*3 ;パレット情報ファイル、色違い分(pal2,pal3,..)用意しインクルードしてしまえ

*実行 

if palette_sw {    memcpy ppp,ppp1,256*3 palette ,,,,1 redraw 1 }
一瞬で切り替わります

256*3ではなく32*3のように一部切り替えでも可能だったかも知れません(そっちが主流?)
画像やパレット情報は違うプログラムで先に処理しておくことが妙味かと



ONION software Copyright 1997-2023(c) All rights reserved.