【解決済み】画像ファイルが存在してなくてもエラーにならないようにしたい

アバター
にゃたま
記事: 837
登録日時: 2016年1月13日(水) 23:53
お住まい: 床下の猫王国-すみませんが体調悪いのでサポートはお休みさせていただきます
連絡を取る:

【解決済み】画像ファイルが存在してなくてもエラーにならないようにしたい

投稿記事by にゃたま » 2021年9月23日(木) 19:59

var bitmap = this.loadBitmap('img/', filename, hue, false);
画像ファイルを上記のようにloadBitmapで読み込んだ時、その画像ファイルが存在しないときに
「Loading Error Failed to load: アイテムのURL」となりエラーになりますが
loadBitmapする直前にファイルが存在しているかどうかを取得、判定すれば
このようなエラーを回避できると思うのですがそういう関数は存在するのでしょうか?
〇〇という画像がpictureフォルダにないときに▼▼という画像を表示するというイメージです。
最後に編集したユーザー にゃたま on 2021年9月30日(木) 14:06 [ 編集 1 回目 ]

名無し蛙
記事: 305
登録日時: 2015年11月23日(月) 02:46

Re: 画像ファイルが存在してなくてもエラーにならないようにしたい

投稿記事by 名無し蛙 » 2021年9月24日(金) 04:25

どうもこんばんは
ファイル(フォルダ)の存在可否についてはこの方法を使えば可能です

コード: 全て選択

const fs = require('fs');
console.log(fs.existsSync("img/faces/Actor1.png")); // true

ただこれには一つ欠点があり、
リリース時にimgフォルダを暗号化した時に正しい情報を得られないと思います。
コアスクリプト内でも使用していますけどStorageManager(セーブファイルの取り扱い)に関する物に留めています。
try-catchを使用するにしてもロードの予約をしているだけなのでエラーをcatchする事は出来ません。

結論を言えばトリアコンタン氏がそれ用のプラグインを作成しているので利用するのが無難ですね。
ロード失敗エラーのすり抜けプラグイン
https://triacontane.blogspot.com/2016/06/blog-post_10.html
アバター
にゃたま
記事: 837
登録日時: 2016年1月13日(水) 23:53
お住まい: 床下の猫王国-すみませんが体調悪いのでサポートはお休みさせていただきます
連絡を取る:

Re: 画像ファイルが存在してなくてもエラーにならないようにしたい

投稿記事by にゃたま » 2021年9月24日(金) 23:56

名無し蛙様

助言いただき誠にありがとうございました。

名無し蛙 さんが書きました:const fs = require('fs');


こちらについて試してみましたが恥ずかしながら宣言の場所がわからず
const fs = require('fs');
console.log(fs.existsSync("img/faces/Actor1.png")); // true
と続けてみましたがrequire is not definedというエラーになってしまいます。
宣言の場所が決まっているのでしょうか?

名無し蛙 さんが書きました:ただこれには一つ欠点があり、
リリース時にimgフォルダを暗号化した時に正しい情報を得られないと思います。


これにつきましてはフォルダを暗号化する予定は現在のところなく
アツマールにアップすることを想定していますがこちらで動けば問題ありません。
つまりローカル環境でのテスト時及びアプリ化した時とアツマールが対象の環境です。
デプロイメントの暗号化のチェックは外す予定です。

名無し蛙 さんが書きました:結論を言えばトリアコンタン氏がそれ用のプラグインを作成しているので利用するのが無難ですね。
ロード失敗エラーのすり抜けプラグイン
https://triacontane.blogspot.com/2016/06/blog-post_10.html



このプラグインは知りませんでした。
エラーをすり抜けるとはスゴイ使えそうですね。こんなのがあったとは目からウロコ。
ご紹介ありがとうございました。

ですが私の書き方が悪くてすみません…。タイトルに少し語弊がありました。
画像ファイルがないときのエラー無視よりむしろ

コード: 全て選択

〇〇という画像がpictureフォルダにないときに▼▼という画像を表示するというイメージです。

このようにファイルが無い時に異なる画像を表示したいという意味合いのほうが強かったです。
私の書き方が曖昧な感じになっていて混乱させてしまい大変失礼しました。

fs.existsSync("img/faces/Actor1.png")
こちらがもしできるのなら

コード: 全て選択

if(fs.existsSync("img/faces/Actor1.png")){
 //Actor1.pngを表示(loadBitmap)
}else{
 //Actor1.pngが見つからない
 if(fs.existsSync("img/faces/Actor2.png")){
  //Actor2.pngを表示(loadBitmap)
 }else
  //どちらの画像も見つからない
 }
}

このような感じで書けばloadBitmapでエラーが発生しないことになるのでしょうか?
名無し蛙
記事: 305
登録日時: 2015年11月23日(月) 02:46

Re: 画像ファイルが存在してなくてもエラーにならないようにしたい

投稿記事by 名無し蛙 » 2021年9月25日(土) 21:01

