X Window Systemでnvidia,fglrx以外のドライバを用いた環境における明るさとガンマの調整について(ページ3/3)
「X Window Systemでnvidia,fglrx以外のドライバを用いた環境における明るさとガンマの調整について(ページ2/3)」の続き。
自作の明るさ/ガンマ調整ツールのコード
ページ2のメモの内容を踏まえ、明るさと各色成分ごとのガンマの両方を同時に設定できるCLIツールを作成したものを下に貼り付ける。ライセンスはMITとする。
コードはPythonで記述しており、実行属性を付けて実行するだけでコンパイルの作業は必要ない(動作もOSやアーキテクチャに非依存となる)が
- libXxf86vm(/usr/lib(64)/libXxf86vm.so.1)
- バージョンが2.6.x/2.7.x/3.x.xのいずれかのPython
の両方が必要となる。ただ、GUI環境込みでインストールされたGNU/Linuxにおいてはどちらもインストール済みのことが多い。
[任意]ファイル名: xbrightness-rgbgamma.py ライセンス: MIT
#! /usr/bin/python # # X11 brightness / gamma adjustment tool # version 20110505 # (C) 2011 kakurasan # Licensed under MIT # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. # # THANKS: # xbrightness by Asher Blum and Jean-Daniel Pauget from __future__ import print_function # for 2.6/2.7 import ctypes import math import sys import os class GetGammaRampSizeError (Exception): pass class GetGammaRampError (Exception): pass class SetGammaRampError (Exception): pass class XOpenDisplayError (Exception): pass class Libxxf86vm: try: __lib = ctypes.CDLL ('libXxf86vm.so.1') except OSError as e: print ('Error: {0}'.format (e), file=sys.stderr) sys.exit (1) __ramp_size = ctypes.c_int () def __init__ (self): # XOpenDisplay(): Display * self.__display = self.__lib.XOpenDisplay (None) # envar "DISPLAY" if not self.__display: raise XOpenDisplayError () # XDefaultScreen: Display * self.__screen = self.__lib.XDefaultScreen (self.__display) # XF86VidModeGetGammaRampSize(): Display *, int, int * ret = self.__lib.XF86VidModeGetGammaRampSize (self.__display, self.__screen, ctypes.byref (self.__ramp_size)) if not ret: raise GetGammaRampSizeError () Ramp = ctypes.c_ushort * self.__ramp_size.value # type (self.__ramp_red, self.__ramp_green, self.__ramp_blue) = (Ramp (), Ramp (), Ramp ()) # XF86VidModeGetGammaRamp(): Display *, int, int, # unsigned short *, unsigned short *, unsigned short * ret = self.__lib.XF86VidModeGetGammaRamp (self.__display, self.__screen, self.__ramp_size, self.__ramp_red, self.__ramp_green, self.__ramp_blue) if not ret: raise GetGammaRampError () # max output -> brightness self.__brightness = self.__ramp_red[self.__ramp_size.value - 1] def __del__ (self): if self.__display: # XCloseDisplay(): Display * self.__lib.XCloseDisplay (self.__display) def set_gamma (self, gamma_red, gamma_green, gamma_blue): self.set_gamma_and_brightness (self.__brightness, gamma_red, gamma_green, gamma_blue) def set_brightness (self, brightness): # calculate current gamma gamma_red = 1.0 / math.log (self.__ramp_red[self.__ramp_size.value / 2] / float (self.__brightness), (self.__ramp_size.value / 2) / float (self.__ramp_size.value - 1)) gamma_green = 1.0 / math.log (self.__ramp_green[self.__ramp_size.value / 2] / float (self.__brightness), (self.__ramp_size.value / 2) / float (self.__ramp_size.value - 1)) gamma_blue = 1.0 / math.log (self.__ramp_blue[self.__ramp_size.value / 2] / float (self.__brightness), (self.__ramp_size.value / 2) / float (self.__ramp_size.value - 1)) #gamma_red = 1.0 / (math.log (self.__ramp_red[self.__ramp_size.value / 2] / float (self.__brightness)) / math.log ((self.__ramp_size.value / 2) / float (self.__ramp_size.value - 1))) #gamma_green = 1.0 / (math.log (self.__ramp_green[self.__ramp_size.value / 2] / float (self.__brightness)) / math.log ((self.__ramp_size.value / 2) / float (self.__ramp_size.value - 1))) #gamma_blue = 1.0 / (math.log (self.__ramp_blue[self.__ramp_size.value / 2] / float (self.__brightness)) / math.log ((self.__ramp_size.value / 2) / float (self.__ramp_size.value - 1))) #print ('gamma_red:{0} gamma_green:{1} gamma_blue:{2}'.format (gamma_red, gamma_green, gamma_blue)) self.set_gamma_and_brightness (brightness, gamma_red, gamma_green, gamma_blue) def set_gamma_and_brightness (self, brightness, gamma_red, gamma_green, gamma_blue): for i in range (self.__ramp_size.value): p = i / float (self.__ramp_size.value - 1) self.__ramp_red[i] = ctypes.c_ushort (int (brightness * pow (p, 1 / gamma_red))) self.__ramp_green[i] = ctypes.c_ushort (int (brightness * pow (p, 1 / gamma_green))) self.__ramp_blue[i] = ctypes.c_ushort (int (brightness * pow (p, 1 / gamma_blue))) #print ('i:{0:3d} R:{1:5d} G:{2:5d} B:{3:5d}'.format (i, self.__ramp_red[i], self.__ramp_green[i], self.__ramp_blue[i])) # XF86VidModeSetGammaRamp(): Display *, int, int, # unsigned short *, unsigned short *, unsigned short * ret = self.__lib.XF86VidModeSetGammaRamp (self.__display, self.__screen, self.__ramp_size, self.__ramp_red, self.__ramp_green, self.__ramp_blue) if not ret: raise SetGammaRampError () self.__brightness = brightness (self.__gamma_red, self.__gamma_green, self.__gamma_blue) = (gamma_red, gamma_green, gamma_blue) # main if len (sys.argv) < 2: print (''' USAGE: {0} [BRIGHTNESS] {0} [BRIGHTNESS] [GAMMA] {0} [BRIGHTNESS] [GAMMA_RED] [GAMMA_GREEN] [GAMMA_BLUE] {0} [GAMMA_RED] [GAMMA_GREEN] [GAMMA_BLUE] BRIGHTNESS: 0 - 65535 GAMMA,GAMMA_RED,GAMMA_GREEN,GAMMA_BLUE: 0.000..1 - 10'''.format (__file__)) sys.exit (0) if len (sys.argv) == 4: # gamma (red + green + blue) gamma_red = sys.argv[1] gamma_green = sys.argv[2] gamma_blue = sys.argv[3] else: brightness = sys.argv[1] if len (sys.argv) == 3: # brightness + gamma (all) gamma_red = gamma_green = gamma_blue = sys.argv[2] elif len (sys.argv) == 5: # brightness + gamma (red + green + blue) gamma_red = sys.argv[2] gamma_green = sys.argv[3] gamma_blue = sys.argv[4] if len (sys.argv) != 4: # check invalid brightness try: brightness = int (brightness) except ValueError: print ('Error: Invalid value "{0}"'.format (brightness), file=sys.stderr) sys.exit (1) if len (sys.argv) > 2: # check invalid gamma try: gamma_red = float (gamma_red) except ValueError: print ('Error: Invalid value "{0}"'.format (gamma_red), file=sys.stderr) sys.exit (1) try: gamma_green = float (gamma_green) except ValueError: print ('Error: Invalid value "{0}"'.format (gamma_green), file=sys.stderr) sys.exit (1) try: gamma_blue = float (gamma_blue) except ValueError: print ('Error: Invalid value "{0}"'.format (gamma_blue), file=sys.stderr) sys.exit (1) # check range if gamma_red <= 0 or gamma_green <= 0 or gamma_blue <= 0: print ('Error: Value must be greater than 0', file=sys.stderr) sys.exit (1) if gamma_red > 10 or gamma_green > 10 or gamma_blue > 10: print ('Error: Value must be less or equal to 10', file=sys.stderr) sys.exit (1) # start try: lib = Libxxf86vm () except XOpenDisplayError: print ('Error: Could not open display: "{0}"'.format (os.environ['DISPLAY']), file=sys.stderr) sys.exit (1) except GetGammaRampSizeError: print ('Error: XF86VidModeGetGammaRampSize() failed', file=sys.stderr) sys.exit (1) except GetGammaRampError: print ('Error: XF86VidModeGetGammaRamp() failed', file=sys.stderr) sys.exit (1) try: if len (sys.argv) == 2: lib.set_brightness (brightness) elif len (sys.argv) == 4: lib.set_gamma (gamma_red, gamma_green, gamma_blue) else: # 3 or 5 lib.set_gamma_and_brightness (brightness, gamma_red, gamma_green, gamma_blue) except SetGammaRampError: print ('Error: XF86VidModeSetGammaRamp() failed', file=sys.stderr) sys.exit (1)
(2011/5/5)ディスプレイが開けなかった場合の処理を修正
下は使用法。明るさは0-65535の範囲の整数,ガンマ補正値は0より大きく10以下の値を指定する。
(明るさのみ変更・ガンマ補正値は変更しない) $ [xbrightness-rgbgamma.pyの場所] [明るさ] (明るさと同時に全ての色成分で共通のガンマ補正値を変更) $ [xbrightness-rgbgamma.pyの場所] [明るさ] [全ての色成分で共通のガンマ補正値] (明るさと同時に各色成分のガンマ補正値を変更) $ [xbrightness-rgbgamma.pyの場所] [明るさ] [赤成分のガンマ補正値] [緑成分のガンマ補正値] [青成分のガンマ補正値] (各色成分のガンマ補正値のみを変更・明るさは変更しない) $ [xbrightness-rgbgamma.pyの場所] [赤成分のガンマ補正値] [緑成分のガンマ補正値] [青成分のガンマ補正値]
関連記事:
- PythonからC言語の関数を呼び出す
- X Window Systemでnvidia,fglrx以外のドライバを用いた環境における明るさとガンマの調整について(ページ1/3)
- X Window Systemでnvidia,fglrx以外のドライバを用いた環境における明るさとガンマの調整について(ページ2/3)
使用したバージョン:
- Python 2.6.6, 3.1.2
- libXxf86vm 1.1.0