高度な検索
Developer Connection
Member Login ログイン | ご入会 ADC連絡先

Technical Q&A QA1396
Creating color spaces that ensure color matching.

Q:カラーをマッチングできるように、色空間を作成するにはどうすればいいのですか。

A:カラーを効果的に処理し、色空間とカラーを使用するための Quartz 2D 機能を理解するには、「Color Management Overview」で説明している用語に慣れてください。当該文書では、色の知覚、カラー値、デバイス独立色空間およびデバイス色空間、カラーマッチング問題、レンダリングインテント、色管理モジュール、ColorSync について説明しています。

デバイス(ディスプレイ、プリンタ、スキャナ、カメラ)は、カラーを同じように扱うわけではありません。デバイスは、それぞれに忠実に再現できるカラーの範囲があります。あるデバイスで生成できたカラーが、別のデバイスでは生成できない場合もあります。このような問題を回避する最善の方法は、「キャリブレーションレコード」を持つ色空間(ICC プロファイルを持つ ICCBased 色空間など)を使用することです。このような場合、システムはその色空間のカラーを任意の目標(ディスプレイなど)に最善の方法で変換することができます。目標のプロファイルがすでに存在するのでないかぎり、最良の解決策は汎用の色空間を使用することです。汎用の色空間(Generic RGB や Generic CYMK など)は、目標デバイスにコピーする際に必ずキャリブレーションされる色空間です。

デバイス色空間はデバイスに依存し、すべてのカラーが目標デバイス用にすでにキャリブレーションされているものとみなします。次の API はデバイス依存の色空間を作成するため、避けてください。CGColorSpaceCreateDeviceRGB()CGColorSpaceCreateDeviceCYMK()、および CGColorSpaceCreateDeviceGray()

Mac OS X では、以下の ICC プロファイルファイルを次のディレクトリに用意しています:'/System/Library/ColorSync/Profiles/'

  • Generic CMYK Profile.icc

  • Generic Gray Profile.icc

  • Generic Lab Profile.icc

  • Generic RGB Profile.icc

  • Generic XYZ Profile.icc

  • sRGB Profile.icc

ICC カラープロファイルから ICC 色空間を作成する簡単な API はありませんが、リスト 1 に色空間を作成する方法の例を示します。

リスト 1:ICC プロファイルからの色空間の作成、および Generic RGB 色空間と sRGB 色空間を作成する例

CGColorSpaceRef CreateICCColorSpaceFromPathToProfile (const char * iccProfilePath) {

  CMProfileRef    iccProfile = (CMProfileRef) 0;
  CGColorSpaceRef iccColorSpace = NULL;
  CMProfileLocation loc;

  // プロファイルの場所がプロファイルへの POSIX パスとなることを指定する。
  loc.locType = cmPathBasedProfile;
  
  // パスがバッファより大きくないことを確認する
  if(strlen(iccProfilePath) > sizeof(loc.u.pathLoc.path))
    return NULL;

  // プロファイルのパスを CMProfileLocation 構造体にコピーする
  strcpy (loc.u.pathLoc.path, iccProfilePath);

  // プロファイルを開く
  if (CMOpenProfile(&iccProfile, &loc) != noErr)
  {
    iccProfile = (CMProfileRef) 0;
                return NULL;
  }
  
  // 開いているプロファイルで色空間を作成する。
  iccColorSpace = CGColorSpaceCreateWithPlatformColorSpace( iccProfile );

  // 必要なものを取得できたので、プロファイルを閉じる。
  CMCloseProfile(iccProfile);

  return iccColorSpace;
}

CGColorSpaceRef CreateColorSpaceFromSystemICCProfileName(CFStringRef profileName) {
  FSRef pathToProfilesFolder;
    FSRef pathToProfile;

  // Systems Color Sync Profiles フォルダを探し出す
  if(FSFindFolder(kOnSystemDisk, kColorSyncProfilesFolderType,
      kDontCreateFolder, &pathToProfilesFolder) == noErr) {

    // プロファイル名の UniChar 文字列を作成する
    UniChar uniBuffer[sizeof(CMPathLocation)];
    CFStringGetCharacters (profileName,CFRangeMake(0,CFStringGetLength(profileName)),uniBuffer);

    // Systems Color Sync Profile フォルダにプロファイルへの FSRef を作成する
    if(FSMakeFSRefUnicode (&pathToProfilesFolder,CFStringGetLength(profileName),uniBuffer,
      kUnicodeUTF8Format,&pathToProfile) == noErr) {
        char path[sizeof(CMPathLocation)];
      
      // プロファイルへの posix パスを FSRef からパスバッファに書き込む
      if(FSRefMakePath (&pathToProfile,path,sizeof(CMPathLocation)) == noErr)
        return CreateICCColorSpaceFromPathToProfile(path);
    }
  }
  
  return NULL;
}

CGColorSpaceRef CreateICCGenericRGBColorSpace() {
  return CreateColorSpaceFromSystemICCProfileName(CFSTR("Generic RGB Profile.icc"));
}

CGColorSpaceRef CreateICCsRGBColorSpace() {
     return CreateColorSpaceFromSystemICCProfileName(CFSTR("sRGB Profile.icc"));
}

オフスクリーンキャッシュは一般に、パフォーマンスを強化するのに使用しますが、色空間を使用して、ディスプレイデバイスにマッチしないオフスクリーンキャッシュを作成すると、データをディスプレイデバイスにコピーするたびに、カラーキャリブレーション処理を経由する必要があります。どのディスプレイデバイスもカラーを異なる方法で同じカラー値にマップするので、最善の方法はディスプレイデバイスプロファイルをシステムに要求することです。ディスプレイデバイスプロファイルを取得したら、それを使用してディスプレイの色空間を作成できます。その後、その色空間を使用して、オフスクリーンキャッシュとして使用する CGBitmapContext を作成することができます。リスト 2 に、現在のディスプレイプロファイルに基づいて色空間を作成する方法を示します。

リスト 2:メインディスプレイを表す色空間の作成

CGColorSpaceRef CreateSystemColorSpace () {
  CMProfileRef sysprof = NULL;
  CGColorSpaceRef dispColorSpace = NULL;

  // メインディスプレイのシステムプロファイルを取得する
  if (CMGetSystemProfile(&sysprof) == noErr)
  {
    // システムプロファイルで色空間を作成する
    dispColorSpace = CGColorSpaceCreateWithPlatformColorSpace(sysprof);

    // プロファイルを閉じる
    CMCloseProfile(sysprof);
  }
  
  return dispColorSpace;
}

現在のディスプレイプロファイルに基づく「ディスプレイ色空間」を使用すると、画面にコピーするときにはカラーをマッチングしないが、オフスクリーンキャッシュに描画するときにはカラーをマッチングするようシステムに指示することとなります。この「ディスプレイ色空間」は現在のディスプレイに基づいているため、キャッシュしたデータを異なるディスプレイを装備した別のシステムで再現する場合は、各デバイスが同じカラー値に対して異なる反応を示すので、カラーの見かけが異なります。

ドキュメントの改訂履歴

日付 メモ
2005-01-12 初版

掲載日: 2005-01-12