Почти всегда на ночь (или утром, со словами «Что? Рассвет уже?») я включаю на ноутбуке фильм или сериал. Чтобы бубнило и успокаивало. Недавно заметил, что совсем не уменьшаю яркость при включении. Свет светит в глаза, мешает уснуть. Решается поворотом на другой бок или уменьшением яркости, конечно, но я слишком ленив, чтобы искать Fn+уменьшить яркость или установить и вывести апплет яркости. Уменьшение яркости при неактивности ставить не захотел, потому как это меня раздражает (пьешь себя кофе и смотришь код, тут резко до нуля так хрясь). Вспомнил про свою старую Nokia E70 (ох и шикарный телефон был), в котором был индикатор освещённости. Подумал, что такой датчик может заменить и обычная камера.
Ничего необычного. Фотографируем
#!/bin/bash
x=320 #ширина фото
y=240 #высота фото
n=1000 # порог проверки фото (от 0 до x*y) - каждый N пиксель будет взят для подсчета
max=40 #максимальный "цвет" (от 0 до 255)
sleep=60 #ожидание, перед повторением операции
maxbright=100 #максимальная яркость
minbright=20 #минимальная яркость
while [ 1 ]; do #бесконечный цикл
ffmpeg -f video4linux2 -s ${x}x${y} -i /dev/video0 -f image2 /tmp/snapshot.jpg 2>/dev/null #делаем скрин
convert /tmp/snapshot.jpg -colorspace gray /tmp/snapshot.jpg #обесцвечиваем его
sum=0
count=0
let "s = x*y" #всего пикселей
color=(`convert /tmp/snapshot.jpg[${x}x${y}+0+0] -depth 8 txt: | tail -n +2 | sed -n 's/^.*\(#[^ ]*\).*$/\1/p' | cut -c2-3`); #массив цветов пикселей, у которых взял только R из RGB, грубо говоря. Цвет то серый
for i in `seq 0 $n $s`; #для каждого N-го
do
#переводим цвет из 16-ричной в десятичную запись
color1=`echo ${color[i]} | cut -c1-1`
color2=`echo ${color[i]} | cut -c2-2`
case "$color1" in
"A" ) color1=10;;
"B" ) color1=11;;
"C" ) color1=12;;
"D" ) color1=13;;
"E" ) color1=14;;
"F" ) color1=15;;
esac
case "$color2" in
"A" ) color2=10;;
"B" ) color2=11;;
"C" ) color2=12;;
"D" ) color2=13;;
"E" ) color2=14;;
"F" ) color2=15;;
esac
let "rgbcolor = color1*16+color2"
let "sum = sum+rgbcolor" #сумма "цветов". Потом поделим на количество и получим средний цвет
let "count = count+1" #считаем количество
done
let "avcolor = sum/count" #средний цвет
#echo "Цвет: $avcolor" #раскомментировать для просмотра яркости при максимальном освещении (чтобы вписать в max)
let "bright=avcolor*100/$max" #яркость
#проверка на максимальную и минимальную яркость
if [ $bright -gt $maxbright ]; then
bright=$maxbright
fi
if [ $bright -lt $minbright ]; then
bright=$minbright
fi
xbacklight -set $bright #устанавливаем яркость экрана
echo "Установлена яркость: $bright"
sleep $sleep #спим
done
Максимальную яркость смотреть, когда много света. Я поставил ниже, чем выводит, чтобы при небольших изменениях яркость не прыгала туда-сюда. Надеюсь, скрипт поможет глазам хоть как-нибудь. В темноте все же лучше сидеть с чуть притушенным монитором, чем с яркостью в 100%.
Всё написано для себя, в интернете по такому подходу ничего не видел, поэтому делюсь.
Что надо установить (для работоспособности скрипта): ffmpeg, ImageMagick и xbacklight.
Усовершенствования, ошибки и всё такое жду в комментариях. Знаю, что код не идеален.
PS: на картинке камера с ноутбука ASUS N53sv (у меня такой). Если закрыть шторку, яркость падает до минимума, что подтверждает работу скрипта. Параноики, завидуйте.
UPD: romik предлагает заменять математику на
avcolor=`convert snapshot.jpg -colorspace GRAY -resize 1x1 txt: | sed 's/[^(]*(\s*\([0-9]*\),.*/\1/p;d'`
А wrewolf менять яркость через acpi
echo -n $bright > /proc/acpi/video/VGA/LCD/brightness;