Windows Terminal 背景图片切换工具

Windows Terminal 背景图片切换工具


说在前面

使用 Windows Terminal 有一段时间了,但是安装之后一直没有动过配置,做了点儿简单的修改,希望有一个比较舒服的终端背景。实现了一个终端背景图片变化的功能,每一次开机都会随机几张图片,作为不同终端的背景,也可以通过调用命令实时更换背景。也支持对于不同背景的打分功能,对于喜欢的图片增加它出现的机率,不喜欢的图片可以让它不再出现。是在做毕设之余完成的,非常简单的一个工具,但是我挺喜欢的,就拿来更一下(好久没更了呀,诈尸一波。。。)

思路说明

  • 首先,我们需要一个背景图库,我们叫他 WhiteAlbum 🐶🐶🐶
    里面包含了一些平时收的图。这里我的图挺多的就用本地的图了,后面有空考虑做个爬壁纸的工具,再搞一个评价壁纸质量的工具,有缘再说。

  • 接下来就是修改终端的背景,这个很容易通过修改settings.json对应的参数做到,我们简单实现个代码完成。changeWindowsTerminalBackground.cpp 实现图片的随机抽取,并修改对应的json文件参数。为了方便后面的步骤,准备一个文件candidatesList.txt存下所有候选的图片的路径,随机抽取时,直接在候选的列表里随机出来。

  • 再之后就是评价机制,用一个最简单的思路:用一个图片在候选列表里出现的次数越多,就表示用户越喜欢这张图,如果用户不喜欢某一张图,直接将这张图从列表里删除。由于,一般来说常用的终端就是powershell,cmd 和 wsl,需要具体指向特定的窗口。这部分在like.cpp和dislike.cpp中实现。

  • 开机自启和方便调用很容易就可以在系统里设置。

背景图片修改

打开Windows Terminal后,'Ctrl + ,'打开settings.json文件。其中"profiles"中的"list"部分,每一个大括号中添加:

"acrylicOpacity": 0.85,
"useAcrylic": true,
"backgroundImage": "Background Image Path", // D://A.jpg
"backgroundImageOpacity": 0.25,
"backgroundImageStretchMode": "fill"

我本地的 settings.json 路径为:

C:\Users\Username\AppData\Local\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json

只需要通过,修改settings.json中"backgroundImage"的路径即可实现修改背景。

candidatesList初始化

为了方便, candidatesList.txt 的格式如下:

 "backgroundImage": "C:\\WhiteAlbum\\1.jpg",
 "backgroundImage": "C:\\WhiteAlbum\\2.jpg",
 "backgroundImage": "C:\\WhiteAlbum\\3.jpg",
  ...
 "backgroundImage": "C:\\WhiteAlbum\\223.jpg",

每一行是对应的图片文件路径,可以不编号为数字。可以手动添加,也可使用一些方法遍历目录下的所有文件,来初始化 candidatesList.txt,这里不多赘述。

背景图片更新实现

实现 changeWindowsTerminalBackground.cpp

#include <bits/stdc++.h>

using namespace std;

#define MAX_VSTR 223
string vstr[MAX_VSTR];
string randBackgroundImage() { // 随机一张图片
    // candidatesList.txt 绝对路径
    ifstream fin("D:\\changeWindowsTerminalBackground\\candidatesList.txt");
    string str;
    int cnt = 0, sum = -1;
    while(getline(fin,str)) {
        vstr[cnt++] = str;
        if(cnt >= MAX_VSTR) cnt = 0, sum = MAX_VSTR;
    }
    fin.close();
    if(sum == -1) sum = cnt;
    return vstr[rand()%sum];
}

int main(int argv, char * argc[]) {
    srand(time(0));
    if(argv == 1) {
        // settings.json 绝对路径
        ifstream fin("C:\\Users\\Username\\AppData\\Local\\Packages\\Microsoft.WindowsTerminal_8wekyb3d8bbwe\\LocalState\\settings.json");
        string str, res;
        while(getline(fin,str)) {
            if( str.find("\"backgroundImage\": ") != str.npos ) {
                str = randBackgroundImage();
            }
            res += str;
            res += "\n";
        }
        fin.close();
        ofstream fout("C:\\Users\\Username\\AppData\\Local\\Packages\\Microsoft.WindowsTerminal_8wekyb3d8bbwe\\LocalState\\settings.json");
        fout << res;
        fout.close();
    }
    else {
        for(int i = 1; i < argv; ++ i) {
            string block = argc[i];
            ifstream fin("C:\\Users\\Username\\AppData\\Local\\Packages\\Microsoft.WindowsTerminal_8wekyb3d8bbwe\\LocalState\\settings.json");
            string str, res;
            int inBlock = 0, isChanged = 0;
            while(getline(fin,str)) {
                if( str.find(block) != str.npos ) inBlock = 1;
                if( !isChanged && inBlock && str.find("\"backgroundImage\": ") != str.npos ) {
                    str = randBackgroundImage();
                    isChanged = 1;
                }
                res += str;
                res += "\n";
            }
            fin.close();
            ofstream fout("C:\\Users\\Username\\AppData\\Local\\Packages\\Microsoft.WindowsTerminal_8wekyb3d8bbwe\\LocalState\\settings.json");
            fout << res;
            fout.close();
        }
    }
}

