Yoko
http://forum.yoko.com.ua/

Цвета в Ultima Online
http://forum.yoko.com.ua/viewtopic.php?f=6&t=13022
Page 1 of 3

Author:  Destruction [ 2008-01-07 17:06:24 ]
Post subject:  Цвета в Ultima Online

Объясните пожалуйста мне неразумному, как в UO происходит наложение цвета на картинку?

На стратиксе нашёл лишь совсем краткое описание данного процесса:
Quote:
Hues are applied to an image in one of two ways. Either all gray pixels are mapped to the specified color range (resulting in a part of an image changed to that color) or all pixels are first mapped to grayscale and then the specified color range is mapped over the entire image.

Quote:
Цвета наносятся на изображение одновременно двумя способами. Каждый серый пиксел преобразуется в указанный цветовой диапазон (получается изображение отчасти изменённое к тому цвету) или все пикселы сначала преобразуются в оттенки серого и затем указанный диапазон цветов применяется поверх полученного изображения.


Конкретно как нужно заменять цвета - мне не ясно..

К примеру:
Есть картинка - http://ultimasoft.ru/tools/pants.gif
Есть цвет вытащенный из hues.mul - http://ultimasoft.ru/tools/image.php?show=hue
Должен получится такой результат - http://ultimasoft.ru/tools/result.gif

Т.к. я понятия не имею как должен происходит процесс наложения - мой результат несколько отличается от должного - http://ultimasoft.ru/tools/image.php ..

Объясните пожалуйста, как должно происходить наложение?..

PS: Я точно знаю, кто мне поможет.. :) Ты ведь мне поможешь?)

Author:  Grin [ 2008-01-07 17:16:53 ]
Post subject: 

не наложение идет, а замена палитры. невдавался вподробности, но логично предположить, что цвет пикселя преобразуется в 32 цветную шкалу серого, получаем номер ячейки, и изменяем на соответствующий цвет.

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

Author:  Destruction [ 2008-01-07 17:21:41 ]
Post subject: 

Grin wrote:
не наложение идет, а замена палитры. невдавался вподробности, но логично предположить, что цвет пикселя преобразуется в 32 цветную шкалу серого, получаем номер ячейки, и изменяем на соответствующий цвет

Не совсем ясно изложено, но в принципе идею понял. У меня к слову тоже идёт замена палитры, просто я видимо не совсем корректно выразился.

Вопрос за малым, как серый цвет из RGB корректно преобразовать в 32-цветную шкалу серого?

Слово подчеркнул не случайно - в голове есть минимум два варианта, интересует правильный.

PS: Английский у меня страдает, переведи полностью?)

PPS: Тоже кнопочка "редактировать" нравится?)

Author:  Grin [ 2008-01-07 17:35:44 ]
Post subject: 

чисто логически... каждый канал равноправен, следовательно на каждый канал при ходит 1\3 всего спектра.
логично было бы предположить
Gray = Int((R+G+B)/3)

В инете отрыл что в телеке другие предпочтения;) в плане по весам 0.30R 0.59G 0.11B

сейчас еще посмотрю

Author:  Destruction [ 2008-01-07 17:38:30 ]
Post subject: 

Grin wrote:
чисто логически... каждый канал равноправен, следовательно на каждый канал при ходит 1\3 всего спектра.
логично было бы предположить
Gray = Int((R+G+B)/3*32)

Гм..

А почему умножить на 32? Скорее уж делить на 256/32, т.е. на 8..

Такой вариант тоже в голове крутился, раз он пришёл не только ко мне в голову - видимо он правильный, пойду пробовать :)

Author:  Grin [ 2008-01-07 17:42:01 ]
Post subject: 

признаю ошибся, но делить ничего не надо...

Author:  Grin [ 2008-01-07 17:44:27 ]
Post subject: 

на 1-у ячейку отводится 2 байта, тобишь 16 бит. как разделить на 3 канала?;) правельно значит используется только 15 бит.
следовательно по 5 бит на канал, это 32 комбинаци
следовательно каждый из каналов 32 цвета.

Но интересна фишка с 0 цветом, или там отдельно логика (надо проверять), + Черный - прозрачный.

Author:  Destruction [ 2008-01-07 17:45:21 ]
Post subject: 

Grin wrote:
признаю ошибся, но делить ничего не надо...

Не суть важно, у меня в скрипте записано так:
floor( ( red + green + blue ) / 24 );

Итого получается циферка от 0 до 31 и что самое главное - оно работает.

Большое спасибо :)

Чёрный цвет = прозрачный, за это я бы не стал париться, пока мой скрипт чёрный цвет просто игнорирует.

