加賀一稿一記

心は戦国

デスクトップの壁紙をコロコロ変える

デスクトップの壁紙を動画にするのが流行ってるぽいので実装した.

Windowsで壁紙を変えるにはレジストリを書き換えてやればよい.
regeditから
HKEY_CURRENT_USER/ Control Panel/ desktop/
のWallPaperを見れば,今使ってる壁紙のパスが確認できるはず.

レジストリを編集する関数もたくさんあるけど,
これについて使いやすそうな関数があるのでこっちを使った.

適当にopencvで画像を保存して,そのパスを壁紙に指定してやれば終わり.
opencvで動画も1フレームずつ扱えるので常勝!と思ったが,垂れ流したい動画がない.
(そんなに動画を流したいなら,全画面&背面で動画流しちゃだめなの?)

しょうがないのでライフゲームを壁紙で実行することにした.

実装は次の感じ.
人々はどんな感じに実装するんやろか.

#include "opencv2/opencv.hpp"
#include <Windows.h>
#include <random>

const int CellW = 64;
const int CellH = 36;
const int ImgW = 1920;
const int ImgH = 1080;

int Cell[CellW][CellH];
int TmpCell[CellW][CellH];
int dx[8] = {0,1,1,1,0,-1,-1,-1};
int dy[8] = {1,1,0,-1,-1,-1,0,1};

void Init(){
	std::random_device rd;
	for (int y = 0; y < CellH;y++){
		for (int x = 0; x < CellW;x++){
			if (rd() % 2)Cell[x][y] = 1;
		}
	}
}

void Update(){
	for (int y = 0; y < CellH; y++){
		for (int x = 0; x < CellW; x++){
			TmpCell[x][y] = 0;
			for (int i = 0; i < 8;i++){
				int ty = (y + dy[i] + CellH) % CellH;
				int tx = (x + dx[i] + CellW) % CellW;
				TmpCell[x][y] += Cell[tx][ty];
			}
		}
	}
	for (int y = 0; y < CellH; y++){
		for (int x = 0; x < CellW; x++){
			if (Cell[x][y] == 0 && TmpCell[x][y] == 3)Cell[x][y] = 1;
			else if (Cell[x][y] && (TmpCell[x][y] <= 1 || 4 <= TmpCell[x][y]))Cell[x][y] = 0;
		}
	}
}

void ImgWrite(){
	cv::Mat wallpaper(ImgH, ImgW, CV_8UC1, cv::Scalar(255));
	for (int y = 0; y < CellH;y++){
		for (int x = 0; x < CellW;x++){
			if (Cell[x][y]){
				cv::rectangle(
					wallpaper,
					cv::Point(ImgW / CellW*x, ImgH / CellH*y),
					cv::Point(ImgW / CellW*(x + 1), ImgH / CellH*(y + 1)),
					cv::Scalar(0),
					-1
				);
			}
		}
	}
	cv::imwrite("C:\\wallpaper\\wallpaper.bmp", wallpaper);
}

void ChangeWallpaper(){
	SystemParametersInfoA(
		SPI_SETDESKWALLPAPER,
		0,
		"C:\\wallpaper\\wallpaper.bmp",
		SPIF_SENDCHANGE
	);
}

int main(){

	Init();
	for (int i = 0; i < 1000;i++){
		ImgWrite();
		ChangeWallpaper();
		Update();
		Sleep(200);
	}
	

	return 0;
}