编译及使用方法为:

g++ -o changeWTBK .\changeWindowsTerminalBackground.cpp -std=c++11
changeWTBK // 更新3个终端的图片
changeWTBK cmd // 更新cmd终端的图片
changeWTBK cmd powershell // 更新cmd和powershell终端的图片
changeWTBK cmd powershell wsl // 更新wsl,cmd和powershell终端的图片

其余组合方法类似

评价机制实现

like.cpp 实现将对应终端中当前的图片加入candidateList.txt

#include <bits/stdc++.h>
using namespace std;
int main(int argv, char * argc[]) {
    if(argv == 1) {
        ifstream fin("C:\\Users\\Username\\AppData\\Local\\Packages\\Microsoft.WindowsTerminal_8wekyb3d8bbwe\\LocalState\\settings.json");
        ofstream fout("D:\\changeWindowsTerminalBackground\\candidatesList.txt",ios::app);    
        string str, res;
        while(getline(fin,str)) {
            if( str.find("\"backgroundImage\": ") != str.npos ) {
                fout << str << endl;
            }
        }
        fin.close();
        fout.close();
    }
    else {
        for(int i = 1; i < argv; ++ i) {
            string block = argc[i];
            ifstream fin("C:\\Users\\Username\\AppData\\Local\\Packages\\Microsoft.WindowsTerminal_8wekyb3d8bbwe\\LocalState\\settings.json");
            ofstream fout("D:\\changeWindowsTerminalBackground\\candidatesList.txt",ios::app);
            string str;
            int inBlock = 0, isChanged = 0;
            while(getline(fin,str)) {
                if( str.find(block) != str.npos ) inBlock = 1;
                if( !isChanged && inBlock && str.find("\"backgroundImage\": ") != str.npos ) {
                    fout << str << endl;
                    isChanged = 1;
                }
            }
            fin.close();
            fout.close();
        }
    }
}

编译及使用方法为:

g++ -o LIKE .\like.cpp -std=c++11
LIKE // 3个终端的图片都加入candidateList.txt
LIKE cmd // cmd终端的图片加入candidateList.txt
LIKE cmd powershell // cmd和powershell终端的图片加入candidateList.txt
LIKE cmd powershell wsl // wsl,cmd和powershell终端的图片加入candidateList.txt

其余组合方法类似

dislike.cpp 实现将对应终端中当前的图片从candidateList.txt中删除

#include <bits/stdc++.h>
using namespace std;
vector<string> del;
int main(int argv, char * argc[]) {
    if(argv == 1) {
        ifstream fin("C:\\Users\\Username\\AppData\\Local\\Packages\\Microsoft.WindowsTerminal_8wekyb3d8bbwe\\LocalState\\settings.json");
        string str, res;
        while(getline(fin,str)) {
            if( str.find("\"backgroundImage\": ") != str.npos ) {
                del.push_back(str);
            }
        }
        fin.close();
    }
    else {
        for(int i = 1; i < argv; ++ i) {
            string block = argc[i];
            ifstream fin("C:\\Users\\Username\\AppData\\Local\\Packages\\Microsoft.WindowsTerminal_8wekyb3d8bbwe\\LocalState\\settings.json");
            string str;
            int inBlock = 0, isChanged = 0;
            while(getline(fin,str)) {
                if( str.find(block) != str.npos ) inBlock = 1;
                if( !isChanged && inBlock && str.find("\"backgroundImage\": ") != str.npos ) {
                    del.push_back(str);
                    isChanged = 1;
                }
            }
            fin.close();
        }
    }

    ifstream fin("D:\\changeWindowsTerminalBackground\\candidatesList.txt",ios::app);
    string str,res;
    while(getline(fin,str)) {
        int flag = 0;
        for(auto A: del) if(str.find(A) != str.npos) flag = 1;
        if(!flag) res += str, res += "\n";
    }
    fin.close();
    ofstream fout("D:\\changeWindowsTerminalBackground\\candidatesList.txt");
    fout << res;
    fout.close();
}

编译及使用方法为:

g++ -o DISLIKE .\dislike.cpp -std=c++11
DISLIKE // 3个终端的图片都从candidateList.txt删去
DISLIKE cmd // cmd终端的图片从candidateList.txt删去
DISLIKE cmd powershell // cmd和powershell终端的图片从candidateList.txt删去
DISLIKE cmd powershell wsl // wsl,cmd和powershell终端的图片从candidateList.txt删去

其余组合方法类似

其他设置

我们希望每次开机,都会有不同的背景。因此将changeWTBK设为开机启动项,具体方法是:
将 changeWTBK的快捷方式移到 USERPROFILE%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup 中。

同时我们希望调用更加方便,因此可以将changeWTBK,LIKE,DISLIKE所在的目录加入环境变量。

效果实现

以powershell为例,当前界面如下:

AA

运行changeWTBK后,界面更新为:

BB

改进思路

如果有下一版的话,一方面,考虑实现爬取图片,进一步扩大图片的规模,不用本地提供Album;另一方面,针对用户的喜好的图片的推荐功能,更加智能一些。

posted @ 2020-06-15 23:15  RRRR_wys  阅读(1325)  评论(0编辑  收藏  举报