スタック表示

似たファイル名・連番・撮影タイミングの画像をひとまとめにして、一覧をすっきり見渡す機能です。

スタックとは

1 つのフォルダの中に、同じ投稿の連番ページや連写した写真など「ひとまとまりとして扱いたい画像」が たくさん混在していると、一覧が縦に長くなって全体を見渡しにくくなります。 スタック表示は、こうした似たファイル名・連番・撮影タイミングの画像を自動で分類し、 1 つのセル(サムネイル)に畳んでくれる機能です。

フルスクリーンでのページ移動は次のとおりです。

キー動作
/ すべての画像を 1 枚ずつ順送り(スタックの境界を越えて進みます)
Shift+ / 次 / 前のスタックの先頭画像へジャンプ
ℹ️
スタック表示は今いるフォルダだけの一時的な見せ方で、ファイルそのものは移動・変更されません。 通常のフォルダ表示のときだけ使え、検索結果・ZIP / PDF の中・ドライブ一覧では表示されません。

既定の分類ルール

スタックのまとめ方は、いくつかのルールを上から順に試して決まります。 判定の考え方は次のとおりです。

このように、迷ったときは「畳まない」側に倒す安全寄りの作りになっているため、 意図しないスタックが勝手に作られることはありません。

試されるルールは、上から順に次のとおりです。

ルール説明
1 命名パターン ファイル名の末尾に固定の接尾辞が付いていて、途中の番号だけが変わる形をまとめます。 たとえば作者が配布しているダウンローダ mXD のファイル名 (20260429_1100_0003_1234567890_p01_m01_@user.jpg のように、 末尾が _m01_@ユーザー名 で枚数の部分だけ変わるもの)に対応する例です。
2 末尾が連番・ページ番号 ファイル名の末尾が連番やページ番号になっている場合 (例: name_001 / name_002id_p0 / id_p1)に、 番号の手前の部分でまとめます。
3 先頭が連番 ファイル名の先頭が連番になっている場合(例: 0001_xxxx / 0002_xxxx)に、 連番が途切れずに続いたかたまりごとにまとめます。番号の切れ目でスタックを分けます。
4 更新時刻が近いもの(連写) 更新時刻が近いファイルをまとめます。既定では、連続して更新されたファイルのうち 5 秒以内のものを 1 つのスタックにまとめます。

カスタマイズ(上級者向け)

分類ルールは Rhai スクリプトで自由に書き換えられます。 自分の使っているファイル名の付け方に合わせて、好きなようにまとめ方を定義できます。

スクリプトの場所

導入方法スクリプトの場所
インストーラ版 / 単体 exe 版%APPDATA%\mimageviewer\stack_rules.rhai
ポータブル版実行ファイルと同じ場所の data\stack_rules.rhai

操作

環境設定 → 「フォルダ」ページの「ファイル名スタック」欄から操作します。

スクリプトの約束事

フィールド内容
name拡張子つきのファイル名
stem拡張子を除いたファイル名
ext小文字の拡張子
mtime更新時刻(秒)
sizeファイルサイズ(バイト)

使えるヘルパー関数

スクリプトの中では、次のヘルパー関数が使えます。

関数戻り値説明
regex_is_match(text, pattern)真偽値正規表現に一致するかどうかを返します。
regex_capture(text, pattern, group)文字列一致した丸かっこ番号 group の中身を返します(一致しなければ空文字)。
regex_replace(text, pattern, replacement)文字列一致した部分を置き換えた文字列を返します。
argsort_int(整数の配列)添字の配列渡した値を昇順に並べたときの添字(インデックス)の配列を返します。連番順・時刻順の処理に使います。
stack_all_matched(keys)真偽値キー配列に「該当なし(())」が 1 つも無いか=全ファイルがそのルールに当てはまったかを返します。「全部当てはまったときだけ採用する」判定に使います。
stack_distinct(keys)整数キー配列の中の異なるキーの個数() は無視)を返します。「2 つ以上のスタックができるときだけ採用する」(=全部が 1 つの巨大スタックに潰れるのを防ぐ)判定に使います。
⚠️
速度の注意。 全ファイルに対する「判定」や「集計」「並べ替え」は、上のヘルパー関数 (stack_all_matched / stack_distinct / argsort_int)を使ってください。 これらは内部で高速に処理されます。自分で全ファイルをループして数えたり、ファイルごとに配列やマップへ 1 件ずつ追加していく書き方をすると、ファイル数が多いときに非常に遅くなります (特にマップへ 1 件ずつ追加する処理は、ファイル数の二乗に比例して遅くなり、数万件で十数秒かかります)。 画像 1 万件で一瞬、10 万件でも 1 秒程度で終わるように、ファイル数に比例する程度(O(n))で書くのが目安です。
ℹ️
正規表現は使えます。 regex_capture / regex_is_match / regex_replace で、Rust の正規表現構文が使えます。 線形時間で安全に動作しますが、後方参照(backreference)と先読み / 後読み(lookahead / lookbehind)は使えません。

