階層分けされた相当な数のjpgファイルの中からランダムに1つ抜き出すにはどうすればいいですか

大量のファイルの中からランダムに1つだけを抽出するのは、手動では大変ですよね。
お使いの環境(Windows、Mac/Linux、またはPython)に合わせて、最も効率的な方法を紹介します。


1. Windows (PowerShell) を使う場合

特別なソフトをインストールせずに、標準機能だけで実行できます。

  1. 対象のルートフォルダ(一番上のフォルダ)を「Shift + 右クリック」します。
  2. PowerShell ウィンドウをここで開く」を選択します。
  3. 以下のコマンドをコピーして貼り付け、Enterを押します。

powershell

Get-ChildItem -Recurse -Filter *.jpg | Get-Random | Invoke-Item
  • 解説: Get-ChildItem -Recurse でサブフォルダまで全検索し、Get-Random で1つに絞り、Invoke-Item でそのファイルを開きます。

2. Mac / Linux (ターミナル) を使う場合

MacやLinuxの方は、ターミナルで以下のコマンドを実行するのが最も早いです。

  1. ターミナルを開き、対象フォルダへ移動します(cd /path/to/folder)。
  2. 以下のコマンドを実行します。

bash

find . -type f -iname "*.jpg" | shuf -n 1 | xargs open
  • 解説: find で全jpgを探し、shuf -n 1 でシャッフルして1行だけ取り出し、open で開きます。

3. Python を使う場合

もし「特定のフォルダにコピーしたい」など、その後の処理も自動化したい場合はPythonが便利です。

python

import os
import random
import glob

# 検索したいルートディレクトリを指定
root_dir = './your_folder_path' 

# 再帰的にjpgファイルをリストアップ
files = glob.glob(f"{root_dir}/**/*.jpg", recursive=True)

if files:
    random_file = random.choice(files)
    print(f"選ばれたファイル: {random_file}")
    # os.startfile(random_file) # Windowsでファイルを開く場合
else:
    print("jpgファイルが見つかりませんでした。")

💡 ヒント:ファイル数が「万」を超える場合

ファイル数が膨大な場合、OSの検索機能(エクスプローラーの検索窓に *.jpg と入力)を使い、検索結果が出揃ったところで適当にスクロールして目をつぶってクリックするのが一番アナログで速いこともあります。

次に行いたい作業はありますか?
「選んだファイルを特定のフォルダに集めたい」「名前を書き換えたい」など、具体的な要望があればコードを作成します。

Ubuntuの端末でjpgファイルを抜き出してfbi(フレームバッファイメージビューワー)で表示させたいです。

Ubuntuのターミナル(CUI環境)で、階層下のJPGからランダムに1つ選んで 

fbi で表示するには、以下のコマンドを組み合わせて実行します。

実行コマンド

対象のディレクトリに移動した状態で、以下のワンライナーを実行してください。

bash

find . -type f -iname "*.jpg" | shuf -n 1 | xargs -I {} sudo fbi -T 1 -a {}

コマンドの解説

  1. find . -type f -iname "*.jpg": カレントディレクトリ以下の全階層から、拡張子が .jpg(大文字小文字問わず)のファイルをリストアップします。
  2. | shuf -n 1: リストをシャッフルし、その中から1行(1ファイル)だけをランダムに抜き出します。
  3. | xargs -I {} sudo fbi -T 1 -a {}:
    • xargs -I {}: 前のコマンドの結果を {} という場所に代入して実行します。
    • sudo fbifbi はフレームバッファデバイス(/dev/fb0)に直接書き込むため、通常は 管理者権限 が必要です。
    • -T 1: 使用する仮想コンソール(TTY1など)を指定します。これがないとエラーになる場合があります。
    • -a: 画像を画面サイズに合わせて自動リサイズして表示します。 