А вообще - достаточно было сказать, что в hues.mul хранятся цветовые палитры - за полчасика я бы дошёл до решения сам и был бы безмерно счастлив :)

Author:  Grin [ 2008-01-07 17:48:51 ]
Post subject: 

0.299R 0.587G 0.114B еще вариация на право быть правельной. используется в конвертации в YIQ

а поповоду цвета, это уже от твоей картинки зависет.
Кстати флор вроде с округлением работае, лутше Инт использовать;)

Author:  Destruction [ 2008-01-07 17:51:12 ]
Post subject: 

Grin wrote:
0.299R 0.587G 0.114B еще вариация на право быть правельной. используется в конвертации в YIQ

Ну в целях общего образования - предлагаю тебе расписать полностью. Т.к. я вообще ничего не понял.

В данный момент - всё работает, как нужно за исключением совсем мелких отличий в цвете, я бы предложил свалить это на особенности gd-библиотеки, которая юзится у меня.

PS: А мне floor и нада, у меня свои особенности кода.. Это ж PHP, там всё проще :)

PPS: А цветовую палитру я неплохо нарисовал.. Хоть вэб-редактор hues.mul пиши.. Кстате идея :)

Author:  Grin [ 2008-01-07 17:58:20 ]
Post subject: 

Строится предположение, что каждый канал цвета вносит разный вклад в интенсивнсть, хз почему но люди решили указать какой изканалов более мение вносит изменение.
0.299R 0.587G 0.114B
отсюда
зеленый вносит самую большую интенсивность
далее красный ну и потом синий.

следовательно для твоего случия

Gray32 = int((0.299R+0.587G+0.114B)*32/Колво_цветов_на_канал_исходной_картинки)

Author:  Grin [ 2008-01-07 18:01:06 ]
Post subject: 

Покажи результат то;)

Author:  Destruction [ 2008-01-07 18:02:56 ]
Post subject: 

Grin wrote:
Строится предположение, что каждый канал цвета вносит разный вклад в интенсивнсть, хз почему но люди решили указать какой изканалов более мение вносит изменение.
0.299R 0.587G 0.114B
отсюда
зеленый вносит самую большую интенсивность
далее красный ну и потом синий.

следовательно для твоего случия

Gray32 = int((0.299R+0.587G+0.114B)*32/Колво_цветов_на_канал_исходной_картинки)


Ок, Gray32 высчитали, вопрос в том, а где идёт поправка на интенсивность?..

Касательно небольшого различия в цветах предполагаемого результата и непосредственно результата, я могу объяснить:
result.gif = Inside UO + Gump Studio + Photoshop (для конвертации)
image.php = Inside UO + Photoshop (для конвертации) + PHP GD (для раскраски)

Как видишь - пути несколько разные и логично предположить, что разные программы решили задачу несколько по-разному + выходной формат у меня GIF, ибо PHP GD не совсем корректно работает с цветовой палитрой BMP и весят последние просто неприлично много. Это я ещё не уверен, что в уошных файлах графика зарыта в BMP формате.. Хотя скорее всего оно именно так.

Author:  Grin [ 2008-01-07 18:05:21 ]
Post subject: 

0.299R+0.587G+0.114B

видишь коэфициенты?;) то у всех был один коэфициент 0.3(3) а теперь вон какие;) тоесть каналы делают не одинаковый вклад в интенсивность.

Author:  Destruction [ 2008-01-07 18:07:34 ]
Post subject: 

Grin wrote:
0.299R+0.587G+0.114B

видишь коэфициенты?;) то у всех был один коэфициент 0.3(3) а теперь вон какие;) тоесть каналы делают не одинаковый вклад в интенсивность.


Ммм.. Непонятно :)

Author:  Grin [ 2008-01-07 18:14:53 ]
Post subject: 

графика именно так и хранится по пиксельно;) на пиксель 2 байта, это для простых тайлов, а сложные арты еще больше кушают...

Author:  Grin [ 2008-01-07 18:17:02 ]
Post subject: 

Destruction wrote:

Ммм.. Непонятно :)

тогда наверно проще спросить, а что понятно?;)
помойму все очевидно;)
скажем так;) зеленый темнеет быстрей;)

Author:  Destruction [ 2008-01-07 18:22:05 ]
Post subject: 

Попробуем иначе, вот код:

Code:
<?php

$im = "pants.gif"; // картинка которую будем раскрашивать
$hexcolor = "0000020C0418072409300B400D4C0F5812641470167C367876749670D66CF66836655661765DB659D6551552354E754A9546B542F53E153B55377533B52FD52B"; // цвета из hues.mul

