Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Цвета: светлее/темнее 
:(
    Опции темы
мухр
Дата 11.8.2005, 09:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 136
Регистрация: 11.8.2005

Репутация: нет
Всего: нет



http://forum.woweb.ru/topic15973s0.html
Дублирую тему с вовеба.

Цвет задаётся #RRGGBB.
Каким алгоритмом можно реализовать, чтобы текущий цвет сделать чуток светлее или темнее: то-есть приблизить немножко к белому (#FFFFFF) или чёрному (#000000), но чтобы ясно было видно, что сам цвет (текущее равновесие каналов) не изменился?
Подозреваю, что здесь математическая функция, связанная с экспонентой.
Если понимать под цветом свечение с преобладанием каких-то определённых длин волн, то под светлым/тёмным следует понимать физическую величину, характеризующую интенсивность свечения, которая может принимать значения в интервале от нуля до бесконечности.
При текущем задании интенсивности свечения каждого канала (00-FF или 0-255) верхний порог имеет границу, следовательно, не годится вариант изменения общей яркости путём домножения значения каждого цветового канала на произвольный коеффициент.

Какая здесь может быть функция?

Это сообщение отредактировал(а) мухр - 11.8.2005, 09:41
PM WWW   Вверх
maxim1000
Дата 11.8.2005, 09:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 33
Всего: 110



Цитата
При текущем задании интенсивности свечения каждого канала (00-FF или 0-255) верхний порог имеет границу, следовательно, не годится вариант изменения общей яркости путём домножения значения каждого цветового канала на произвольный коеффициент

и тем не менее, нужно именно домножать
а то, что что-то будет вылазить за FF - ограничения RGB, и с этим ничего не поделаешь
разве что, все, что вылазит, обрезать, но это уже - изменение цвета...


--------------------
qqq
PM WWW   Вверх
мухр
Дата 11.8.2005, 09:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 136
Регистрация: 11.8.2005

Репутация: нет
Всего: нет



maxim1000, отчасти согласен: домножать, НО НЕ В ЧИСТОМ ВИДЕ. Нужно построить функцию таким образом, чтобы коеффициент домножения стремился к единице при приближении к верхнему порогу.
Тут не всё так просто. smile
Добавлено @ 10:01
Кстати, домножать в данном случае на коееффициент - неверное решение. Как интересно следующий цвет будет работать: #990000 ??? Тут домножением не отделаешься.
PM WWW   Вверх
maxim1000
Дата 11.8.2005, 10:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 33
Всего: 110



насколько я понял задача:
увеличить интенсивность в k раз (k чуть-чуть больше 1)
при этом минимизировать изменение цвета
правильно?
если да, то:
1. находим обычное решение задачи - домножением на k
2. проверяем, удовлетворяет ли решение ограничениям (FF)
3. если да, то задача решена - цвет вообще не измпенился
4. если нет, считаем, что те компоненты, которые вышли за пределы, должны быть FF, т.к. это - самое близкое допустимое значение к реальному

если вместо того, чтобы обрезать FF, делать что-то более плавное - цвет будет меняться больше...


--------------------
qqq
PM WWW   Вверх
мухр
Дата 11.8.2005, 10:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 136
Регистрация: 11.8.2005

Репутация: нет
Всего: нет



Не надо ничего проверять. Допустим, что мы работаем с реальным свечением, потому k может изменяться от нуля до бесконечности. ОДНАКО функция должна возвращать значение в КОНЕЧНЫХ пределах (0-255).

Грубо говоря:
--Resize_Images_Alt_Text--
PM WWW   Вверх
maxim1000
Дата 11.8.2005, 10:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 33
Всего: 110



но это - неправильно...
если у нас будет цвет, например 2 зеленых, 1 красный (если я не ошибаюсь, желтый)
при чем значения их будут небольшими
тогда при увеличении интенсивности зеленый увеличится сильнее (т.к. он ближе к быстрорастущему участку кривой), и общий цыет станет зеленоватым...


--------------------
qqq
PM WWW   Вверх
Петрович
Дата 11.8.2005, 11:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1000
Регистрация: 2.12.2003
Где: Москва

Репутация: нет
Всего: 55



Уже давно для этих целей использую свою функцию:
Код

function Brightnes (aColor :Longint; Percent :Integer) :Longint;
// Возвращает цвет интенсивность которого на Precent процентов больше
// (при Precent > 0) или меньше (при Precent < 0).
// Допустимый диапазон Percent - от -100%(черный) до +100%(белый)
var
  n, r, g, b :Byte;
begin
  if      Percent < 0  then begin
    Percent := -Percent;
    n := 0;
    end
  else if Percent > 0  then begin
    n := 255;
    end
  else begin
    Result := aColor;
    Exit;
  end;
  // aColor := ColorToRGB(aColor); это тянет за собой Graphics, поэтому:
  if aColor < 0 then  aColor := GetSysColor(aColor and $000000FF);
  r := GetRValue(aColor);
  g := GetGValue(aColor);
  b := GetBValue(aColor);

  Result := RGB (r + MulDiv(n-r, Percent,100)
                ,g + MulDiv(n-g, Percent,100)
                ,b + MulDiv(n-b, Percent,100) );
end;

Меня вроде устраивает smile


--------------------
Все знать невозможно, но хочется
PM ICQ   Вверх
мухр
Дата 12.8.2005, 02:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 136
Регистрация: 11.8.2005

Репутация: нет
Всего: нет



maxim1000, вышеуказанная кривая достаточно широкораспространена. Не помню, как она записывается аналитически. В зависимости от параметров она может вести себя различно: можно установить ей верхний порог и крутизну. Скорее всего, крутизна будет несколько различна для каждого из каналов, если цвет отличается от серого.
PM WWW   Вверх
мухр
Дата 12.8.2005, 02:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 136
Регистрация: 11.8.2005

Репутация: нет
Всего: нет



maxim1000, хотя даже и не крутизна здесь роль играет, а растянутость по горизонтали - скорее всего.
PM WWW   Вверх
мухр
Дата 12.8.2005, 03:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 136
Регистрация: 11.8.2005

Репутация: нет
Всего: нет



Петрович, пытаюсь разобраться с твоей функцией.
MulDiv() - это что такое?
PM WWW   Вверх
Петрович
Дата 12.8.2005, 06:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1000
Регистрация: 2.12.2003
Где: Москва

Репутация: нет
Всего: 55



Это целочисленное умножение и деление:
Вот из MSDN:
Цитата
MulDiv
The MulDiv function multiplies two 32-bit values and then divides the 64-bit result by a third 32-bit value. The return value is rounded up or down to the nearest integer.

int MulDiv(
  int nNumber,      // 32-bit signed multiplicand
  int nNumerator,    // 32-bit signed multiplier
  int nDenominator  // 32-bit signed divisor
);
Parameters
nNumber
[in] Specifies the multiplicand.
nNumerator
[in] Specifies the multiplier.
nDenominator
[in] Specifies the number by which the result of the multiplication (nNumber * nNumerator) is to be divided.
Return Values
If the function succeeds, the return value is the result of the multiplication and division. If either an overflow occurred or nDenominator was 0, the return value is –1.

Requirements
  Windows NT/2000: Requires Windows NT 3.1 or later.
  Windows 95/98: Requires Windows 95 or later.
  Header: Declared in Winbase.h; include Windows.h.
  Library: Use Kernel32.lib.



--------------------
Все знать невозможно, но хочется
PM ICQ   Вверх
Psychosis
Дата 12.8.2005, 06:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 12.8.2005

Репутация: нет
Всего: нет



Я так думаю, что MulDiv(a, b, c) = Round(a*(b/c))
PM MAIL   Вверх
мухр
Дата 12.8.2005, 07:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 136
Регистрация: 11.8.2005

Репутация: нет
Всего: нет



Что ж, надо попробовать будет.
Благодарю.
PM WWW   Вверх
Петрович
Дата 12.8.2005, 18:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1000
Регистрация: 2.12.2003
Где: Москва

Репутация: нет
Всего: 55



Цитата(Psychosis @ 12.8.2005, 07:27)
Я так думаю, что MulDiv(a, b, c) = Round(a*(b/c))

Не совсем.
Если быть более точным то это , MulDiv(a, b, c) = a * b div c .
Так будет быстрее, и с минимальными потерями точности.
А чем MulDiv - то не нравится? smile


--------------------
Все знать невозможно, но хочется
PM ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Алгоритмы"

maxim1000

Форум "Алгоритмы" предназначен для обсуждения вопросов, связанных только с алгоритмами и структурами данных, без привязки к конкретному языку программирования и/или программному продукту.


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, maxim1000.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Алгоритмы | Следующая тема »


 




[ Время генерации скрипта: 0.0865 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.