こんにちは。開発ブログ運営担当のktです。

皆さんはデスクトップの壁紙はどのような設定にしていますか?
Windowsにプリインストールされているものを設定したり、お気に入りの画像を設定している人もいるでしょう。
私はきれいな景色を設定していますが、ずっと同じだと飽きてしまうのでコロコロと違う画像に変更したいタイプです。
でも手動で壁紙を変更するのは面倒ですよね。

今回はデュアルモニターに別々の画像を設定して、それを自動で変更する方法を紹介しようと思います。
Windows標準のスライドショー機能を利用した方法とPythonプログラムを利用した方法です。

環境

Windows10 Home 64bit 21H2
Python 3.10.1
モニター1 解像度:2560×1440 27インチ
モニター2 解像度:1920×1080 24インチ

※Pythonのインストールが必要です。
インストール手順は説明しているサイトが山ほどあるのでここでは割愛します。

Windows標準機能を利用した方法

ディスプレイ上で右クリックして「個人用設定」を選択します。

背景の選択肢から「スライドショー」を選択します。
「参照」をクリックして壁紙に設定したい画像ファイルを格納したフォルダを指定します。
画像の切り替え間隔を好みのものに設定します。
調整方法を選ぶで「スパン」になっていたら、「画面のサイズに合わせる」等に変更すればそれぞれのモニターで別々の画像が壁紙として設定されます。

今回は1分で切り替える設定にしたので、1分ごとに左右のモニターが交互に別の画像に切り替わります。

はい、簡単ですね。
Windows標準機能があるんだからわざわざプログラムを組む必要ないんちゃうと思いますよね。
それにこんな情報が載っているサイトはたくさんあります。
なのに今回記事にしたのは、私の環境が関係しています。
普段24インチのモニターは縦置きにして利用しています。
そうすると1920×1080の画像だとモニターの上下に何も表示されない状態になってしまいます。
せっかくきれいな景色を表示しているのにそんなの嫌じゃないですか。

Windows標準機能だと「スライドショー」で表示する画像ファイルの配置場所は一つしか指定できません。
モニター1用の画像ファイルの置き場所、モニター2用の画像ファイルの置き場所と指定できたら良かったのですが、私が調べた限り見つかりませんでした。
※もし方法があるなら教えてください。

Pythonプログラムを利用した方法

まずは先ほどと同じ「個人用設定」で背景の選択肢から「画像」を選択します。
次に「画像を選んでください」の下から任意の画像の上で右クリックして「モニター1に設定」を選択します。
同じように他の画像の上で右クリックから「モニター2に設定」を選択します。
そうすると選択した画像がそれぞれのモニターの壁紙に設定されます。

次に「C:/Users/healt」(healtの部分は自身のPCにログインしているユーザーを選択)フォルダを開きます。
「AppData」フォルダが表示されていなかったら、エクスプローラー上部の「表示」タブで「隠しファイル」にチェックを入れて表示されるようにします。

「C:/Users/healt/AppData/Roaming/Microsoft/Windows/Themes/」フォルダを表示します。
Transcoded_000とTranscoded_001というファイルがあります。

これらのファイルは先ほど「モニター1に設定」や「モニター2に設定」した画像ファイルがコピーされてファイル名が変更されたものです。
試しにTranscoded_000とTranscoded_001を別のフォルダにコピーして、拡張子「.jpg」(元の画像がjpgの場合)を付けて開くと画像ファイルだというのが分かると思います。
ここまで説明すると分かると思いますが、プログラムでTranscoded_000とTranscoded_001のファイルを変更すればそれに合わせて壁紙が変更されるということです。
そしてPythonでその機能を実装したコードが下記です。

import glob
import random
import shutil

# WQHDのフォルダからファイル名のリストを取得
wqhd_files = glob.glob("C:/Users/healt/OneDrive/画像/WallPaper/wqhd/*")

# リストの数までの乱数を取得してインデックスとする
wqhd_index = random.randint(0, len(wqhd_files)-1)

# リストからインデックスのファイルを、壁紙として指定するように「Transcoded_000」にリネームしてコピーする
BASE_DIR = "C:/Users/healt/AppData/Roaming/Microsoft/Windows/Themes/"
shutil.copy(wqhd_files[wqhd_index], BASE_DIR + "Transcoded_000")

# 縦フルHDのフォルダからファイル名のリストを取得
hdv_files = glob.glob("C:/Users/healt/OneDrive/画像/WallPaper/fullhdv/*")

# リストの数までの乱数を取得してインデックスとする
hd_index = random.randint(0, len(hdv_files)-1)

# リストからインデックスのファイルを、壁紙として指定するように「Transcoded_001」にリネームしてコピーする
shutil.copy(hdv_files[hd_index], BASE_DIR + "Transcoded_001")

ひとつ制限があり、Transcoded_000とTranscoded_001のファイルを変更してすぐに壁紙が変更されるわけではない点です。
一度ログオフやシャットダウンしてからログオンしたタイミングで反映されるようです。
あとはこれを自動実行するようにタスクスケジューラに登録するだけです。
タスクの設定は下記です。
プログラム/スクリプトにインストールしたPythonのexeファイルを指定。
C:\Users\healt\AppData\Local\Programs\Python\Python310\python.exe
引数の追加(オプション)に実行したいソースファイルを指定。
image_change.py
開始(オプション)にソースファイルを置いているフォルダを指定。
C:\Users\healt\OneDrive\デスクトップ\python

タスクのトリガーはログオンしたタイミングで遅延時間を30秒ほど指定して実行されるようにしておきます。
遅延時間を指定していないと壁紙が変更されない場合があったので動作を安定させるための設定です。

ログオンしたらこのプログラムが実行されTranscoded_000とTranscoded_001のファイルが変更され、次にログオンするタイミングでその壁紙が反映されるというわけです。
スリープでは反映されなかったのでログオフをする必要がありますが、自分のPCの使い方だったら問題ありません。

まとめ

Windowsの標準機能でカバーできない部分をプログラムで解決できました。
あとは自動的に自分好みの画像ファイルを集められるように機能を追加したいですね。
そこまでできたらGitHubでソースを公開するのもいいかも。
今回は手動で壁紙を変更する手間を無くすため、手間をかけて対応方法を調査しました。
楽するために頑張れる人はプログラマー・SEに向いていると思います。
興味を持たれた方は下記リンク先の採用情報も覗いてください。

http://www.softem.com/recruit_top/