ページ 11

セーブデータに画像を含める方法

Posted: 2013年7月14日(日) 21:16
by smly
DXライブラリを使用してゲームを作成しています。

現在、ゲームの進行状況をセーブする際にセーブ時のスクリーンショットを取り、これを縮小しセーブデータに含める
方法を探しているのですが、良い方法が見つからないため質問致します。
(ノベルゲームによくある、ロード画面にセーブ時のスクリーンショット一覧が並ぶようなものを実装します)

方針として、GetDrawScreenGraphで画面の情報を取り込み、これをどうにかして縮小し、セーブデータ用の構造体に格納しバイナリデータとして出力したいと考えています。
縮小に使えそうな関数として、DrawExtendGraphやGraphFilterがありますが、DrawExtendGraphは即画面に出力してしまうので、これは保存するには向きません。
またGraphFilterの縮小フィルタでは1/2, 1/4, 1/8のサイズしか指定することができません。
また、仮に上手く希望のサイズに縮小が出来たとしても、それを下記コードの構造体に格納することができません。
(グラフィックハンドルは単なるint型の数値で画像としての意味をもたないため)
また、上手く構造体に格納できたとしても、これを画像として復元する方法がありません。

コード:

//セーブデータ管理用構造体
typedef struct SaveData_tag{
    int id;
    int scenario; //シナリオの進行状況など
    unsigned char *image; //(仮)構造体にイメージデータを格納したい
} SaveData;

SaveData data;
FILE *fp = fopen("save.dat", "wb");
fwrite(&data, sizeof(data), 1, fp);
fclose(fp);
似たような機能を実装する方法として、SaveDrawScreenで画像を縮小せずに保存し、ゲームのロード画面にて縮小して表示する方法が考えられます。
しかしこの方法では、シナリオ進行状況等のデータと画像データが別ファイルになってしまいます。
また、これに目をつぶったとしても、ロード画面を呼び出した際に(セーブデータが複数あれば)複数の画像の縮小表示処理をしなければならないため、
画面表示の際の負荷が非常に高くなってしまいます。

これらの問題を解決して、
1. (可能ならば)シナリオ進行状況などのデータと縮小したスクリーンショットを1つのファイルにまとめる
2. (1が困難であれば)シナリオ進行状況とスクリーンショットは別々のファイルでいいので、スクリーンショットを縮小して保存する

このどちらかの方法を実装したいと思います。
どういった方法にて実装すれば良いのでしょうか。

Re: セーブデータに画像を含める方法

Posted: 2013年7月14日(日) 21:35
by みけCAT
「メモリ上の画像ファイルイメージからグラフィックハンドルを作成する」
CreateGraphFromMem関数があります。
これをうまく使えばデータから画像を復元できるかもしれません。
あ、ポインタをファイルに保存してもほとんど(全く?)意味がないので気をつけてください。

画像をデータ化する方法はSaveDrawScreenで一時ファイルに保存して読み込むくらいしか思いつきませんでした。
もしくはGetPixelで1ドットずつ取得でしょうか?(ネタです)

縮小に関しては、MakeScreenで描画対象を作成し、そこにDrawExtendGraphで描画する方法が考えられます。

Re: セーブデータに画像を含める方法

Posted: 2013年7月14日(日) 21:56
by softya(ソフト屋)
SaveDrawScreenが無難な方法かもしれませんね。
「SaveDrawScreen関数についての質問です」
http://hpcgi2.nifty.com/natupaji/bbs/pa ... ast&no=458

Re: セーブデータに画像を含める方法

Posted: 2013年7月14日(日) 22:07
by smly
みけCAT様, softya(ソフト屋) 様

ありがとうございます。
やはりSaveDrawScreenが無難ですかね。
この方法を使うと、どうしても一時ファイルが出力されてしまいますが、DXライブラリのみで処理を完成させるのであれば
この方法で妥協するのが問題も少なく良いのでしょうか…

SaveDrawScreenで吐き出された画像を一時ファイルとするか、またはこれを暗号化でもするかは迷うところですが、
どちらにせよSaveDrawScreenを使う方向で実装を進めてみたいと思います。

Re: セーブデータに画像を含める方法

Posted: 2013年7月14日(日) 22:16
by softya(ソフト屋)
smly さんが書きました:みけCAT様, softya(ソフト屋) 様

ありがとうございます。
やはりSaveDrawScreenが無難ですかね。
この方法を使うと、どうしても一時ファイルが出力されてしまいますが、DXライブラリのみで処理を完成させるのであれば
この方法で妥協するのが問題も少なく良いのでしょうか…

SaveDrawScreenで吐き出された画像を一時ファイルとするか、またはこれを暗号化でもするかは迷うところですが、
どちらにせよSaveDrawScreenを使う方向で実装を進めてみたいと思います。
あとはDxLibの管理人さんにお願いしてメモリイメージを取得する関数を増やしてもらうぐらいですかね。
bmpに加工する段階で中間データとしては存在しているはずです。

Re: セーブデータに画像を含める方法

Posted: 2013年7月17日(水) 06:07
by smly
softya(ソフト屋) さんが書きました:
あとはDxLibの管理人さんにお願いしてメモリイメージを取得する関数を増やしてもらうぐらいですかね。
bmpに加工する段階で中間データとしては存在しているはずです。
softya(ソフト屋)様

そうですね…どうにかして加工段階のデータを取得できないものかと思ったものですが…
とりあえず一時ファイルとしてbmpを吐き出しても問題のない仕様となったので、今回はこれで対応することとします。
ありがとうございました。

Re: セーブデータに画像を含める方法

Posted: 2013年7月17日(水) 07:35
by beatle
スクリーンショットを保存するのではなく,その時の状態を保存しておいてロード画面で描画する方法もあります.
例えば,その時の背景画像の名前,敵味方の位置,それらの動き方などを保存しておいて,再生します.
この方法のいいところは,ロード画面で動画を流せることです.
何秒間かのプレイヤーからの入力をセーブデータに保存しておくことで,再生時に利用できます.
悪いところは,画像でやるよりプログラムが複雑になる可能性が高いことです.