アツマール等のサーバ環境とexe出力のローカル環境ではファイルアクセスの勝手が違うのでその影響ですかね
require(fsモジュール)はアツマール上でゲーム起動する場合は利用出来ないようですね
rpg_core.jsよりも深い処理やサーバ関係はあまり読み解いていないので専門外です。すみません

にゃたま さんが書きました:〇〇という画像がpictureフォルダにないときに▼▼という画像を表示するというイメージです。

自分も手探りですけどXMLHttpRequestを使用すれば外部ファイルの存在可否チェックも
出来そうな気はするんですけど非同期処理だしこれはこれで活用するのは面倒臭そうです。
やはり「ロード失敗エラーのすり抜けプラグイン」を調整する、
という方向でアプローチを掛けた方が良いと思いますね。
個別に差し替えるのではなく一括で▼▼の画像になってしまいますけど
エラー検出時に実行されるeraseErrorをフックして再リクエストする方法が一番簡単だと思います。
まず普通に件のプラグインを導入した後、その下に

コード: 全て選択

(()=>{
    'use strict'
    const _Bitmap_eraseError = Bitmap.prototype.eraseError;
    Bitmap.prototype.eraseError = function() {
        _Bitmap_eraseError.apply(this, arguments);
        this._requestImage("img/pictures/▼▼.png");
    };
})();

この調整プラグインを導入すれば一応実現出来ると思います。
アバター
にゃたま
記事: 837
登録日時: 2016年1月13日(水) 23:53
お住まい: 床下の猫王国-すみませんが体調悪いのでサポートはお休みさせていただきます
連絡を取る:

Re: 画像ファイルが存在してなくてもエラーにならないようにしたい

投稿記事by にゃたま » 2021年9月27日(月) 23:20

名無し蛙様

確認が遅くなり申し訳ありません。
アイテムリストで試してみましたがアイテムにフォーカスすると画像が表示される
という仕様になっていますがアイテムがフォーカスされたらすぐに表示して欲しいのですが
他のアイテムに一旦フォーカスを移して元のアイテムに戻さないと表示されないようです。
直ぐに画像を表示するのは難しいのでしょうか?
つまりフォーカスされてすぐだと何も表示されてない状態です。

でも画像を切り替えるところは出来たのであとは即時に表示できれば結構いいかもしれません。
今一度アドバイスいただけましたら幸いです。

追記
すみません。あと一点、出来たらでいいのですが新しい画像をリクエストしてそれも無ければ
エラー表示とかできると嬉しいです。コンソールにエラー表示でも構いません。よろしくおねがいします。

因みにですが画像は以下のような感じで表示させています。

コード: 全て選択

const bitmap = ImageManager.loadPicture(file);
       bitmap.addLoadListener(function() {
       if (bitmap.isReady()){
             this.contents.blt(bitmap, 0, 0, bitmap.width, bitmap.height,  x,  y, width, height);
       }
 }.bind(this));
名無し蛙
記事: 305
登録日時: 2015年11月23日(月) 02:46

Re: 画像ファイルが存在してなくてもエラーにならないようにしたい

投稿記事by 名無し蛙 » 2021年9月28日(火) 16:42

にゃたま さんが書きました:アイテムリストで試してみましたがアイテムにフォーカスすると画像が表示される
という仕様になっていますがアイテムがフォーカスされたらすぐに表示して欲しいのですが
他のアイテムに一旦フォーカスを移して元のアイテムに戻さないと表示されないようです。
直ぐに画像を表示するのは難しいのでしょうか?
つまりフォーカスされてすぐだと何も表示されてない状態です。

同じ状況を再現出来るテスト環境がない事にはあまり込み入った助言は言えませんねぇ
試しにこんなコードを書きましたけどローカル環境では問題なくエラー時の画像が表示されました

コード: 全て選択

    class Window_Test extends Window_Base {
        initialize(x, y, width, height){
            super.initialize(x, y, width, height);
            const bitmap = ImageManager.loadPicture("test");
            bitmap.addLoadListener(() => {
                this.contents.blt(bitmap, 0, 0, bitmap.width, bitmap.height, 0, 0, bitmap.width, bitmap.height);
            });
        }
    }
    const _Scene_Map_createAllWindows = Scene_Map.prototype.createAllWindows;
    Scene_Map.prototype.createAllWindows = function() {
        _Scene_Map_createAllWindows.apply(this, arguments);
        this._testWindow = new Window_Test(0, 0, 400, 300);
        this.addWindow(this._testWindow);
    };



にゃたま さんが書きました:すみません。あと一点、出来たらでいいのですが新しい画像をリクエストしてそれも無ければ
エラー表示とかできると嬉しいです。コンソールにエラー表示でも構いません。よろしくおねがいします。

this._urlにはそのままファイルパスが入っているのでこんな感じのif文を組めば可能だとは思います。

コード: 全て選択

    const failedPicturePath = "img/pictures/test2.png";
    const _Bitmap_eraseError = Bitmap.prototype.eraseError;
    Bitmap.prototype.eraseError = function() {
        _Bitmap_eraseError.apply(this, arguments);
        if (this._url != failedPicturePath) {
            this._requestImage(failedPicturePath);
        } else {
            throw new Error('Failed to load failedPicture');
        }
    };
