これは本当に馬鹿げているように聞こえますが、これをあまり使用する予定はありませんが、xrandr
または同様のものを使用して、ディスプレイをグレースケールと同等に表示するが、グレーではなく色を使用する方法はありますか?一部のアプリケーションにとっては本当に素晴らしい効果だと思います。
(これはX11のみを対象としており、Waylandやその他のディスプレイ管理システムは対象外です。これらの手法の一部は、他のツールegを使用して適用できます- GNOMEシェル 。)
琥珀色の表示を取得するには、2つの方法が考えられます。すべての色を修正する合成プラグインを挿入することと、すべての色を黄色に相当する色に修正するカラープロファイルを作成することです。これらは両方とも、おそらく価値があるよりも多くの努力を必要とします(物事の学習面は別として)。
sigveiの回答 ;で説明されているように、チャネルごとのガンマを操作することで、プライマリカラーディスプレイの適切な近似を得ることができます。 xcalib
もこれにアクセスでき、輝度とコントラストを直接制御するだけでなく、ガンマ値を指定できます。
xcalib -blue 1.0 0 1.0 -red 1.0 0 1.0 -alter
緑色の表示になります。輝度とコントラストがガンマランプに適用されるため、xrandr
を使用しても同じ結果が得られます。
ガンマランプをさらに細かく制御することは可能ですが、いずれにしてもすべてを琥珀色に再マッピングすることはできません。チャンネルを特定の範囲に「クランプ」することができます。たとえば、明るい赤には緑が導入されて琥珀色に見えますが、暗い赤は緑に表示されます...
次のコードは、これに対処する方法を示しています(エラー処理なし)。
#include <X11/Xos.h>
#include <X11/Xlib.h>
#include <X11/extensions/xf86vmode.h>
#include <stdlib.h>
int main(int argc, char **argv) {
Display * dpy = NULL;
int screen = -1;
u_int16_t * r_ramp = NULL, * g_ramp = NULL, * b_ramp = NULL;
unsigned int ramp_size = 256;
int r_tgt = 255, g_tgt = 191, b_tgt = 0;
int i;
dpy = XOpenDisplay(NULL);
screen = DefaultScreen(dpy);
/* Set up ramps */
XF86VidModeGetGammaRampSize(dpy, screen, &ramp_size);
r_ramp = (unsigned short *) calloc(ramp_size, sizeof(u_int16_t));
g_ramp = (unsigned short *) calloc(ramp_size, sizeof(u_int16_t));
b_ramp = (unsigned short *) calloc(ramp_size, sizeof(u_int16_t));
for (i = 0; i < ramp_size; i++) {
r_ramp[i] = r_tgt * 256 * i / ramp_size;
g_ramp[i] = g_tgt * 256 * i / ramp_size;
b_ramp[i] = b_tgt * 256 * i / ramp_size;
}
XF86VidModeSetGammaRamp(dpy, screen, ramp_size, r_ramp, g_ramp, b_ramp);
XCloseDisplay(dpy);
}
(あなたは必要になるでしょう -lX11 -lXxf86vm
リンクすること。)
xrandr --output $OUTPUT --gamma 1:0.01:0.01
を使用すると、ほぼモノクロの赤から黒になります。
トリプレットの数値は、ガンマ補正のrgb値であり、:で区切られ、0〜1の範囲です。緑の場合は1:0.01:0.01
を0.01:1:0.01
に、青の場合は0.01:0.01:1
に置き換えます。これら3つの基本的な色以外の色を作るのは難しいです。複数の色を通過させ始めると、非常に目立ちます。
明るい白のガンマ補正は白だけなので、この方法は暗い/黒の背景でのみ機能します。
xrandr -q
を使用して、$OUTPUT
に使用する出力IDを見つけます。たとえば、私のラップトップ画面はLVDS-1です。
プラグインをサポートする合成ウィンドウマネージャーを使用している場合は、画面のピクセルを希望どおりに変更するプラグインを作成できます。つまり、入力ピクセルの輝度を計算し、結果を琥珀色で変調します(必要に応じてガンマ補正を適用します) )。
これを実現するために、KDEウィンドウマネージャーKWinのInvert効果をハックする例を次に示します。このハックは、KWinソースツリーの effects/invert/data/1.40/invert.frag
(GPUがGLSL 1.40に対応している場合)にあるInvertエフェクトのシェーダーをカスタマイズされたコードに置き換えるだけです。
#version 140
uniform sampler2D sampler;
uniform vec4 modulation;
uniform float saturation;
in vec2 texcoord0;
out vec4 fragColor;
void main()
{
vec4 tex = texture(sampler, texcoord0);
float luminance = dot(vec3(0.2126729,0.7151522,0.0721750), pow(tex.rgb,vec3(2.2)));
float desaturated = pow(luminance, 1./2.2);
const vec3 amber=vec3(1.,0.5,0.);
tex.rgb = desaturated*amber;
tex *= modulation;
tex.rgb *= tex.a;
fragColor = tex;
}
KDE4 KWinでは、/usr/share/apps/kwin/shaders/1.40/invert.frag
にインストールされたシェーダーファイルを単に置き換えることができます(上記のコードでtexcoord0
をvaryingTexCoords
に置き換えました)。 KDE5以降、残念ながら、シェーダーはQtリソースとしてプラグインバイナリに組み込まれているため、新しいシェーダーを適用するには、ソースツリーで編集したファイルを使用してKWinを再コンパイルする必要があります。
結果は、次のスクリーンショットのように、ショートカットキーコンボによってエフェクトがアクティブ化されたときのようになります(独自のnvidia
ドライバーを搭載したGeforce GTX 750TiのKDE4 KWinでテスト)。マウスカーソルは通常ウィンドウマネージャーではなくレンダリングされるため、変更されないことに注意してください。別の方法で変更するか、Zoomエフェクトとしてシミュレートする必要があります。します。