Отправляет email-рассылки с помощью сервиса Sendsay

Программирование на Visual С++

  Все выпуски  

Программирование на Visual С++ No.103 Цветовые схемы


Информационный Канал Subscribe.Ru


  ПРОГРАММИРОВАНИЕ  НА  VISUAL  C++
Статьи по программированию под Windows и платформу .NET
РАССЫЛКА САЙТА
RSDN.RU

No. 103 / 2004-10-15
Подписчиков: 26775

РАССЫЛКА ЯВЛЯЕТСЯ ЧАСТЬЮ ПРОЕКТА RSDN, НА САЙТЕ КОТОРОГО ВСЕГДА МОЖНО НАЙТИ ВСЮ НЕОБХОДИМУЮ РАЗРАБОТЧИКУ ИНФОРМАЦИЮ, СТАТЬИ, ФОРУМЫ, РЕСУРСЫ, АРХИВ ВЫПУСКОВ РАССЫЛКИ И МНОГОЕ ДРУГОЕ.

Цветовые схемы

Автор: Роман Акопов
Источник: RSDN Magazine #1-2004


Типы схем цвета

Мир полон цветов. Их разнообразие и сочетания поражают. Хочется на экране монитора воспроизвести хотя бы часть этого великолепия. Но как это сделать? Ведь и монитор, и весь компьютер в целом - это цифровые системы, а цвет не описывается ни одним, ни двумя, ни вообще каким-либо разумным конечным числом параметров полностью. Однако есть методы, дающие весьма хорошее приближение. Эти методы исходят, как правило, из двух способов: аддитивного сочетания цветов и субтрактивного. На практике аддитивному способу соответствуют лучи, а субтрактивному - краски. И те, и другие схемы исходят из предпосылки, что так или иначе смешивая несколько базовых цветов, можно создать впечатление любого видимого цвета или его хорошего приближения.


Аддитивные схемы

Аддитивные схемы легко иллюстрировать на примере лучей света. При сложении двух лучей, то есть если осветить белый предмет двумя лучами, цвет становиться светлее, ярче. Освещать надо именно белый предмет. Если осветить предмет синим лучом света, то он покажется синим. Если же красным, то он покажется красным. Если же обоими сразу, то цвет будет какой-то фиолетовый, но что самое главное, он будет светлее, чем каждый из цветов в отдельности. Итак, аддитивные схемы при смешении всех базовых цветов в равной пропорции дают оттенки серого цвета. Отсутствие составляющих означает чёрный цвет, а их максимальное количество - белый.


Субтрактивные схемы

Субтрактивные схемы легко иллюстрировать с помощью красок. При смешении двух красок мы получаем новую краску. Краски мы наносим на белый лист бумаги. Если смешать две краски, то результат будет насыщеннее и темнее. Итак, субтрактивные схемы при смешении всех базовых цветов дают оттенки серого цвета. Отсутствие составляющих означает белый цвет, а их максимальное количество - чёрный.


RGB

Эта аддитивная схема принята в большинстве световых аппаратных решений, включая мониторы. Базовыми являются 3 цвета: красный (Red), зелёный (Green) и синий (Blue).

Рисунок 1.

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

Рисунок 2.

Каждый конкретный цвет в таком случае обозначается точкой в пространстве.

Почему же именно красный, зелёный и синий? Основой человеческого зрения является сетка из сенсоров света, расположенная внутри нашего глаза. Эти сенсоры реагируют на волны различной длины, посылая мозгу комбинации электрических сигналов. Вопрос в том, как эти сенсоры посылают информацию. Разве информация это непосредственно длины волн? Человеческому зрению приходится работать быстро, чтобы справиться с потоком ежесекундно поступающих новых изображений. В удивительной конструкции этой системы используется гораздо более эффективный метод ≈ метод "пакетной обработки" потока волн различной длины. В нашем мозгу видимый спектр разбивается на три доминирующие области - красную, зеленую и синюю, и по этим цветам затем вычисляется совокупная цветовая информация. Таким образом, схема RGB соответствует в некоторой степени методам восприятия цвета глазом.


CMYK