アバター
にゃたま
記事: 837
登録日時: 2016年1月13日(水) 23:53
お住まい: 床下の猫王国-すみませんが体調悪いのでサポートはお休みさせていただきます
連絡を取る:

Re: 画像ファイルが存在してなくてもエラーにならないようにしたい

投稿記事by にゃたま » 2021年9月29日(水) 10:24

名無し蛙様

マップ画面で直ぐに切り替わって表示されることを確認しました。
アイテムリストでは難しそうでしょうか?
一応サンプルプラグインを作成しましたので一度参考程度に見てもらえると嬉しいです。
症状が再現されるように作ってあります。
アイテムのメモ欄に<image:アイテムファイル名>をつけて
アイテム欄を表示してください。
画像サイズは正方形(比率1:1)が好ましいです。

もし直ぐに表示できなければ別の方法を考えたいと思います。
助言参考になります。ありがとうございました。
最後に編集したユーザー にゃたま on 2021年9月30日(木) 14:06 [ 編集 1 回目 ]
名無し蛙
記事: 305
登録日時: 2015年11月23日(月) 02:46

Re: 画像ファイルが存在してなくてもエラーにならないようにしたい

投稿記事by 名無し蛙 » 2021年9月29日(水) 22:26

同じ不具合を確認しました。
すみません、Bitmapの挙動に関する理解が甘かったです。
eraseErrorではなくonErrorの方にフックすれば解決すると思います。

それとは別にこの表示構造はあまり良くないですね。
bitmapのロードが完了するタイミングは均一ではないので
カーソルキーを押しっぱなしにすると画像と選択アイテムの不一致を起こす可能性があります。
bltを実行する前にthis._imageとbitmap._urlの整合性をチェックした方が良いと思います。
ロード失敗時画像の絡みで若干面倒になりますけど。

コード: 全て選択

    Window_Info.prototype.drawPicture = function() {
        var bitmapName;
        if (this._image){
            bitmapName = this._image;
        }
        const bitmap = bitmapName ? ImageManager.loaddx(bitmapName) : null;
        bitmap.addLoadListener(() => {
            if ((bitmap._beforeUrl || bitmap._url).includes(this._image)) {
                this.contents.blt(bitmap,
                     0, 0, bitmap.width, bitmap.height,
                     WinfoGraphic_X, WinfoGraphic_Y, WinfoGraphic_width, WinfoGraphic_height);
            }
        });
    }

    const failedPicturePath = "img/pictures/test2.png";
    const _Bitmap_onError = Bitmap.prototype._onError;
    Bitmap.prototype._onError = function() {
        _Bitmap_onError.apply(this, arguments);
        if (this._url != failedPicturePath) {
            this._beforeUrl = this._url;
            this._requestImage(failedPicturePath);
        } else {
            throw new Error('Failed to load failedPicture');
        }
    };

あと何故か全角スペースが紛れ込んでいたのでそちらもついでに直した方が良いですね。
エディタの設定によっては可視可能です。自分はAtomEditorに可視パッケージを導入しています。

コード: 全て選択

Window_ItemCategory.prototype.windowWidth = function() {
    return  WcItem_Width;  // 左に二つ全角スペース有り
};
Window_ItemCategory.prototype.windowHeight = function() {
    return  WcItem_Height;  // 同上
};
アバター
にゃたま
記事: 837
登録日時: 2016年1月13日(水) 23:53
お住まい: 床下の猫王国-すみませんが体調悪いのでサポートはお休みさせていただきます
連絡を取る:

Re: 画像ファイルが存在してなくてもエラーにならないようにしたい

投稿記事by にゃたま » 2021年9月30日(木) 14:06

名無し蛙様

ありがとうございました。
解決いたしました。

アツマールやMacOS用デプロイメントも確認しましたが動作に問題はありません。
おそらくアドバイスがなければできなかったと思います。本当に助かりました。
重ねてお礼申し上げます。
アイテム画像が無い時にアイテム画像が無いときの画像を表示できるようになりました。

bitmap._urlの整合性とか自分にはちょっと難しいのですがこのようにif文をつかってやればよかったのですね。
何故これをしなければいけなかったのかまだ未だに掴めていません。
ですがまぁこれでとりあえずは動作しているので問題ありません。

あと先頭に大文字空白があった点について教えていただきありがとうございました。
なるほどこれは気になりますよね。VisualStudioCodeで編集してますがそれには
デフォルトで表示する機能がなかったので拡張機能を使って機能追加できることがわかったので追加しました。
というかそんな機能あったことしらなくて勉強になりました。これは便利です。

色々至らぬ点ばかりで申し訳なかったですが結構困っていたので助けていただき頭が上がりません。
なにとぞ今後もまた何かわからない点があった時お力添えいただけましたら幸いです。
とりあえずは今回のトピックについてはこれにて解決済みといたします。何度もすみませんでした。
ありがとうございました。

“MV:質問” へ戻る