スタック表示
似たファイル名・連番・撮影タイミングの画像をひとまとめにして、一覧をすっきり見渡す機能です。
スタックとは
1 つのフォルダの中に、同じ投稿の連番ページや連写した写真など「ひとまとまりとして扱いたい画像」が たくさん混在していると、一覧が縦に長くなって全体を見渡しにくくなります。 スタック表示は、こうした似たファイル名・連番・撮影タイミングの画像を自動で分類し、 1 つのセル(サムネイル)に畳んでくれる機能です。
- ON / OFF:グリッド右上(アドレスバーの右側)の 「スタック」 トグルで切り替えます。 ON にしている状態は一時的なもので、別のフォルダへ移動すると自動的に解除されます。
- 枚数バッジ:畳まれたスタックの右上には、まとめた枚数のバッジが付きます。 まとめる相手がいない(1 枚しかない)画像は、畳まずに通常どおり 1 枚で表示されます。
- 1 本の並びで読める:畳んだスタックをダブルクリックまたは Enter で開くと、 フォルダ内の画像を 1 枚ずつ並べたフルスクリーン表示に入ります。 スタックの中だけでなく、フォルダ全体を続けて読めます。
フルスクリーンでのページ移動は次のとおりです。
| キー | 動作 |
|---|---|
| ↓ / ↑ | すべての画像を 1 枚ずつ順送り(スタックの境界を越えて進みます) |
| Shift+↓ / ↑ | 次 / 前のスタックの先頭画像へジャンプ |
既定の分類ルール
スタックのまとめ方は、いくつかのルールを上から順に試して決まります。 判定の考え方は次のとおりです。
- あるルールが「フォルダ内のすべてのファイルに当てはまる」場合に、そのルールを採用します。
- 汎用的なルールは、「2 つ以上のまとまりができる」場合だけ採用します。 フォルダ全体が 1 個の巨大なスタックに潰れてしまうのを避けるためです。
- どのルールにも当てはまらなかった場合は、何も畳みません(すべて 1 枚ずつ単独表示)。
このように、迷ったときは「畳まない」側に倒す安全寄りの作りになっているため、 意図しないスタックが勝手に作られることはありません。
試されるルールは、上から順に次のとおりです。
| 順 | ルール | 説明 |
|---|---|---|
| 1 | 命名パターン | ファイル名の末尾に固定の接尾辞が付いていて、途中の番号だけが変わる形をまとめます。
たとえば作者が配布しているダウンローダ mXD のファイル名
(20260429_1100_0003_1234567890_p01_m01_@user.jpg のように、
末尾が _m01_@ユーザー名 で枚数の部分だけ変わるもの)に対応する例です。 |
| 2 | 末尾が連番・ページ番号 | ファイル名の末尾が連番やページ番号になっている場合
(例: name_001 / name_002、id_p0 / id_p1)に、
番号の手前の部分でまとめます。 |
| 3 | 先頭が連番 | ファイル名の先頭が連番になっている場合(例: 0001_xxxx / 0002_xxxx)に、
連番が途切れずに続いたかたまりごとにまとめます。番号の切れ目でスタックを分けます。 |
| 4 | 更新時刻が近いもの(連写) | 更新時刻が近いファイルをまとめます。既定では、連続して更新されたファイルのうち 5 秒以内のものを 1 つのスタックにまとめます。 |
カスタマイズ(上級者向け)
分類ルールは Rhai スクリプトで自由に書き換えられます。 自分の使っているファイル名の付け方に合わせて、好きなようにまとめ方を定義できます。
スクリプトの場所
| 導入方法 | スクリプトの場所 |
|---|---|
| インストーラ版 / 単体 exe 版 | %APPDATA%\mimageviewer\stack_rules.rhai |
| ポータブル版 | 実行ファイルと同じ場所の data\stack_rules.rhai |
操作
環境設定 → 「フォルダ」ページの「ファイル名スタック」欄から操作します。
- 「スクリプトを使う」チェック:カスタムスクリプトを有効にします。OFF のときは既定の分類ルールが使われます。
- 「スクリプトを開く」ボタン:スクリプトファイルをテキストエディタで開きます。
- 「既定に戻す」ボタン:スクリプトの内容を初期状態(既定のルールを書いたもの)に戻します。
スクリプトの約束事
- 入口は
fn group(files)という関数です。filesと同じ長さの グループキー配列を返します。同じキーになったファイルが同じスタックにまとまります (同じキーが 2 つ以上あって初めて畳まれます)。 files[i]は次のフィールドを持ちます。
| フィールド | 内容 |
|---|---|
name | 拡張子つきのファイル名 |
stem | 拡張子を除いたファイル名 |
ext | 小文字の拡張子 |
mtime | 更新時刻(秒) |
size | ファイルサイズ(バイト) |
- スクリプトに渡されるのは画像だけです。 フォルダ・ZIP・PDF はグリッドの先頭に
そのまま表示され、動画は常に単独で並びます(いずれもスクリプトには渡らず、まとめる対象になりません)。
そのため
filesに動画やフォルダは入りません。 - 返り値を
#{ 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 つ以上のスタックができるときだけ採用する」(=全部が 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)は使えません。
制約
- ファイル操作・ネットワーク・OS 操作はできません(安全のため隔離された環境で動きます)。
- 1 回の処理量には上限があります。
- EXIF の撮影時刻やカメラ機種といった重い情報は渡されません。
ただし、ファイルの更新時刻(
mtime)は使えます。
例: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 個添えると、より正確なスクリプトが作れます。)