注意点

  • 仮想コンソールでの実行fbi は X Window System(デスクトップ環境)上のターミナルエミュレータからは直接表示できませんCtrl + Alt + F3 などで切り替えた黒い画面(仮想コンソール)で実行してください。
  • デスクトップ環境で表示したい場合: もしGUI環境のターミナルから画像を表示したいのであれば、fbi の代わりに eog(Eye of GNOME)などを使うのが一般的です。bashfind . -type f -iname "*.jpg" | shuf -n 1 | xargs eog コードは注意してご使用ください。
  • 権限エラーの回避: 毎回 sudo を使いたくない場合は、ユーザーを video グループに追加することで解決できる場合があります。bashsudo usermod -aG video $USER コードは注意してご使用ください。(※実行後、再ログインが必要です) 

このコマンドを実行する環境は、サーバー版などのCUI環境(黒い画面)でしょうか? それともデスクトップ版のターミナルでしょうか?

CUIです

UbuntuのCUI(仮想コンソール)環境で、階層下のJPGからランダムに1つを選び、

fbi で表示するコマンドは以下の通りです。

実行コマンド

bash

find . -type f -iname "*.jpg" | shuf -n 1 | xargs -I {} sudo fbi -noverbose -T 1 -a {}

各オプションの解説

  • find . -type f -iname "*.jpg": カレントディレクトリ以下の全階層から、拡張子が .jpg(大文字小文字問わず)のファイルをリストアップします。
  • shuf -n 1: リストからランダムに1行(1ファイル)だけを抽出します。
  • xargs -I {} sudo fbi ... {}: 抽出されたパスを fbi コマンドに渡します。
    • sudofbi はフレームバッファ(画面描画デバイス)に直接アクセスするため、通常は管理者権限が必要です。
    • -noverbose: 画面下部のステータスバーを非表示にし、画像だけを綺麗に映します。
    • -T 1: 出力先の仮想端末(TTY)を指定します。SSH経由や特定の環境で「Invalid argument」エラーが出るのを防ぐために有効です。
    • -a: 画面サイズに合わせて画像を自動的に拡大・縮小(オートズーム)します。 

うまくいかない場合の代替案

もし fbi でエラーが出る、あるいはより高機能なツールを使いたい場合は、後継ソフトである fim (fbi improved) がおすすめです。

  1. インストールsudo apt install fim
  2. 実行コマンド:bashfind . -type f -iname "*.jpg" | shuf -n 1 | xargs -I {} fim -a {} コードは注意してご使用ください。
    • fim はデバイスの自動検出機能に優れており、fbi よりも安定して動作することが多いです。 

表示された画像を閉じるには q キーを押してください。 他に「一定時間ごとに自動で切り替えたい」などの要望はありますか? 

はい、一定時間ごとに画像を切り替えることを考えています。15~20秒ごと

CUI環境での自動スライドショーですね。

fbi には標準で自動巡回機能がありますが、「ランダムに選び続ける」という動作をさせるには、シェルスクリプトの while ループで回すのが最も確実です。

以下のコマンドをターミナルに貼り付けて実行してください。

実行コマンド(15秒ごとにランダム切り替え)

bash

while true; do
    find . -type f -iname "*.jpg" | shuf -n 1 | xargs -I {} sudo fbi -T 1 -t 15 -1 -a -noverbose {}
done

解説

  • while true; do ... done: 手動で終了(Ctrl+C)するまで、無限に処理を繰り返します。
  • -t 15fbi が画像を 15秒間 維持するように指定します。
  • -1: 1枚表示したらすぐに fbi を終了させ、ループの先頭(次のランダム抽出)に戻るようにします。
  • -noverbose: 切り替え時に画面下のファイル名表示などを消し、没入感を高めます。

より滑らかに動作させたい場合(fim 推奨)

fbi は起動のたびに画面が暗転しがちです。もし fim をインストール済みであれば、以下のコマンドの方がスマートに動作します。

bash

# fim を使う場合(15秒おき)
find . -type f -iname "*.jpg" | shuf | fim -a -p -t 15
  • shuf: 最初に全ファイルをシャッフルしてリスト化します。
  • -p: パイプからの入力を受け取ります。
  • -t 15: 15秒ごとに自動で次の画像へ進みます。