Для начала стоит сказать, что такая схема, как CMYK, обязана своим существованием чисто технологическим причинам. Есть субтрактивная схема CMY, в которой базовые цвета - это бирюзовый (Cyan), пурпурный (Magenta) и жёлтый (Yellow). Схема, в принципе, неплохая, и могла бы с успехом использоваться, если бы не одно досадное обстоятельство. Ну не дают краски при смешении чёрного цвета! Какой-то грязно-коричневый цвет выходит - а чёрный нет. Однако полноцветные картинки печатать все-таки надо. Поэтому придумали схему CMYK с добавленным четвёртым цветом - чёрным (blacK, буква B не используется во избежание путаницы с Blue из RGB). Схема абсолютно избыточна в том смысле, что разным числовым комбинациям количества базовых цветов нередко соответствует один и тот же видимый цвет. Но не всё так просто. На самом деле теперь CMY задают оттенок и часть темноты, а другая часть задается только K, который на оттенок, естественно, не влияет. При этом соотношение CMY + K подбирается так хитро, что получившаяся комбинация великолепно отображается существующими красками. Вы спросите, стоило ли столько возиться? Не легче ли сделать нормальные краски? Увы, нет. Пока эта задача не решена, и не приходится рассчитывать на ее решение в ближайшем будущем. Надо ли говорить, что данная схема используется исключительно в полиграфии и смежных с ней отраслях. На рисунке представлена схема CMY:

Рисунок 3.

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

Рисунок 4

Каждый конкретный цвет в таком случае обозначается точкой в пространстве. Почему же были выбраны именно бирюзовый, пурпурный и жёлтый цвета? Дело в том, что в отличие от мониторов, которые сами излучают свет, принтеры, а вернее их распечатки, вынуждены пользоваться отражённым светом. В зависимости от того, какую часть света краска поглощает, а какую отражает, мы видим разные цвета. Если две краски смешать, то смесь будет поглощать все те цвета, которые поглощала первая краска, и все те, которые поглощала вторая, а отражаться будет то, что осталось. На рисунке 5 приведены различные варианты отражения от чистых красок и их смесей.

Рисунок 5


Цветовые схемы CIE

Однако возникает вопрос: как все вышеперечисленные схемы согласуются с физиологией глаза человека? Ответ прост - практически никак. Хотя рецепторы глаза действительно воспринимают красный, зелёный и синий, есть некоторые особенности восприятия, не учитываемые ни схемой RGB, ни тем более CMY(K). Однако же в некоторых случаях предельно точное отображение цвета может оказаться необходимым. А уж при необходимости распознавания цвета имитация работы глаза должна быть максимально точной.