制約

例:mXD のファイル名をまとめる

たとえば、末尾が _m01_@ユーザー名 のように「_m + 番号 + _@」で終わる ファイル名を、その手前の部分でまとめたい場合は、次のように書けます。

fn group(files) {
    let keys = [];
    for f in files {
        keys.push(regex_capture(f.stem, "^(.+)_m\d+_@", 1));
    }
    keys
}

regex_capture(f.stem, "^(.+)_m\d+_@", 1) は、_m + 数字 + _@ の手前にある 丸かっこ (.+) の中身を取り出します。同じ取り出し結果になったファイルが、1 つのスタックにまとまります。

AI にスクリプト修正を頼むときのテンプレート

正規表現や Rhai スクリプトに慣れていなくても、AI アシスタント(チャット型 AI など)に まとめ方を相談すれば、スクリプトを書いてもらえます。下の枠の文章をそのままコピーして AI に貼り付け、 末尾の「やりたいこと」だけ自分の言葉で書き足してください。

あなたは mImageViewer のファイル名スタック分割スクリプト(Rhai 言語)を編集します。

【契約】
- 入口は fn group(files) です。files と同じ長さのグループキー配列を返します。
  同じキーになったファイルが同じスタックにまとまります(同じキーが 2 つ以上で畳まれます)。
- files に渡るのは画像だけです(フォルダ / ZIP / PDF / 動画は渡りません。動画は常に単独)。
- files[i] は次のフィールドを持ちます:
  - name   : 拡張子つきのファイル名
  - stem   : 拡張子を除いたファイル名
  - ext    : 小文字の拡張子
  - mtime  : 更新時刻(秒)
  - size   : ファイルサイズ(バイト)
- まとめないファイルのキーは () (unit)にできます。
- 返り値を #{ rule: "表示名", keys: [...] } の形にすると、採用したルール名を画面に表示できます(任意)。

【使えるヘルパー関数】(全ファイルの判定・集計・並べ替えは必ずこれらを使うこと)
- regex_is_match(text, pattern)            -> 真偽値。正規表現に一致するか。
- regex_capture(text, pattern, group)      -> 文字列。一致した丸かっこ番号 group の中身(不一致は空文字)。
- regex_replace(text, pattern, replacement)-> 文字列。一致部分を置き換えた結果。
- argsort_int(整数の配列)                  -> 値を昇順に並べたときの添字の配列。連番順・時刻順に使う。
- stack_all_matched(keys)                  -> 真偽値。キーに () が 1 つも無い(=全ファイル該当)か。
- stack_distinct(keys)                     -> 整数。異なるキーの個数(() は無視)。2 つ以上のスタックができるかの判定に使う。

【正規表現】
- regex_capture / regex_is_match / regex_replace で使えます(Rust の正規表現構文)。
- 後方参照、先読み / 後読みは使えません。

【性能(重要)】
- ファイル数に比例する程度(O(n))で書くこと。画像 1 万件で一瞬、10 万件でも 1 秒程度が目安。
- 全ファイルの判定・集計・並べ替えは stack_all_matched / stack_distinct / argsort_int を使う。
  自前で全ファイルをループして数える・並べ替えるのは避ける。
- 特に Rhai のマップ(#{})にファイルごとに 1 件ずつ追加していく書き方は、ファイル数の二乗に比例して
  非常に遅くなる(数万件で十数秒)。重複排除や個数集計は stack_distinct を使うこと。

【制約】
- ファイル操作・ネットワーク・OS 操作はできません(隔離された環境で動きます)。
- 1 回の処理量には上限があります。
- EXIF の撮影時刻やカメラ機種などの重い情報は渡されません(更新時刻 mtime は使えます)。

【やりたいこと】
ここに、どんなファイル名をどうまとめたいかを書いてください。
(例のファイル名を 2〜3 個添えると、より正確なスクリプトが作れます。)
💡
AI が書いたスクリプトは、「スクリプトを開く」で開いたファイルに貼り付けて保存し、 「スクリプトを使う」を ON にすると反映されます。思ったとおりにまとまらないときは、 実際のファイル名をいくつか AI に伝えて調整を頼んでください。