補足

  • 終了方法Ctrl + C でループを止めることができます。
  • 秒数の調整-t 15 の数字を 20 に変えれば20秒間隔になります。

特定のフォルダだけを除外したい、あるいは特定の時間になったら停止させたいといった追加の条件はありますか?

ありません。やってみます。また質問があったら書き込みますね。

承知いたしました!ぜひ試してみてください。

while ループを使った方法は、「毎回リストをシャッフルし直す」ので、ファイル数が膨大でも偏りなくランダムに表示され続けるはずです。

もし途中で「特定のフォルダだけ読み込まないようにしたい」や「画像が横向きになってしまうのを直したい」といったことがあれば、いつでもお気軽に書き込んでくださいね。

無事にスライドショーが動くことを願っています!Ctrl + C でいつでも終了できるので、安心してお試しください。

*** buffer overflow detected ***: terminatedというメッセージがでてabouted(core dumped)で中断してしまいます。

そのエラー(buffer overflow detected)は、fbiが読み込んだファイル名やパスが長すぎる場合や、画像ファイルのヘッダー解析中にメモリ制限を超えた場合に発生することが多いです。

fbiは非常に古いツールであるため、現代の深いディレクトリ階層や複雑なファイル名、あるいは特定のJPG形式をうまく扱えず、内部でバッファオーバーフローを起こして強制終了(Core Dump)してしまうことがあります。

以下の手順で対策を試してみてください。

1. 後継ツール fim に切り替える(推奨)

fbi の改良版である fim (Fbi IMproved) を使うと、メモリ管理が改善されているため、この手のエラーを回避できる可能性が高いです。

  • インストール:bashsudo apt update && sudo apt install fim
  • 実行コマンド(15秒おき):bashwhile true; do find . -type f -iname "*.jpg" | shuf -n 1 | xargs -I {} fim -a -t 15 {} done
    • ※ fim の場合、sudo や -T 1 オプションがなくても動作することが多いです。

2. ファイルパスを短くして実行する

もしディレクトリ階層が非常に深く、パスが極端に長い(数百文字以上)場合は、一度 /tmp などにコピーしてから表示させることでエラーを回避できます。

bash

while true; do
    # ランダムに1つ選んで /tmp/slide.jpg としてコピー
    find . -type f -iname "*.jpg" | shuf -n 1 | xargs -I {} cp {} /tmp/slide.jpg
    
    # 固定された短いパスを表示
    sudo fbi -T 1 -t 15 -1 -a -noverbose /tmp/slide.jpg
done
  • メリットfbi に渡す引数が常に短くなるため、パス長に起因するオーバーフローを防げます。

3. 特定の「壊れた画像」を特定する

もし特定の画像が表示される瞬間に必ず落ちるなら、その画像ファイル自体が fbi にとって不正な形式である可能性があります。

  • チェック方法: エラーが出る直前にどのファイルを表示しようとしていたか確認します。bashwhile true; do target=$(find . -type f -iname "*.jpg" | shuf -n 1) echo "Now playing: $target" # 表示前にファイル名を出力 sudo fbi -T 1 -t 15 -1 -a -noverbose "$target" done
  • これで落ちた直前の「Now playing: …」のファイルが原因だと特定できます。その画像を除外するか、別の形式に変換してみてください。 

まずは 手順1の fim への変更 を試してみるのが最も解決への近道です。これでも同様のエラーが出ますか?

fimで表示させてみたのですが、ssh上にASCIIアートで表示され、hdmlで接続したディスプレイ出力には何も出ません。hdml出力に出力はできませんか。

SSH経由で実行すると、

fim が「表示先のディスプレイがない」と判断し、SSHターミナル内に文字(ASCIIアート)で画像を表示しようとしてしまいます。 