В 1931 году комитет CIE (Commission Internationale d'Eclairage) утвердил несколько цветовых пространств, описывающих видимый спектр. Цветовые системы CIE подобны другим трехмерным моделям, рассмотренным нами выше, поскольку, для того, чтобы обнаружить положение цвета в цветовом пространстве, в них тоже используется три координаты. Однако, в отличие от описанных выше, пространства CIE не зависят от устройства, то есть диапазон цветов, которые можно определить в этих пространствах, не ограничивается изобразительными возможностями того или иного конкретного устройства или визуальным опытом определенного наблюдателя.


XYZ

Главное цветовое пространство CIE - это пространство CIE XYZ. Оно построено на основе зрительных возможностей так называемого "Стандартного Наблюдателя", то есть гипотетического зрителя, возможности которого были тщательно изучены и зафиксированы в ходе проведенных комитетом CIE длительных исследований человеческого зрения. Комитет CIE провел множество экспериментов с огромным количеством людей, предлагая им сравнивать различные цвета, а затем с помощью совокупных данных этих экспериментов построил так называемые функции соответствия цветов (color matching functions) и универсальное цветовое пространство (universal color space), в котором был представлен диапазон видимых цветов, характерный для среднестатистического человека. Функции соответствия цветов ≈ это значения каждой первичной составляющей света, которые должны присутствовать, чтобы человек со средним зрением мог воспринимать все цвета видимого спектра. Этим трем первичным составляющим были поставлены в соответствие координаты X, Y и Z. X, Y и Z не являются реально существующими цветами, но обладают одной важной особенностью. Любой цвет можно получить линейной комбинацией X, Y и Z с положительными коэффициентами. При этом координата Y равна яркости наблюдаемого цвета.

Нередко вместо XYZ для обозначения только оттенка (без яркости) используют координаты x и y, где x = X/(X+Y+Z), y = Y/(X + Y + Z). Конечно, есть ещё координата z = Z/(X + Y + Z), но она используется редко. Заметим в любом случае, что x + y + z = 1.

На рисунке 6 приведен так называемый цветовой треугольник xy, и выделена те его части, которые воспроизводятся устройствами цветного вывода.

Рисунок 6


Lab

Конечной целью комитета CIE была разработка повторяемой системы стандартов цветопередачи для производителей красок, чернил, пигментов и других красителей. Самая важная функция этих стандартов ≈ предоставить универсальную схему, в рамках которой можно было бы устанавливать соответствие цветов. В основу этой схемы легли Стандартный Наблюдатель и цветовое пространство XYZ, однако несбалансированная природа пространства XYZ, вызванная тем, что человек различает разницу между оттенками зелёного и жёлтого гораздо лучше, чем между оттенками красного и пурпурного, сделала эти стандарты трудными для четкой реализации. В результате CIE разработал более однородные цветовые шкалы - CIE Lab и CIE Luv. Из этих двух моделей более широко применяется модель CIE Lab. Хорошо сбалансированная структура цветового пространства Lab основана на той теории, что цвет не может быть одновременно зеленым и красным или желтым и синим. Следовательно, для описания красно-зеленого и желто-синего атрибутов можно воспользоваться одними и теми же значениями. Когда цвет представляется в пространстве CIE Lab, величина L обозначает яркость (luminosity), a - величину красно-зеленой составляющей, а b - величину желто-синей составляющей.

Рисунок 7

На рисунке 8 изображено видимое Стандартным Наблюдателем пространство Lab.

Рисунок 8.

А на рисунке 9 - та его часть, которая доступна 4-х красочным типографским станкам.

Рисунок 9


Другие схемы

Есть и другие схемы, основанные на представлении цвета не как смеси базовых цветов, а функции параметров иного рода. Например, довольно популярна схема HSB, в которой параметрами являются оттенок (Hue), насыщенность (Saturation), и яркость (Lightness). Ее, как и предыдущие схемы, можно отобразить в пространстве, правда, уже не в виде куба, а в виде двух конусов.

Рисунок 10


Как конвертировать цвет из одной схемы в другую?

Нередко можно слышать утверждения, что схемы RGB и CMYK только пересекаются. Другими словами есть такие RGB цвета, которые нельзя отобразить в CMYK и наоборот. Нередко можно слышать о цветопередаче принтера, монитора. Что же кроется за этими утверждениями? Дело в том, что ничто не идеально: ни краски в принтере, ни кинескоп в мониторе. Даже если на монитор поступает RGB сигнал 1:0:0 это не означает, что точка на мониторе будет действительно красной. Она будет весьма красной, но возможно ещё чуть-чуть зелёной или синей. Совсем чуть-чуть. Вы не заметите этого и скажете, что точка красная. Но если вы распечатаете на цветном принтере фотографию, которая весьма приятно выглядела на мониторе, вы можете быть разочарованы. Что же делать, если устройства отображают совсем не тот цвет, который их запросили отобразить? Как в таких условиях работать, если рисовать надо одно, а печатать другое? Каждое цветное устройство вывода имеет дефекты отображения цвета. Можно попытаться учитывать эти дефекты, пытаясь преобразовать исходный сигнал в такой, который с учётом дефекта даст правильный цвет. Это конечно не всегда возможно и иногда приходиться жертвовать оттенком или яркостью. Чем меньше этот дефект, то есть чем меньше разница между тем, что мы посылаем и тем, что рисуется, тем лучше устройство отображает цвет. Когда мы фотографию с экрана печатаем на принтере, мы имеем дело с ужасной ситуацией. Цвет преобразуется через два устройства и соответственно дважды искажается. Так как принтер это, как правило, CMYK-отображение цвета, а монитор это, как правило, RGB, то вследствие таких искажений и пошло мнение, что некоторые цвета RGB не отображаются на CMYK и наоборот. Более того, большинство устройств позволяют отображать не весь видимый набор цветов, а только его часть. И эти части у конкретных устройств могут лишь пересекаться, хотя к используемым ими цветовым схемам это не имеет отношения. Есть ещё одна причина, почему цветовые схемы на практике отображаются друг на друга не полностью или не однозначно. Дело в том, что параметры цветовых схем, как правило, хранятся с ограниченной точностью. В подавляющем большинстве случаев как целые числа. Так как перевод цвета из одной схемы в другую сопряжён не только со сложением и вычитанием приходится округлять числа и тем самым теряется исходный цвет.

Итак, как же конвертировать цвета в такой сложной ситуации? Если не требуется учитывать особенности отображения цвета устройствами, то можно прибегнуть к простым арифметическим решениям.

Предполагается, что R, G, B, C, M и Y принимают значения от 0 до 1

  

C = (G + B)/2
M = (R + B)/2
Y = (R + G)/2
R = (M + Y - C)
G = (C + Y - M)
B = (C + M - Y)

 

Однако у Windows API есть свой, более корректный, ответ на данный вопрос. Это не панацея, но таки неплохое средство - Image Color Management, сокращённо ICM. Почти каждое устройство цветного вывода при инсталляции добавляет цветовой профиль, файл с расширением ICM в котором описывается искажение при отображении цвета данным устройством. В примере ниже трансформация производится для всех найденных в системе мониторов и принтеров.

  

//
// Необходима бибилиотека Mscms.lib, добавляйте как хотите.
//
#include <windows.h>
#include <tchar.h>
#include <Icm.h>
#include <stdio.h> 
//
void PrintTransform( HTRANSFORM hTransform )
{
    // Local variables
    COLOR source;
    COLOR destination;
    // Трансформировать белый RGB в CMYK
    source.rgb.red = 255;
    source.rgb.green = 255;
    source.rgb.blue = 255;
    ZeroMemory( &destination, sizeof( destination ) );

    if ( TranslateColors( hTransform, &source, 1, COLOR_RGB, &destination, COLOR_CMYK ) )
    {
        printf( 
        "\t\tRGB(255, 255, 255) aka 'White' corresponds to CMYK(%3d, %3d, %3d, %3d)\n",
                ( BYTE ) destination.cmyk.cyan,
                ( BYTE ) destination.cmyk.magenta,
                ( BYTE ) destination.cmyk.yellow,
                ( BYTE ) destination.cmyk.black );
    }

    // Трансформировать красный RGB в CMYK
    source.rgb.red = 255;
    source.rgb.green = 0;
    source.rgb.blue = 0;

    ZeroMemory( &destination, sizeof( destination ) );

    if ( TranslateColors( hTransform, &source, 1, COLOR_RGB, &destination, COLOR_CMYK ) )
    {
        printf( 
        "\t\tRGB(255,   0,   0) aka 'Red'   corresponds to CMYK(%3d, %3d, %3d, %3d)\n",
                ( BYTE ) destination.cmyk.cyan,
                ( BYTE ) destination.cmyk.magenta,
                ( BYTE ) destination.cmyk.yellow,
                ( BYTE ) destination.cmyk.black );
    }

    // Трансформировать зелёный RGB в CMYK
    source.rgb.red = 0;
    source.rgb.green = 255;
    source.rgb.blue = 0;

    ZeroMemory( &destination, sizeof( destination ) );

    if ( TranslateColors( hTransform, &source, 1, COLOR_RGB, &destination, COLOR_CMYK ) )
    {
        printf( 
        "\t\tRGB(  0, 255,   0) aka 'Green' corresponds to CMYK(%3d, %3d, %3d, %3d)\n",
                ( BYTE ) destination.cmyk.cyan,
                ( BYTE ) destination.cmyk.magenta,
                ( BYTE ) destination.cmyk.yellow,
                ( BYTE ) destination.cmyk.black );
    }

    // Трансформировать синий RGB в CMYK
    source.rgb.red = 0;
    source.rgb.green = 0;
    source.rgb.blue = 255;

    ZeroMemory( &destination, sizeof( destination ) );

    if ( TranslateColors( hTransform, &source, 1, COLOR_RGB, &destination, COLOR_CMYK ) )
    {
        printf( 
        "\t\tRGB(  0,   0, 255) aka 'Blue'  corresponds to CMYK(%3d, %3d, %3d, %3d)\n",
                ( BYTE ) destination.cmyk.cyan,
                ( BYTE ) destination.cmyk.magenta,
                ( BYTE ) destination.cmyk.yellow,
                ( BYTE ) destination.cmyk.black );
    }

}

//
int CALLBACK EnumICMProfilesProcCallback( LPTSTR lpszFilename, LPARAM lParam )
{
    // Процедура вызываемая EnumICMProfiles для каждого цветового профиля,
    //  зарегистрированного для устройства, которому соответсвует переданный
    //  в функцию Device Context
    PROFILE profile;
    // Открыть профиль из файла
    profile.dwType = PROFILE_FILENAME;
    // Имя файла
    profile.pProfileData = lpszFilename;
    // Размер имени файла
    profile.cbDataSize = strlen( lpszFilename ) * sizeof( TCHAR );
    // Собственно открыть
    HPROFILE hProfile = OpenColorProfile( &profile, PROFILE_READ, 
                                FILE_SHARE_READ, OPEN_EXISTING );
    // И если получилось

    if ( hProfile != NULL )
    {
        // Local variables
        LOGCOLORSPACE lcs;
        // Code
        ZeroMemory( &lcs, sizeof( lcs ) );
        lcs.lcsSignature = LCS_SIGNATURE;
        lcs.lcsIntent = LCS_GM_IMAGES;
        lcs.lcsVersion = 0x400;
        lcs.lcsSize = sizeof( lcs );
        // Цветовое пространство по умолчанию
        lcs.lcsCSType = LCS_WINDOWS_COLOR_SPACE;
        // Создать преобразование
        HCMTRANSFORM hTransform = CreateColorTransform( &lcs, hProfile, 
                                                NULL, BEST_MODE );
        // Code

        if ( hTransform != NULL )
        {
            printf( "\tTesting profile '%s'\n", lpszFilename );
            // И распечатать как оно работает
            PrintTransform( hTransform );
            // А потом за собой подчистить
            DeleteColorTransform( hTransform );
        }

        // И здесь тоже не мусорить
        CloseColorProfile( hProfile );
    }

    return TRUE;
}

//
void EnumDisplayAdapterDCs()
{
    printf( "\nDISPLAY ADAPTERS\n" );
    // Перечислять все видео-адаптеры, вряд ли их больше 10

    for ( int index = 0; index < 10; index++ )
    {
        // Local variables
        DISPLAY_DEVICE displayDevice;
        // Code
        ZeroMemory( &displayDevice, sizeof( displayDevice ) );
        displayDevice.cb = sizeof( displayDevice );
        // Если адаптер есть

        if ( EnumDisplayDevices( NULL, index, &displayDevice, 0 ) )
        {
            printf( "\tEnumerating for adapter '%s'\n", displayDevice.DeviceName );
            // Создать Device Context для этого адаптера
            HDC hDC = CreateDC( displayDevice.DeviceName, NULL, NULL, NULL );
            // Перебрать все цветовые профили
            EnumICMProfiles( hDC, EnumICMProfilesProcCallback, 0 );
            // И почистить за собой
            DeleteDC( hDC );
            printf( "\tEnd of enumeration for adapter '%s'\n", displayDevice.DeviceName );
        }
    }

    printf( "END DISPLAY ADAPTERS\n" );
}

//
void EnumPrinterDCs()
{
    printf( "\nPRINTERS\n" );
    // Local variables
    DWORD needed;
    DWORD unused;
    DWORD returned;
    // Узнать сколько нужно места
    EnumPrinters( PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &needed, &unused );
    // Выделить столько сколько нужно
    PRINTER_INFO_2 * lpPrinterInfo = ( PRINTER_INFO_2 * ) malloc( needed );
    // Получить список всех принтеров в системе

    if ( EnumPrinters( PRINTER_ENUM_LOCAL, NULL, 2, 
                                ( LPBYTE ) lpPrinterInfo, needed, &unused, &returned ) )
    {
        // Перебирать все принтеры

        for ( DWORD index = 0; index < returned; index++ )
        {
            printf( "\tEnumerating for printer '%s'\n", 
                ( lpPrinterInfo + index ) ->pPrinterName );
            // Создать Device Context принтера
            HDC hDC = CreateDC( ( lpPrinterInfo + index ) ->pDriverName, 
                ( lpPrinterInfo + index ) ->pPrinterName, NULL, NULL );
            // Перебрать все цветовые профили
            EnumICMProfiles( hDC, EnumICMProfilesProcCallback, 0 );
            // Почистить за собой
            DeleteDC( hDC );
            printf( "\tEnd of enumeration for printer '%s'\n", 
                ( lpPrinterInfo + index ) ->pPrinterName );
        }
    }

    // Удалить список принтеров на фиг
    free( lpPrinterInfo );

    printf( "END PRINTERS\n" );
}

//
int main( int argc, TCHAR * argv[] )
{
    // Перебрать все мониторы
    EnumDisplayAdapterDCs();
    // Перебрать все принтеры
    EnumPrinterDCs();
    return 0;
}

//
// End of file
//

 

У меня этот пример выводит что-то такое:

  

DISPLAY ADAPTERS
    Enumerating for adapter '\\.\DISPLAY1'
    Testing profile 'C:\WINDOWS\system32\spool\DRIVERS\COLOR\995E.ICM'
        RGB(255, 255, 255) aka 'White' corresponds to CMYK(134, 101, 61, 204)
        RGB(255,  0,  0) aka 'Red'  corresponds to CMYK(119,  0,  0, 204)
        RGB( 0, 255,  0) aka 'Green' corresponds to CMYK( 9, 102,  0, 204)
        RGB( 0,  0, 255) aka 'Blue' corresponds to CMYK( 3,  0, 65, 204)
    End of enumeration for adapter '\\.\DISPLAY1'
    Enumerating for adapter '\\.\DISPLAYV1'
    End of enumeration for adapter '\\.\DISPLAYV1'
    Enumerating for adapter '\\.\DISPLAYV2'
    End of enumeration for adapter '\\.\DISPLAYV2'
END DISPLAY ADAPTERS

PRINTERS
    Enumerating for printer 'HP Color LaserJet 4600 PCL6'
    Testing profile 'C:\WINDOWS\system32\spool\DRIVERS\COLOR\sRGB Color Space Profile.icm'
        RGB(255, 255, 255) aka 'White' corresponds to CMYK(240, 240, 240, 204)
        RGB(255,  0,  0) aka 'Red'  corresponds to CMYK(242,  0,  0, 204)
        RGB( 0, 255,  0) aka 'Green' corresponds to CMYK( 0, 242,  0, 204)
        RGB( 0,  0, 255) aka 'Blue' corresponds to CMYK( 0,  0, 240, 204)
    End of enumeration for printer 'HP Color LaserJet 4600 PCL6'
    Enumerating for printer 'Fax'
    End of enumeration for printer 'Fax'
END PRINTERS

 

Обратите внимание, что конвертация цветов в контексте монитора и принтера дала разные результаты. Обратите так же внимание, что принтер Fax, будучи чёрно-белым, никакого профиля не имеет.

Итак, отображение цвета с помощью устройств вывода - это нетривиальная и не реализуемая точно задача. Для успешной работы с цветами надо знать, что разные устройства вывода воссоздают цвета на основе разных принципов, разных цветовых схем. Преобразование цвета из одной цветовой схемы, хотя и можно попытаться сделать своими силами, но лучше использовать для этих целей Windows API, так как в этом случае с большой вероятностью будут учтены особенности устройства, для которого осуществляется трансформация. Вы ведь теперь понимаете, что преобразования вне контекста устройства малоосмысленны?


Когда это надо?

Когда нам это может понадобиться - преобразовывать цвета? Естественно преобразования по всем правилам, через ICM API, не лучшим образом сказываются на производительности. Пользоваться такими преобразованиями надо по мере необходимости. Ниже приведён список случаев, когда настоятельно рекомендуется пользоваться ICM API.

  • В программах редактирования (графических и возможно текстовых редакторах) надо учитывать особенности монитора. Делать это следует корректно, не забывая о системах с несколькими мониторами.
  • При печати или просмотре перед печатью. Можно рисовать не то, что есть, а то, как это будет выглядеть на принтере. Здесь имеет место двойное преобразование, учитывать надо особенности двух устройств: принтера, на котором будет осуществлена печать, и монитора, на котором мы просматриваем ожидаемый результат. Либо, и это, наверное, лучше, имеет смысл передавать на печать соответствующим образом искажённую "под принтер". Второй вариант привлекателен так же тем, что вы будете иметь всего одну систему для рисования, и она будет рисовать одинаково хорошо (или одинаково плохо) работать и на мониторе и на принтере.
  • При конвертации графической информации из одного формата в другой. Часто вместе с исходными данными содержится дополнительная информация, полезная для преобразования. Например, самый, казалось бы, простой формат BMP может указывать координаты красного, зеленого и синего в XYZ пространстве.

В любом случае желательно дать пользователю возможность отключать использования ICM, так как:

  • отключение использования ICM может поднять производительность графики, а цвета могут быть как раз не очень важны;
  • пользователь может просто захотеть увидеть разницу.


Источники информации

Большая Советская Энциклопедия, http://www.realcolor.ru, http://www.color.org


Спасибы

Спасибо Илье Рыженкову за ценные замечания в ходе написания статьи.

Эта статья на RSDN


Ведущий рассылки: Алекс Jenter jenter@rsdn.ru
Публикуемые в рассылке материалы принадлежат сайту RSDN.


http://subscribe.ru/
http://subscribe.ru/feedback/
Подписан адрес:
Код этой рассылки: comp.prog.visualc
Отписаться

В избранное