// Преобразование цветов в RGB
$colors = Array();
For( $i = 0; $i < StrLen( $hexcolor ) / 4; $i ++ ){
   $colors[ $i ] = Array();
   $tmp = (String)DecBin( HexDec( SubStr( $hexcolor, $i * 4, 4 ) ) );
   While( StrLen( $tmp ) < 16 ){
      $tmp = "0" . $tmp;
   }
   $colors[ $i ][ 'r' ] = BinDec( SubStr( $tmp, 9, 5 ) ) * 8;
   $colors[ $i ][ 'g' ] = BinDec( SubStr( $tmp, 14, 2 ) . SubStr( $tmp, 0, 3 ) ) * 8;
   $colors[ $i ][ 'b' ] = BinDec( SubStr( $tmp, 3, 5 ) ) * 8;
}

// Вывод палитры цветов
if( @$_GET['show'] == 'hue' ){
   $im = ImageCreateTrueColor( 640, 240 );
   For( $i = 0; $i < 32; $i ++ ){
      $color = ImageColorAllocate( $im, $colors[ $i ]['r'], $colors[ $i ]['g'], $colors[ $i ]['b'] );
      ImageFilledRectangle( $im, $i * 20, 0, $i * 20 + 20, 200, $color );
      // нехитрая конструкция выбора цвета для шрифта - чёрный или белый.
      $color = $colors[ $i ]['r'] + $colors[ $i ]['g'] + $colors[ $i ]['b'] < 255*3/2 ? 255 : 0;
      $color = ImageColorAllocate( $im, $color, $color, $color );
      ImageStringUp(
         $im, 5, $i * 20, 195,
         "Color: #" .
         strtoupper( sprintf( "%02s", dechex( $colors[ $i ][ 'r' ] ) ) ) .
         strtoupper( sprintf( "%02s", dechex( $colors[ $i ][ 'g' ] ) ) ) .
         strtoupper( sprintf( "%02s", dechex( $colors[ $i ][ 'b' ] ) ) ) .
         " (" . SubStr( $hexcolor, $i * 4, 4 ) . "h)",
         $color
      );
   }
   $color = ImageColorAllocate( $im, 0xFF, 0xFF, 0xFF );
   ImageFilledRectangle( $im, 0, 200, 640, 240, $color );
   $color = ImageColorAllocate( $im, 0x00, 0x00, 0x00 );
   ImageString( $im, 5, 2, 200, "Hex:" . substr( $hexcolor, 00, 64 ), $color );
   ImageString( $im, 5, 2, 220, "Hex:" . substr( $hexcolor, 64, 64 ), $color );
   Header( "Content-Type: image/gif" );
   ImageGif( $im );
   ImageDestroy( $im );
   exit;
}

// раскраска картинки
$im = ImageCreateFromGif( $im );
for( $i = 0; $i < ImageColorsTotal( $im ); $i ++ ){
   $color = ImageColorsForIndex( $im, $i );
   if( Implode( "", $color ) != "0000" ){
      $gray = floor( ( $color['red'] + $color['blue'] + $color['green'] ) / 24 );
      ImageColorSet( $im, $i, $colors[ $gray ][ 'r' ], $colors[ $gray ][ 'g' ], $colors[ $gray ][ 'b' ] );
   }
}

// вывод результата
Header( "Content-Type: image/gif" );
ImageGif( $im );
ImageDestroy( $im );

exit;


?>


Тут что-то неправильно и ты можешь сказать, как было бы корректнее.. Верно?)

PS: Я обычно не использую заглавные буквы в ф-циях, выделил специально для тех, кто незнаком с пхп - код в принципе интуитивно понятен.

PPS: Спасибо за информацию, будем знать, как оно хранится в файлах уо.. :)

Author:  Grin [ 2008-01-07 18:28:34 ]
Post subject: 

$gray = floor( ( 0.299*$color['red'] + 0.114*$color['blue'] + 0.587*$color['green'] )*3 / 24 );

Не посмотрел порядок в котором ты цвета указал...

Author:  Destruction [ 2008-01-07 18:48:17 ]
Post subject: 

Grin wrote:
$gray = floor( ( 0.299*$color['red'] + 0.114*$color['blue'] + 0.587*$color['green'] )*3 / 24 );

Не посмотрел порядок в котором ты цвета указал...

Понял :)

Пробовать не буду.

Меня пока устраивает то, как оно ща работает.

Page 1 of 3 All times are UTC+02:00
Powered by phpBB® Forum Software © phpBB Limited
https://www.phpbb.com/