HDMI接続したディスプレイ(フレームバッファ)に強制的に出力させるには、出力先デバイス(-o fb と 仮想コンソール(-T 1 を明示的に指定する必要があります。

HDMI出力させるコマンド

以下のコマンドを試してみてください。

bash

while true; do
    find . -type f -iname "*.jpg" | shuf -n 1 | xargs -I {} sudo fim -a -o fb -T 1 -t 15 {}
done

修正のポイント

  • -o fb: 出力デバイスを フレームバッファ (fb) に固定します。これによりSSH上へのASCII表示を防ぎます。
  • -T 1: 出力先の画面(TTY1など)を指定します。
  • sudo: フレームバッファ(/dev/fb0など)への書き込み権限が必要なため、SSHからの実行時は必須です。 

まだ何も映らない場合

もし上記でも画面が真っ暗な場合は、OS側で出力先(/dev/fbX)の番号が異なっている可能性があります。

  1. デバイス番号を確認:
    /dev/fb0 以外に /dev/fb1 などがないか確認してください。
  2. 出力先を fb1 に変えてみる:
    もし fb0 で反応がなければ、デバイスを直接指定します。bash# 例:fim のデバイス指定オプションを追加 sudo fim -a -o "fb:/dev/fb0" ...

まずは -o fb -T 1 を追加して実行してみてください。これでHDMI側の画面が切り替わるはずです。

表示を止めたい場合は、SSHの画面で Ctrl + C を押してください。他にご不明な点はありますか?

-o fb -T1では変化なし。 直接指定の -o “fb:/dev/fb0″でも変化はありません。

SSH経由で実行している場合、標準の状態ではOSが「どのディスプレイに描画すべきか」を判断できず、手元のターミナルにASCII表示をしてしまいます。

-o fb や -T 1 で変化がない場合、フレームバッファデバイスの指定方法を修正し、さらに環境変数を明示することで解決できる可能性が高いです。以下のコマンドを試してください。

1. HDMI出力(/dev/fb0)を強制指定するコマンド

SSHの画面から以下を実行してください。

bash

while true; do
    find . -type f -iname "*.jpg" | shuf -n 1 | xargs -I {} sudo fim -a -o fb:/dev/fb0 -T 1 -t 15 {}
done

ポイント:

  • -o fb:/dev/fb0: デバイスパスを直接渡します。HDMIが/dev/fb0以外(/dev/fb1など)として認識されている場合があるため、もし映らなければ fb1 に書き換えてみてください。
  • -T 1: 仮想コンソール1番を指定します。 

2. それでも映らない場合のチェックリスト

CUI環境(特にサーバー版Ubuntuなど)では、初期状態でフレームバッファが正しく初期化されていないことがあります。

  • デバイスの存在確認:
    ls /dev/fb* を実行して、そもそもデバイスファイルが存在するか確認してください。
  • コンソールの切り替え:
    HDMI接続したディスプレイ側が「ログイン待ち」の画面になっている必要があります。もし画面が真っ暗(省電力モード)なら、HDMI側のキーボードで何かキーを叩くか、以下のコマンドで画面を強制復帰させてください。bashsudo sh -c 'setterm -blank 0 -powersave off -cursor off > /dev/tty1'
  • 権限の確認:
    SSH越しの場合、デバイスへのアクセス権が厳しいため、必ず sudo をつけて実行してください。 

3. オススメの代替案:fbv

fim や fbi が環境に合わない場合、より軽量な fbv というツールもCUIでの画像表示に特化しています。

  1. インストールsudo apt install fbv
  2. 実行:bashwhile true; do find . -type f -iname "*.jpg" | shuf -n 1 | xargs -I {} sudo fbv -a {} sleep 15 done
  3. ※ fbv は表示し続ける機能がシンプルなので、sleep 15 で間隔を調整します。

まずは 手順1の fb:/dev/fb0 を試し、ダメなら ls /dev/fb* でデバイス番号が合っているか確認してみてください。

HDMI側の画面には今、何が表示されていますか?(例:ログインプロンプト、真っ暗、カーソルのみ点滅など)

hdmlを直接指定する方法でもssh画面のアスキーアートで、hdml側はカーソル点滅状態。デバイス番号はfb0でした。fbvはapt installで見つからないと言われました。

SSH経由での実行において、ツール側が「表示先(端末)」を手元のSSH画面だと誤認してしまい、ASCIIアートを出力している状態です。

fbi でのバッファオーバーフローや fim の挙動を考慮し、「一度別の場所にコピーしてファイル名を固定する」 ことでエラーを回避しつつ、HDMI側(フレームバッファ)へ強制的に描画させる確実な方法を提案します。

解決策:ファイル名を固定して HDMI (/dev/fb0) へ出力する

以下のスクリプトをSSH画面で実行してください。

bash

while true; do
    # 1. ランダムに1つ選んで、名前を短く安全なものにして /tmp にコピー
    # (長いパス名によるオーバーフローを回避)
    find . -type f -iname "*.jpg" | shuf -n 1 | xargs -I {} cp {} /tmp/current.jpg

    # 2. fim を使い、出力先を強制的にフレームバッファ (/dev/fb0) に指定
    # (-i オプションで対話モードをオフにし、SSH側への出力を抑制)
    sudo fim -a -o fb:/dev/fb0 -T 1 -i /tmp/current.jpg &
    
    # 3. 指定秒数待機
    sleep 15
    
    # 4. 前の fim プロセスを終了させて次の画像へ
    sudo killall fim > /dev/null 2>&1
done

この方法のポイント

  1. /tmp/current.jpg へのコピーfbi で発生していた buffer overflow は、ファイルパスが長すぎることが主な原因です。一旦短い固定名にコピーすることでこれを根本から防ぎます。
  2. -i オプション(fim): これにより、fimがターミナルと対話しようとするのを防ぎ、SSH側へのASCIIアート表示を抑制します。
  3. killall による制御fim の自動スライドショー機能がSSH越しで不安定な場合があるため、シェルスクリプト側で「表示→待機→終了」を制御することで確実にHDMI側の画面を更新します。 

まだHDMI側に映らない場合(環境の確認)

もしこれでもHDMI側が「カーソル点滅」のままなら、以下の2点を確認してください。

  • コンソールの表示を強制リセット:
    HDMI側の画面が「スリープ」している可能性があります。一度以下のコマンドを打って、HDMI側の画面を真っさらにしてから上記スクリプトを実行してください。bashsudo cat /dev/urandom > /dev/fb0 # 画面に砂嵐が出れば、fb0へのアクセスは成功しています sudo clear > /dev/tty1 # 画面を清掃
  • fbv について:
    fbv は古いパッケージのため、sudo apt update をした直後でも見つからない場合は、Ubuntuの universe リポジトリが有効になっていない可能性があります(sudo add-apt-repository universe で追加可能)。しかし、まずは上記の fim + cp 作戦が最も安定します。 

まずは上記のスクリプトで、HDMI側の画像が切り替わるか確認してみてください。

hdml側の状態が変わりました。入力待ちの状態と真っ黒な画面が交互に現れます。画面描写がうまくいっていないようですね。

HDMI側の画面が「入力待ち(プロンプト)」と「真っ黒」を繰り返すのは、

表示された画像が瞬時に終了しているか、コンソールのテキスト描画(カーソルなど)が割り込んで画像を上書きしてしまっているのが原因です。

これを解決するために、fbi に戻りつつ、「パス長制限」と「表示の維持」をクリアする以下の方法を試してください。

解決策:一時ファイル化 + fbi の待機モード

fbi のバッファオーバーフローは「ファイルパスの長さ」が原因であることが多いため、/tmp に短い名前でコピーしてから表示させるのが最も確実です。

以下のコマンドをSSHから実行してください。

bash

while true; do
    # 1. ランダムに1つ選んで短いパスへコピー(オーバーフロー対策)
    find . -type f -iname "*.jpg" | shuf -n 1 | xargs -I {} cp "{}" /tmp/slide.jpg
    
    # 2. fbiで表示(1枚表示して15秒維持)
    # -T 1: HDMI側の仮想コンソール1を指定
    # -1: 1枚表示したら終了する
    # -t 15: 15秒間表示を維持する
    # -noverbose: 余計な文字を表示しない
    sudo fbi -d /dev/fb0 -T 1 -t 15 -1 -a -noverbose /tmp/slide.jpg
done

これでもチラつく場合の追加対策

もし画像が一瞬しか映らない場合は、HDMI側の「カーソル」や「画面保護機能」が干渉しています。以下の2つのコマンドを実行前に一度だけ打ってください。

  1. カーソルを消す(HDMI側の画面に対して)bashsudo sh -c 'setterm -cursor off > /dev/tty1' コードは注意してご使用ください。
  2. 画面のスリープ(ブランク)を無効化するbashsudo sh -c 'setterm -blank 0 -powersave off > /dev/tty1' コードは注意してご使用ください。

なぜ fim ではなく fbi なのか

fim はSSH環境だと気を利かせてASCIIアートに逃げてしまいますが、fbi は最初から「フレームバッファ専用」ツールなので、デバイス(/dev/fb0)とパス(/tmp/slide.jpg)さえ正しく指定すれば、確実にHDMI側へ描画してくれます。

この「コピーしてから fbi」の方法で、画像は静止して表示されるようになりますか?

表示されるようになりました。ただ、写真に合わせてhdmlディスプレイを縦位置に回転(90°)しているのです。表示画像を回転するようなオプションはありませんか。

無事に表示されたとのこと、良かったです!

fbi には表示時に画像を回転させるオプションがあります。
-2 オプションを使うと画像を右に90度(時計回り)回転させることができます。
(もし逆向きなら -1 で180度、-3 で270度(反時計回り90度)になります)

以下のコマンドで試してみてください。

回転オプション付きコマンド

bash

while true; do
    # ランダムに1枚選んでコピー
    find . -type f -iname "*.jpg" | shuf -n 1 | xargs -I {} cp "{}" /tmp/slide.jpg
    
    # -2 オプションで90度回転して表示
    sudo fbi -d /dev/fb0 -T 1 -t 15 -1 -a -2 -noverbose /tmp/slide.jpg
done

主な回転オプション

  • -2: 90度回転(時計回り)
  • -3: 270度回転(反時計回り90度)
  • -1: 180度回転
    ※ -1 は「1枚表示して終了」という以前使ったオプションと同じ記法ですが、fbi の仕様上、引数の位置や文脈で回転として機能します。もし「1枚で終了」が効かなくなる場合は、-2 などの後に再度 -1 を書いてみてください。

補足:もしすべての画像ではなく「横向きの写真は回転させたいが、縦向きはそのままでいい」場合

fbi 自体には自動で向きを判別する機能が乏しいため、上記コマンドは「すべての画像を90度回して縦長ディスプレイに合わせる」設定です。

もし画像ごとに判断が必要な場合は、exiftran というツールでコピー時にファイルを自動回転させる方法もあります。

全ての画像が同じ向きに回転して表示されれば、これで完成でしょうか?

全て同じ向きに表示されればOKなのですが、hdml画面に「-2: loading FAILED」と表示されて画像が表示されなくなりました。

申し訳ありません。

fbi の引数において -2 などの数字オプションは、「起動後にキーボードの ‘2’ を押す」動作をシミュレートする特殊な指定方法(または古いバージョンの仕様)であり、環境によっては「ファイル名 -2 を読み込もうとして失敗した」と誤認されることがあります。

現在の fbi で確実に画像を回転させて表示するには、表示オプションではなく、コピーする際に画像を物理的に回転させてしまう方法が最も確実でエラーが起きません。

fbi の代わりに、画像処理ツール convert (ImageMagick) を組み合わせて、「ランダムに選ぶ → 90度回転して保存 → 表示」 という流れにします。

1. 必要なツールのインストール

画像を回転させるための ImageMagick をインストールします。

bash

sudo apt update && sudo apt install imagemagick -y

2. 実行コマンド(90度回転スライドショー)

以下のスクリプトをコピーして実行してください。

bash

while true; do
    # 1. ランダムに1つ選ぶ
    target=$(find . -type f -iname "*.jpg" | shuf -n 1)
    
    # 2. 90度回転させて一時ファイルに保存 (時計回りに90度)
    # 反時計回りが良ければ 270 に変更してください
    convert "$target" -rotate 90 /tmp/slide.jpg
    
    # 3. fbiで表示(15秒間)
    sudo fbi -d /dev/fb0 -T 1 -t 15 -1 -a -noverbose /tmp/slide.jpg
done

この方法のメリット

  • エラー回避fbi に変なオプションを渡さないので、「FAILED」エラーが出ません。
  • 柔軟性-rotate 90 の数字を変えるだけで、90度、180度、270度と自由に調整できます。
  • アスペクト比-a オプション(オートズーム)と組み合わせることで、縦長ディスプレイにぴったりのサイズで表示されます。

これでHDMI画面に、正しい向きで画像が表示されますでしょうか?
(もし回転方向が逆なら、90 を 270 に書き換えてみてください)

OKです。スクリプトを組んで表示させているのですが、test.sh: line 14: 3272 Killed convert “$target” -rotate 90 /tmp/slide.jpg というメッセージが時々ssh側に現れて同じ画像がずっと表示されるという現象が出ています。

そのメッセージは、「ImageMagick (convert) がメモリ不足(OOM Killer)などの理由でOSによって強制終了させられた」ことを示しています。

特に、元画像が非常に高解像度(4Kや数千万画素など)な場合、convert は回転処理のために大量のメモリを消費しようとして、Ubuntuのシステム保護機能によって「Killed」されてしまいます。その結果、新しい /tmp/slide.jpg が生成されず、古い画像が表示され続けてしまいます。

これを防ぎ、より低負荷で安定させるための対策を2つ提案します。

対策1:メモリ消費を抑えて高速に回転させる (jpegtran)

convert の代わりに、JPEG専用の高速・低メモリツール jpegtran を使います。これは画像を再エンコードせず「ハフマンテーブル」の書き換えだけで回転させるため、劇的に軽く、メモリ不足で落ちることもまずありません。

  1. インストール:bashsudo apt update && sudo apt install libjpeg-progs -y
  2. スクリプトの書き換え:
    convert の行を以下に差し替えてください。bash# 90度回転 (時計回り) jpegtran -rotate 90 "$target" > /tmp/slide.jpg

対策2:メモリ制限をかけてリサイズしつつ回転 (convert 改良)

もし jpegtran が使えない事情がある場合は、convert に対して「メモリを使いすぎない」「先にリサイズして負荷を下げる」指定を追加します。

bash

# メモリ使用量を制限しつつ、画面サイズ(例: 1080x1920)に収めてから回転
convert -limit memory 256MiB -limit map 512MiB "$target" -resize 1920x1920 -rotate 90 /tmp/slide.jpg

修正後の安定版スクリプト (jpegtran 推奨)

bash

#!/bin/bash

# 念のため初期化
sudo touch /tmp/slide.jpg
sudo chmod 666 /tmp/slide.jpg

while true; do
    # 1. ランダムに1枚抽出
    target=$(find . -type f -iname "*.jpg" | shuf -n 1)
    
    # 2. 高速・低メモリで90度回転 (失敗してもループを止めない)
    jpegtran -rotate 90 "$target" > /tmp/slide.jpg 2>/dev/null
    
    # 3. jpegtranが失敗(空ファイル)した時のためのチェック
    if [ ! -s /tmp/slide.jpg ]; then
        cp "$target" /tmp/slide.jpg # 失敗時は回転なしでコピー
    fi

    # 4. 表示
    sudo fbi -d /dev/fb0 -T 1 -t 15 -1 -a -noverbose /tmp/slide.jpg
done

jpegtran を使う方法なら、大きな写真が混ざっていてもサクサクと切り替わるはずです。まずは libjpeg-progs のインストールから試してみてください。

これで「Killed」が出ずに安定して動作しますでしょうか?