Xfce で壁紙の色に基づいて背景色を設定するにはどうすればいいですか?

Xfce で壁紙の色に基づいて背景色を設定するにはどうすればいいですか?

Xfce で壁紙を切り替えるために使用する、数百 (おそらく数千) の画像が入ったフォルダがあります。唯一の問題は、画像を「拡大縮小」に設定すると、一部の画像に「レターボックス」効果が生じ、残りの領域が単色の背景で塗りつぶされることです。

私の質問は、背景色が画像に合わせて動的に変化し、空虚に見えず、画像にフィットするようにすることは可能でしょうか?mコミックス何を言っているのかわからない人のために簡単に説明すると、画像の大部分が白の場合は、単色の背景色を白にしたい、画像の大部分が黒の場合は、単色の背景色を黒にしたい、などです。

答え1

少し考えた後、私が見つけた情報を使ってlast-image便利なユーティリティを使用して変更を監視するPythonスクリプト(Python 3)を書くことにしました。xfconf-queryここ(境界ピクセルのみを取得するために若干変更されています)。

numpy と Pillow をインストールする必要があります (できれば pip を使用)。

pip3 install Pillow pip3 install numpy

次に、このスクリプトを含む .py ファイルを作成します。これを「change-bg-with-color.py」と呼びます。

#!/usr/bin/python3
from PIL import Image
from subprocess import Popen, PIPE
import numpy as np
import os
import traceback

# Edit to point to your workspace
WORKSPACE = "/backdrop/screen0/monitor2/workspace0"

# Choose your flavor! Average...
def compute_average_image_color(img):
    width, height = img.size

    r_total = 0
    g_total = 0
    b_total = 0
    a_total = 0

    count = 0

    # Get top and bottom borders
    for y in [0,height-1]:
        for x in range(0, width):
            r, g, b, a = img.getpixel((x,y))
            r_total += r
            g_total += g
            b_total += b
            a_total += a
            count += 1

    # Get left and right borders
    for x in [0,width-1]:
        for y in range(0, height):
            r, g, b, a = img.getpixel((x,y))
            r_total += r
            g_total += g
            b_total += b
            a_total += a
            count += 1

    return (np.uint16(r_total/count * 65535.0/255.0), np.uint16(g_total/count * 65535.0/255.0), np.uint16(b_total/count * 65535.0/255.0), np.uint16(a_total/count * 65535.0/255.0))

# or Mode
def compute_mode_image_color(img):
    width, height = img.size

    pixel_bins = {}

    # Get top and bottom borders
    for y in [0,height-1]:
        for x in range(0, width):
            pixel = img.getpixel((x,y))

            if pixel in pixel_bins:
                pixel_bins[pixel] += 1
            else:
                pixel_bins[pixel] = 1

    # Get left and right borders
    for x in [0,width-1]:
        for y in range(0, height):
            pixel = img.getpixel((x,y))

            if pixel in pixel_bins:
                pixel_bins[pixel] += 1
            else:
                pixel_bins[pixel] = 1

    pixel = (255,255,255,255)
    mode = 0
    for p,m in pixel_bins.items():
        if m > mode:
            pixel = p

    return (np.uint16(pixel[0] * 65535.0/255.0), np.uint16(pixel[1] * 65535.0/255.0), np.uint16(pixel[2] * 65535.0/255.0), np.uint16(pixel[3] * 65535.0/255.0))

# Start the monitor for changes to last-image
process = Popen(["xfconf-query", "-c", "xfce4-desktop", "-p", os.path.join(WORKSPACE, "last-image"), "-m"], stdout=PIPE)
while True:
    try:
        # Get the initial BG image from the workspace
        p2 = Popen(["xfconf-query", "-c", "xfce4-desktop", "-p", os.path.join(WORKSPACE, "last-image")], stdout=PIPE)
        (filename, err) = p2.communicate()
        exit_code = p2.wait()

        # Next, open the image
        img = Image.open(filename.decode('utf-8').strip()).convert("RGBA")

        # Determine and set the color (CHOOSE YOUR FLAVOR HERE)
        color = compute_mode_image_color(img)
        p2 = Popen(["xfconf-query", "-c", "xfce4-desktop", "-p", os.path.join(WORKSPACE, "color1"), "-s", str(color[0]) , "-s", str(color[1]), "-s", str(color[2]), "-s", str(color[3])], stdout=PIPE)
        (output, err) = p2.communicate()
        p2.wait()

        # Wait for next line
        line = process.stdout.readline()
        if line == '' and process.poll() is not None:
            break
    except Exception as e:
        print(e)
        traceback.print_exc()
        pass

フレーバー (平均またはモード) を選択します。WORKSPACEフィールドを変更して、ワークスペースを指定するようにしてください。通常は、~/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-desktop.xml で確認できます (Dial さん、ありがとうございます!)

スクリプトを実行するだけで、背景色が即座に変わります。もちろん、起動時に実行するように設定することもできますが、簡潔にするために詳細は省略しています。私の場合はこれでうまくいきました。

関連情報