ビットマップイメージとイメージマスク
ビットマップイメージとイメージマスクは、Quartz の任意の描画プリミティブと似ています。Quartz のイメージとイメージマスクの両方とも、CGImageRef データ型で表されます。この章で後述するように、イメージの作成に使用できるさまざまな関数があります。それらのうちのいくつかは、ビットマップデータを供給するためにデータプロバイダまたはイメージソースが必要です。他の関数は、イメージをコピーするか、イメージに操作をして、既存のイメージからイメージを作成します。Quartz でビットマップイメージをどのように作成しても、イメージをグラフィックコンテキストの任意の趣に描画できます。ビットマップイメージは、特定の解像度のビットの配列です。解像度に依存しないグラフィックスコンテキスト(PDF グラフィックスコンテキストなど) にビットマップイメージを描画する場合、ビットマップイメージは作成した解像度によって制限されます。
CGImageMaskCreate 関数を呼び出すことで、Quartz イメージマスクを作成する方法があります。イメージマスクの作成 でイメージマスクを作成する方法がわかります。イメージマスクを適用するのは、描画をマスクする唯一の方法ではありません。色でイメージをマスク、イメージマスクでイメージをマスクする、コンテキストをクリッピングしてイメージをマスクする 節では、Quartz で利用可能なすべてのマスクメソッドについて説明します。
ビットマップイメージとイメージマスクについて
ビットマップイメージ(またはサンプルイメージ) は、ピクセル(またはサンプル) の配列です。各ピクセルはイメージ内の一点を表します。JPEG、TIFF、および PNG グラフィックファイルは、ビットマップイメージの例です。アプリケーションアイコンはビットマップイメージです。ビットマップイメージは長方形に制限されています。しかし、アルファ成分を使用すると、図 11-1 に示したように、様々な形を取るように見え、回転したり、クリップすることができます。
図 11-1 ビットマップイメージ
ビットマップ内の各サンプルには、指定された色空間内の 1 つ以上の色成分と、透過性を示すアルファ値を指定する 1 つの追加成分が含まれます。各成分は 1 から 32 ビットまでの数です。Mac OS X では、Quartz はまた浮動小数点成分もサポートしています。Mac OS X および iOS でサポートされている形式については、ビットマップグラフィックスコンテキストでサポートされるピクセル形式 を参照してください。ColorSync は、ビットマップイメージの色空間のサポートを提供します。
Quartz はまた、イメージマスクもサポートしています。イメージマスクは、ペイントする領域を指定するビットマップですが、色は指定しません。実際には、イメージマスクはステンシルとして機能し、ページ上の色をどこに配置するかを指定します。Quartz は現在の塗りつぶし色を使用してイメージマスクをペイントします。イメージマスクは、1〜8 ビットの深さを有します。
ビットマップイメージ情報
Quartz は広範囲のイメージ形式をサポートし、いくつかの一般的な形式の知識を内蔵しています。iOS では、形式には JPEG、GIF、PNG、TIF、ICO、GMP、XBM、および CUR が含まれます。他のビットマップイメージ形式または独自の形式では、イメージが正しく解釈されるように、イメージ形式に関する詳細を Quartz に指定する必要があります。CGImageCreate 関数に供給するイメージデータは、基本的に、走査線単位ではなく、ピクセル単位でインターリーブしなければなりません。Quartz は二次元データをサポートしていません。
この節では、ビットマップイメージに関連する情報を説明します。Quartz イメージ(CGImageRef データ型を使用する) を作成して作業すると、Quartz イメージ作成関数の中にはこの情報をすべて指定する必要があり、他の関数はこの情報のサブセットを必要とすることがわかります。提供するものは、ビットマップデータに使用されるコード化と、ビットマップがイメージまたはイメージマスクを表すかどうかによります。
Quartz は、ビットマップイメージ(CGImageRef) を作成するときに以下の情報を使用します。
- ビットマップデータソース。これは、Quartz のデータプロバイダまたは Quartz イメージソースです。Quartz 2D でのデータ管理 では、両方を説明し、ビットマップデータのソースを提供する関数について説明します。
- オプションの複合配列(配列の復号)。
- 補間設定。これは、イメージのサイズ変更時に Quartz が補間アルゴリズムを適用するかどうかを指定するブール値です。
- グラフィックスコンテキストの宛先の色空間内に位置する色のマッピング方法を指定するレンダリングインテント。この情報はイメージマスクには必要ありません。詳細については、レンダリングインテントの設定 を参照してください。
- イメージの寸法。
- ピクセルの形式。これは成分ごとのビット数、ピクセルあたりのビット数、および 1 行あたりのバイト数(ピクセルの形式) を含みます。
- イメージの色空間とビットマップレイアウト(色空間とビットマップレイアウト) の情報で、アルファ値の位置と、ビットマップが浮動小数点値を使用するかどうかを記述します。イメージマスクはこの情報を必要としません。
配列の復号
配列の復号は、イメージの色値を他の色値にマッピングし、これは、イメージの飽和度の低下や色の反転などの作業に便利です。配列には、各色成分のペアの数が含まれています。Quartz はイメージをレンダリングするとき、線形変換を適用して元の成分値を宛先の色空間に適した指定された範囲内の相対数にマッピングします。たとえば、RGB 色空間内のイメージの配列の復号には、赤、緑、青の各色成分ごとに 1 組の 6 つのエントリがあります。
ピクセルの形式
ピクセルの形式は、以下の情報で構成されます。
- 成分当たりのビット。これは、ピクセル内の各個々の色成分のビット数です。イメージマスクの場合、この値はソースピクセルの重要なマスキングビットです。たとえば、ソースイメージが 8 ビットマスクの場合、成分ごとに 8 ビットを指定します。
- ピクセルごとのビット。これは、ソースピクセル内のビットの総数です。この値は、少なくとも成分あたりのビット数にピクセルあたりの成分数を掛けた値でなければなりません。
- 行あたりのバイト。イメージ内の水平の行あたりのバイト数。
色空間とビットマップレイアウト
Quartz が各ピクセルのビットを正しく解釈するようにするには、以下の事を指定しなければなりません。
- ビットマップがアルファチャンネルを含んでいるかどうか。Quartz は、RGB、CMYK、および灰色の色空間をサポートしています。アルファ情報はすべてのビットマップイメージ形式で利用できるわけではありませんが、アルファ値または透明度もサポートしています。使用可能な場合、アルファ成分は、ピクセルの最上位ビットまたは最下位ビットのいずれかに位置できます。
- アルファ成分を持つビットマップの場合、アルファ値ですでに色成分が乗算されているかどうか。事前に乗算されたアルファ値 は、その成分がすでにアルファ値で乗算されているソースカラーを表します。事前の乗算は、色成分ごとに余分な乗算の演算を排除して、イメージのレンダリングを高速化します。たとえば、RGB 色空間では、事前に乗算されたアルファ値を使用してイメージをレンダリングすると、イメージ内の各ピクセルの 3 つの乗算演算(赤を乗算したアルファ、緑を乗算したアルファ、青を乗算したアルファ) が排除されます。
- サンプルのデータ形式 - 整数値または浮動小数点値。
CGImageCreate 関数を使用してイメージを作成するときは、CGImageBitmapInfo 型の bitmapInfo パラメータを指定して、ビットマップレイアウト情報を指定します。以下の定数は、アルファ成分の位置と、色成分が事前に乗算されているかどうかを指定します。
- kCGImageAlphaLast - アルファ成分は各ピクセルの最下位ビットに格納されます(RGBA など)。
- kCGImageAlphaFirst - アルファ成分は各ピクセルの最上位ビットに格納されます(ARGB など)。
- kCGImageAlphaPremultipliedLast - アルファ成分は各ピクセルの最下位ビットに格納され、色成分は既にこのアルファ値で乗算されています。
- kCGImageAlphaPremultipliedFirst - アルファ成分は各ピクセルの最上位ビットに格納され、色成分は既にこのアルファ値で乗算されています。
- kCGImageAlphaNoneSkipLast - アルファ成分はありません。ピクセルの合計サイズが色空間内の色成分の数に必要な空間よりも大きい場合、最下位ビットは無視されます。
- kCGImageAlphaNoneSkipFirst - アルファ成分はありません。ピクセルの合計サイズが色空間内の色成分の数に必要な空間よりも大きい場合、最上位ビットは無視されます。
- kCGImageAlphaNone - kCGImageAlphaNoneSkipLast に相当します。
定数 kCGBitmapFloatComponents を使用して、浮動小数点値を使用するビットマップ形式を指定します。浮動小数点形式の場合、この定数と前のリストの適切な定数を論理和(OR) します。たとえば、各ピクセルの最下位ビットにあるアルファ値を使用して、事前に乗算されたアルファ値を使用する、ピクセルあたり 128 ビットの浮動小数点形式の場合は、以下の情報を Quartz に指定します。
kCGImageAlphaPremultipliedLast | kCGBitmapFloatComponents
図 11-2 は、16 ビットまたは 32 ビット整数形式を使用する CMYK および RGB 色空間でピクセルがどのように表されるかを視覚的に示しています。32 ビットの整数ピクセル形式は、成分ごとに 8 ビットを使用します。16 ビットの整数形式は、成分ごとに 5 ビットを使用します。Quartz 2D はまた、成分あたり 32 ビットを使用する 128 ビット浮動小数点ピクセル形式もサポートしています。128 ビットの形式は図には示しません。
図 11-2 Quartz 2D の CMYK および RGB 色空間の 32 ビットおよび 16 ビットピクセル形式
イメージの作成
表 11-1 に、Quartz が CGImage オブジェクトを作成するために提供する関数を示します。イメージ作成関数の選択は、イメージデータのソースに依存します。最も柔軟な関数は CGImageCreate です。それは全ての種類のビットマップデータからイメージを作成します。ただし、すべてのビットマップ情報を指定しなければならないため、使用するのが最も複雑な関数です。この関数を使用するには、ビットマップイメージ情報 で説明した主題に精通している必要があります。
PNG や JPEG などの標準イメージ形式を使用するイメージファイルから CGImage オブジェクトを作成する場合は、CGImageSourceCreateWithURL 関数を呼び出してイメージソースを作成し、CGImageSourceCreateImageAtIndex 関数を呼び出してイメージソース内の特定のインデックスにあるイメージデータからイメージを作成します。元のイメージファイルにイメージが 1 つだけ含まれている場合は、インデックスとして 0 を指定します。イメージファイル形式が複数のイメージを含むファイルをサポートしている場合、インデックス値が 0 から始まることを覚えておいて、適切なイメージにインデックスを提供する必要があります。
ビットマップグラフィックスコンテキストにコンテンツを描画し、その描画を CGImage オブジェクトにキャプチャしたい場合は、関数 CGBitmapContextCreateImage を呼び出します。
いくつかの関数は、コピーを作成したり、サムネイルを作成したり、大きなイメージの一部からイメージを作成したりする、既存のイメージを操作するユーティリティです。どのように CGImage オブジェクトを作成するかにかかわらず、CGContextDrawImage 関数を使用してイメージをグラフィックスコンテキストに描画します。CGImage オブジェクトは不変であることに注意してください。CGImage オブジェクトが不要になったら、CGImageRelease 関数を呼び出して解放して下さい。
表 11-1 イメージを作成する関数
関数 | 説明 |
---|---|
CGImageCreate | イメージ作成用の柔軟な関数。ビットマップイメージ情報 で説明したすべてのビットマップ情報を指定して下さい。 |
CGImageSourceCreateImageAtIndex | イメージソースからイメージを作成します。イメージソースには、複数のイメージを含められます。イメージソースの作成については、Quartz 2D でのデータ管理 を参照してください。 |
CGImageSourceCreateThumbnailAtIndex | イメージソースに関連付けられているイメージのサムネイルイメージを作成します。イメージソースの作成については、Quartz 2D でのデータ管理 を参照してください。 |
CGBitmapContextCreateImage | ビットマップグラフィックスコンテキストからビットをコピーしてイメージを作成します。 |
CGImageCreateWithImageInRect | イメージの下位長方形内に含まれるデータからイメージを作成します。 |
CGImageCreateCopy | イメージのコピーを作成するユーティリティ関数。 |
CGImageCreateCopyWithColorSpace | イメージのコピーを作成し、その色空間を置き換えるユーティリティ関数。 |
以降の節では、作成方法について説明します。
- 既存のイメージからの下位イメージ
- ビットマップグラフィックスコンテキストからのイメージ
追加情報については、以下のソースを参照してください:
- Quartz 2D でのデータ管理 はイメージの読み書きの方法を説明しています。
- 表 11-1 に示した関数とそのパラメータの詳細については、CGImage リファレンス、CGImageSource リファレンス、および CGBitmapContext リファレンス を参照してください。
大きなイメージの一部からイメージを作成
CGImageCreateWithImageInRect 関数を使うと、既存の Quartz イメージから下位イメージを作成できます。図 11-3 は、文字"A" の位置を指定する長方形を指定して、文字"A" を含むイメージを大きなイメージから抽出する方法を示しています。
図 11-3 大きなイメージから作成された下位イメージ
CGImageCreateWithImageInRect 関数によって返されたイメージは元のイメージへの参照を保持し、つまり、この関数を呼び出した後に元のイメージを解放できます。
図 11-4 に、別のイメージを作成するためにイメージの一部を抽出する別の例を示します。この場合、雄鶏の頭部は大きな画像から抽出され、下位イメージよりも大きな長方形に描画され、効果的に画像が拡大されます。
リスト 11-1 に、下位イメージを作成して描画するコードを示します。CGContextDrawImage 関数が雄鶏の頭部を描画する長方形は、抽出された下位イメージの寸法の 2 倍の寸法を持ちます。リストはコードの断片です。適切な変数を宣言し、雄鶏のイメージを作成し、雄鶏のイメージと雄鶏の頭部の下位イメージを処分する必要があります。コードは断片なので、イメージが描画されるグラフィックスコンテキストを作成する方法は示しません。好きなグラフィックスコンテキストのフレーバーを使うことができます。グラフィックスコンテキストを作成する方法の例については、グラフィックスコンテキスト を参照してください。
図 11-4 イメージと、それから取り込まれ、拡大して描画された下位イメージ
リスト 11-1下位イメージを作成し、それを拡大して描画するコード
myImageArea = CGRectMake (rooster_head_x_origin, rooster_head_y_origin, myWidth, myHeight); mySubimage = CGImageCreateWithImageInRect (myRoosterImage, myImageArea); myRect = CGRectMake(0, 0, myWidth*2, myHeight*2); CGContextDrawImage(context, myRect, mySubimage);
ビットマップグラフィックスコンテキストからイメージを作成
既存のビットマップグラフィックスコンテキストからイメージを作成するには、以下のように CGBitmapContextCreateImage 関数を呼び出します。
CGImageRef myImage; myImage = CGBitmapContextCreateImage (myBitmapContext);
関数が返す CGImage オブジェクトは、コピー操作によって作成されます。したがって、その後のビットマップグラフィックスコンテキストの変更は、返された CGImage オブジェクトの内容には影響しません。場合によっては、コピー操作は実際に書いた時コピーする意味に従うので、ビットマップグラフィックスコンテキストの基礎となるデータが変更された場合にのみ、ビットの実際の物理コピーが発生します。データの実際の物理コピーを避けるために、ビットマップグラフィックスコンテキストへの追加描画を実行する前に、結果のイメージを使用して解放することができます。
ビットマップグラフィックスコンテキストの作成方法の例については、ビットマップグラフィックスコンテキストの作成 を参照してください。
イメージマスクの作成
Quartz のビットマップイメージマスクは、芸術家がシルクスクリーンを使用するのと同じ方法で使用されます。ビットマップイメージマスクは、どの色を使用するかではなく、どのように色を転送するかを決定します。イメージマスクの各サンプル値は、現在の塗りつぶし色が特定の位置でマスクされる量を指定します。サンプル値は、マスクの不透明度を指定します。値が大きいほど不透明度が高くなり、Quartz が色を薄く塗る場所を指定します。サンプル値を逆アルファ値と考えることができます。1 の値は透明で 0 は不透明です。
イメージマスクは、成分ごとに 1,2,4 または 8 ビットです。1 ビットマスクの場合、サンプル値 1 は現在の塗りつぶし色をブロックするマスクのセクションを指定します。サンプル値 0 は、マスクがペイントされたときのグラフィックス状態の現在の塗りつぶし色を示すマスクのセクションを指定します。1 ビットのマスクは白黒と考えることができます。サンプルは塗料を完全にブロックするか、塗料を完全に塗ります。
成分ごとに 2 ビット、4 ビット、または 8 ビットのイメージマスクはグレースケール値を表します。各成分は、次の式を使用して 0〜1 の範囲にマッピングされます。
たとえば、4 ビットマスクの値の範囲は 0〜1 で、1/15 ずつ増えます。0 または 1 の成分値は、極端な - 塗りつぶしを完全にブロックし、またはペイントを完全に許可します。0 と 1 の間の値は、式 1 - MaskSampleValue を使用した部分的なペイントを可能にします。たとえば、8 ビットマスクのサンプル値が 0.7 にスケールされると、アルファ値が(1 - 0.7)、つまり 0.3 であるようにペイントされます。
CGImageMaskCreate 関数は、指定したビットマップイメージ情報から Quartz のイメージマスクを作成します。これについては、ビットマップイメージ情報 を参照してください。イメージマスクを作成するために提供する情報は、イメージを作成するために提供するものと同じですが、リスト 11-2 に挙げた関数のプロトタイプを見ればわかるように、色空間情報、ビットマップ情報定数、またはレンダリングインテントを与えない点が異なります。
リスト 11-2   CGImageMaskCreate 関数のプロトタイプ
CGImageRef CGImageMaskCreate ( size_t width, size_t height, size_t bitsPerComponent, size_t bitsPerPixel, size_t bytesPerRow, CGDataProviderRef provider, const CGFloat decode[], bool shouldInterpolate );
イメージをマスクする
マスキング技法は、イメージのどの部分がペイントされるかを制御することによって、多くの興味深い効果を生むことができます。以下の事ができます:
- イメージマスクをイメージに適用します。イメージマスクを適用するのとは反対の効果を得るために、イメージをマスクとして使用することもできます。
- クロマ・キー・マスキングと呼ばれる技法を含む、イメージの一部をマスクする色を使用します。
- Quartz がクリップされたコンテキストにコンテンツを描画するときに、イメージ(またはあらゆる種類の描画) を効果的にマスクするイメージまたはイメージマスクに、グラフィックスコンテキストをクリップします。
イメージマスクでイメージをマスクする
CGImageCreateWithMask 関数は、イメージマスクをイメージに適用することによって作成されたイメージを返します。この関数は 2 つのパラメータをとります:
- マスクを適用したいイメージ。このイメージは、イメージマスクではなく、マスキングカラー(色でイメージをマスク を参照してください) と関連付けることはできません。
- CGImageMaskCreate 関数を呼び出して作成されたイメージマスク。イメージマスクの代わりにイメージを提供することは可能ですが、それははるかに異なる結果をもたらします。イメージでイメージをマスク を参照してください。
イメージマスクのソースサンプルは、逆アルファ値として機能します。イメージマスクサンプル値(S):
- 対応するイメージサンプルをペイントする 1 ブロックと同じです。
- 対応するイメージサンプルを完全な範囲でペイントできる 0 に等しい。
- 0 以上 1 未満の場合は、(1 - S) のアルファ値を持つ、対応するイメージサンプルをペイントできます。
図 11-5 は Quartz のイメージ作成関数の 1 つで作成されたイメージを示し、図 11-6 は CGImageMaskCreate 関数で作成されたイメージマスクを示します。図 11-7 に、 CGImageCreateWithMask 関数を呼び出してイメージマスクをイメージに適用したイメージを示します。
図 11-5 オリジナルのイメージ
図 11-6 イメージマスク
マスクの黒い領域に対応するオリジナルのイメージ内の領域は、結果のイメージに表示されます(図 11-7)。マスクの白い領域に対応する領域はペイントされません。マスクのグレーの領域に対応する範囲は、イメージマスクサンプル値を 1 から引いた中間のアルファ値を使用してペイントされます。
図 11-7 オリジナルのイメージにイメージマスクを適用した結果のイメージ
イメージでイメージをマスク
CGImageCreateWithMask 関数を使用して、イメージマスクではなく、別のイメージでイメージをマスクできます。イメージマスクを使用してイメージをマスクするときとは逆の効果を得るには、これを行います。 CGImageMaskCreate 関数を使用して作成されたイメージマスクを渡す代わりに、Quartz イメージ作成関数の 1 つから作成されたイメージを提供して下さい。
マスクとして使用されるイメージ(Quartz イメージマスクではない) のソースサンプルは、アルファ値として動作します。イメージサンプル値(S):
- 1 に等しいと、対応するイメージサンプルを全範囲でペイントできます。
- 0 に等しいと、対応するイメージサンプルをペイントするのを防ぎます。
- 0 より大きく 1 未満の場合は、アルファ値が S の対応するイメージサンプルをペイントできます。
図 11-8 に、CGImageCreateWithMask 関数を呼び出して、図 11-6 に示したイメージを 図 11-5 のイメージに適用した結果のイメージを示します。この場合、図 11-6 に示すイメージは、CGImageCreate などの Quartz イメージ作成関数のいずれか 1 つを使用して作成されたものとします。図 11-8 と 図 11-7 を比較してわかるのは、同じサンプル値をイメージマスクサンプルではなくイメージサンプルとして使用すると、逆の効果が得られます。
図 11-8 オリジナルのイメージをイメージでマスクして得られたイメージ
色でイメージをマスク
CGImageCreateWithMaskingColors 関数は、関数に供給されたイメージ内の 1 つの色または色の範囲をマスクしてイメージを作成します。この関数を使用すると、図 11-9 に示すようなクロマキーマスキングを実行したり、図 11-11、図 11-12、および 図 11-13 に示すような色の範囲のマスクができます。
CGImageCreateWithMaskingColors 関数は 2 つのパラメータをとります:
- イメージマスクではなく、他のイメージにイメージマスクや色マスキングを適用した結果ではないイメージ。
- イメージ内でマスクする関数用の色または色の範囲を指定する色成分の配列。
図 11-9 クロマキーマスキング
色成分配列の要素の数は、イメージの色空間内の色成分の数の 2 倍に等しくなければなりません。色空間の各色成分に対して、マスクする色の範囲を指定する最小値と最大値を指定します。1 つの色のみをマスクするには、最小値を最大値に設定します。色成分配列の値は、以下の順序で供給されます。
{min[1], max[1], ... min[N], max[N]} ここで N は成分の数です。
イメージが整数ピクセル成分を使用する場合、色成分配列の各値は [0 .. 2^bitsPerComponent - 1] の範囲内になければなりません。イメージが浮動小数点ピクセル成分を使用する場合、各値は有効な色成分である任意の浮動小数点数になれます。
イメージの色の値が範囲内にある場合、イメージサンプルはペイントされません。
{c[1], ... c[N]}
ここで min[i] <= c[i] <= max[i] for 1 <= i <= N です。
現在の塗りつぶし色やその他の描画など、ペイントされていないサンプルの下のものがすべて表示されます。
図 11-10 に示した 2 匹のトラのイメージは、成分あたり 8 ビットの RGB 色空間を使用します。このイメージの色の範囲をマスクするには、最小値と最大値の色成分値を 0〜255 の範囲で指定して下さい。
図 11-10 オリジナルのイメージ
リスト 11-3 は、色成分配列を設定し、その配列を CGImageCreateWithMaskingColors 関数に渡して、図 11-11 に示す結果を得るコードの断片を示しています。
リスト 11-3 イメージの明るい茶色から中間色の茶色をマスクする
CGImageRef myColorMaskedImage; const CGFloat myMaskingColors[6] = {124, 255, 68, 222, 0, 165}; myColorMaskedImage = CGImageCreateWithMaskingColors (image, myMaskingColors); CGContextDrawImage (context, myContextRect, myColorMaskedImage);
図 11-11 明るい茶色から中間色の茶色の色をマスクしたイメージ
リスト 11-4 に、図 11-10 に示したイメージを操作して、図 11-12 に示す結果を得る別のコードの断片を示します。この例では、より暗い範囲の色をマスクします。
リスト11-4 茶色から黒色の色合いをマスクする
CGImageRef myMaskedImage; const CGFloat myMaskingColors[6] = { 0, 124, 0, 68, 0, 0 }; myColorMaskedImage = CGImageCreateWithMaskingColors (image, myMaskingColors); CGContextDrawImage (context, myContextRect, myColorMaskedImage);
図 11-12 ダークブラウンから黒までマスクした後のイメージ
図 11-13 に示したような効果を得るには、イメージ内の色をマスクしたり、塗りつぶし色を設定したりして、マスクされた領域が塗りつぶしの色に置き換えられます。リスト 11-5 に、図 11-13 に示したイメージを生成するコードの断片を示します。
リスト 11-5 ある範囲の色をマスクし塗りつぶし色を設定して
CGImageRef myMaskedImage; const CGFloat myMaskingColors[6] = { 0, 124, 0, 68, 0, 0 }; myColorMaskedImage = CGImageCreateWithMaskingColors (image, myMaskingColors); CGContextSetRGBFillColor (myContext, 0.6373,0.6373, 0, 1); CGContextFillRect(context, rect); CGContextDrawImage(context, rect, myColorMaskedImage);
図 11-13 ある範囲の色をマスクし塗りつぶし色を設定した後に描かれるイメージ
コンテキストをクリッピングしてイメージをマスクする
CGContextClipToMask 関数は、マスクを長方形にマッピングし、それをグラフィックスコンテキストの現在のクリッピング領域と交差させます。以下のパラメータを指定します。
- クリップしたいグラフィックスコンテキスト。
- マスクを適用すべき長方形。
- CGImageMaskCreate 関数を呼び出して作成されたイメージマスク。イメージマスクの代わりに画像を供給して、イメージマスクを供給することによって得られる効果とは反対の効果を得られます。イメージは、Quartz イメージ作成関数で作成しなければなりませんが、マスクを適用したり、別のイメージに色をマスクした結果であってはなりません。
生成されるクリップされた領域は、CGContextClipToMask 関数にイメージマスクまたはイメージを指定するかどうかによって異なります。イメージマスクを指定すると、グラフィックスコンテキストがクリップされることを除いて、イメージマスクでイメージをマスクする で説明したのと同様の結果が得られます。イメージを指定すると、グラフィックスコンテキストは、イメージでイメージをマスク と同様にクリップされます。
図 11-14 を見てください。これは CGImageMaskCreate 関数を呼び出して作成されたイメージマスクであり、マスクが CGContextClipToMask 関数へのパラメータとして提供されているとします。結果として得られるコンテキストは、黒い領域にペイントすることができ、白い領域にはペイントすることができず、1-S のアルファ値でグレー領域にペイントできます。ここで、S はイメージマスクのサンプル値です。CGContextDrawImage 関数を使用してクリップされたコンテキストにイメージを描画すると、図 11-15 のような結果が得られます。
図 11-14 マスクするイメージ
図 11-15 イメージマスクを使用してコンテンツをクリップした後にコンテキストに描かれたイメージ
マスクするイメージをイメージとして扱うと、図 11-16 に示すように、反対の結果になります。
図 11-16 イメージでコンテンツをクリップした後にコンテキストに描画されたイメージ
イメージにブレンドモードを使用
Quartz 2D ブレンドモード(ブレンドモードの設定 を参照) を使用して、2 つのイメージを合成したり、すでにグラフィックコンテキストに描画されているコンテンツとイメージを合成したりできます。この節では、背景の描画の上にイメージを合成する方法について説明します。
背景上にイメージを合成する一般的な手順は以下のとおりです。
- 背景を描画します。
- ブレンドモード定数の 1 つを使用して CGContextSetBlendMode 関数を呼び出し、ブレンドモードを設定します。(ブレンドモードは、PDF Reference、第4版、バージョン 1.5、Adobe Systems、Inc. で定義されたものに基づきます)
- CGContextDrawImage 関数を呼び出して、合成したいイメージを背景に描画します。
このコードの断片は、"より暗くする" ブレンドモードを使用して背景に 1 つのイメージを合成します。
CGContextSetBlendMode (myContext, kCGBlendModeDarken); CGContextDrawImage (myContext, myRect, myImage2);
この節の残りの部分では、Quartz で使用可能な各ブレンドモードを使用して、図 11-17 の右側に示したイメージを、図の左側に示した、ペイントされた長方形で構成される背景の上に描画します。すべての場合、長方形は最初にグラフィックスコンテキストに描画されます。次に、適切なブレンドモード定数を渡して、CGContextSetBlendMode 関数を呼び出して、ブレンドモードを設定します。最後に、ジャンパーのイメージがグラフィックスコンテキストに描画されます。
図 11-17 背景描画(左) と前景のイメージ(右)
標準ブレンドモード
標準ブレンドモードは、ソースイメージサンプルを背景のイメージサンプル上にペイントします。標準ブレンドモードは、Quartz のデフォルトのブレンドモードです。現在別のブレンドモードを使用していて、標準ブレンドモードに切り替える場合のみ、明示的に標準ブレンドモードを設定する必要があります。CGContextSetBlendMode 関数に定数 kCGBlendModeNormal を渡すか、CGContextRestoreGState 関数を使用してグラフィックス状態を復元する(標準ブレンドモードを使用していた前のグラフィックス状態を想定して)、標準ブレンドモードを設定できます。
図 11-18 に、標準ブレンドモードを使用して、図 11-17 に示したイメージを、同じ図に示した長方形にペイントした結果を示します。この例では、アルファ値 1.0 を使用してイメージが描画されるため、背景はイメージによって完全に隠されます。
図 11-18 標準ブレンドモードを使用して背景上にイメージを描画
乗算ブレンドモード
乗算ブレンドモードは、ソースイメージサンプルを背景イメージサンプルと乗算します。結果のイメージの色は、少なくとも 2 つの寄与するサンプル色のいずれかと同じくらい暗いです。
定数 kCGBlendModeMultiply を関数 CGContextSetBlendMode に渡すことにより、乗算ブレンドモードを指定します。 図 11-19 は、図 11-17 に示したイメージを乗算ブレンドモードを使用して同じ図に示す長方形の上にペイントした結果を示しています。
図 11-19 乗算ブレンドモードを使用して背景にイメージを描画
スクリーンブレンドモード
スクリーンブレンドモードは、ソースイメージサンプルの逆数と背景イメージサンプルの逆数とを乗算して、少なくとも 2 つの寄与するサンプル色のいずれかと同じ明るさの色を得ます。
CGContextSetBlendMode 関数に定数 kCGBlendModeScreen を渡して、スクリーンブレンドモードを指定します。図 11-20 は、図 11-17 に示したイメージをスクリーンブレンドモードを使用して同じ図に示した長方形の上にペイントした結果を示しています。
図 11-20 スクリーンブレンドモードを使用して背景にイメージを描画
上塗りブレンドモード
上塗りブレンドモードは、背景サンプルの色に応じて、ソースイメージサンプルを背景イメージサンプルと乗算するか、スクリーンします。結果は、背景のハイライトとシャドウを保存しながら、既存のイメージサンプルを上塗りすることです。背景色は、背景の明るさまたは暗さを反映するためにソースイメージと混合されます。
上塗りブレンドモードは、CGContextSetBlendMode 関数に定数 kCGBlendModeOverlay を渡して指定します。図 11-21 は、上塗りブレンドモードを使用して、図 11-17 に示したイメージを、同じ図に示した長方形の上にペイントした結果を示しています。
図 11-21 上塗りブレンドモードを使用して背景にイメージを描画
より暗くするブレンドモード
より暗くするブレンドモードは、ソースイメージまたは背景から、より暗いサンプルを選択して合成イメージサンプルを作成します。背景イメージサンプルより暗いソースイメージサンプルは、対応する背景サンプルを置き換えます。
定数 kCGBlendModeDarken を CGContextSetBlendMode 関数に渡して、より暗くするブレンドモードを指定します。図 11-22 は、より暗くするブレンドモードを使用して、図 11-17 に示したイメージを、同じ図に示した長方形の上にペイントした結果を示しています。
図 11-22 より暗くするブレンドモードを使用して背景にイメージを描画
より明るくするブレンドモード
より明るくするブレンドモードは、ソースイメージまたは背景から、より明るいサンプルを選択して、合成イメージサンプルを作成します。背景イメージサンプルよりも明るいソースイメージサンプルは、対応する背景サンプルを置き換えます。
定数 kCGBlendModeLighten を関数 CGContextSetBlendMode に渡して、より明るくするブレンドモードを指定します。図 11-23 は、より明るくするブレンドモードを使用して、図 11-17 に示したイメージを、同じ図に示した長方形の上にペイントした結果を示しています。
図 11-23 より明るくするブレンドモードを使用して背景にイメージを描画
色覆い焼きブレンドモード
色覆い焼きブレンドモードは、背景イメージサンプルをもっと明るくしてソースイメージサンプルを反映します。黒を指定するソースイメージサンプル値は変更されません。
色覆い焼きブレンドモードを指定するには、定数 kCGBlendModeColorDodge を関数 CGContextSetBlendMode に渡します。図 11-24 は、色覆い焼きブレンドモードを使用して、図 11-17 に示したイメージを、同じ図に示した長方形の上にペイントした結果を示しています。
図 11-24 色覆い焼きブレンドモードを使用して背景にイメージを描画
色焼きブレンドモード
色焼きブレンドモードは、背景イメージサンプルを暗くして、ソースイメージサンプルを反映します。白を指定するソースイメージサンプル値は変更されません。
色焼きブレンドモードを指定するには、定数 kCGBlendModeColorBurn を関数 CGContextSetBlendMode に渡します。図 11-25 は、色焼きブレンドモードを使用して、図 11-17 に示したイメージを、同じ図に示した長方形の上にペイントした結果を示しています。
図 11-25 色焼きブレンドモードを使用して背景にイメージを描画
柔らかい光のブレンドモード
柔らかい光のブレンドモードは、ソースイメージサンプル色に応じて、色が暗くなったり明るくなります。ソースイメージサンプル色が 50% グレーよりも明るい場合、覆い焼くのと同様に背景が明るくなります。ソースイメージサンプル色が 50% グレーより暗い場合は、焼くのと同様に背景が暗くなります。ソースイメージサンプル色が 50% グレーに等しい場合、背景は変化しません。
純粋な黒または純粋な白に等しいイメージサンプルは、より暗くまたはより明るい領域を生成しますが、純粋な黒または白になりません。全体的な効果は、ソースイメージに、拡散したスポットライトを照射して得られる効果と似ています。
柔らかい光のブレンドモードを指定するには、定数 kCGBlendModeSoftLight を関数 CGContextSetBlendMode に渡します。図 11-26 は、柔らかい光のブレンドモードを使用して、図 11-17 に示したイメージを、同じ図に示した長方形の上にペイントした結果を示しています。
図 11-26 柔らかい光のブレンドモードを使用して背景にイメージを描画
ハードライトブレンドモード
ハードライトブレンドモードは、ソースイメージサンプル色に応じて、色を乗算またはスクリーンします。ソースイメージサンプルの色が 50% グレーよりも明るい場合、スクリーンと同様に背景は明るくなります。ソースイメージサンプル色が 50% グレーよりも暗い場合は、背景は暗くなります。ソースイメージサンプル色が 50% グレーに等しい場合、ソースイメージは変更されません。純粋な黒または純粋な白に等しいイメージサンプルは、純粋な黒または白になります。全体的な効果は、ソースイメージに厳しいスポットライトを当てることで得られる効果に似ています。
ハードライトブレンドモードを指定するには、定数 kCGBlendModeHardLight を関数 CGContextSetBlendMode に渡します。図 11-27 は、ハードライトブレンドモードを使用して、図 11-17 に示したイメージを、同じ図に示した長方形の上にペイントした結果を示しています。
図 11-27 ハードライトブレンドモードを使用して背景にイメージを描画
差分ブレンドモード
差分ブレンドモードは、背景イメージサンプルカラーからソースイメージサンプルカラーを減算するか、または輝度値がより大きいサンプルに応じてその逆をします。黒であるソースイメージサンプル値は変化しません。白は背景色の値を反転させます。
差分ブレンドモードを指定するには、定数 kCGBlendModeDifference を CGContextSetBlendMode 関数に渡します。図 11-28 は、差分ブレンドモードを使用して、図 11-17 に示したイメージを、同じ図に示した長方形の上にペイントした結果を示しています。
図 11-28 差分ブレンドモードを使用して背景にイメージを描画
排他的ブレンドモード
排他的ブレンドモードでは、差分ブレンドモードのコントラストを低くしたバージョンを生成します。黒であるソースイメージサンプル値は変化しません。白は背景色の値を反転させます。
排他的ブレンドモードを指定するには、定数 kCGBlendModeExclusion を関数 CGContextSetBlendMode に渡します。図 11-29 は、排他的ブレンドモードを使用して、図 11-17 に示したイメージを、同じ図に示した長方形の上に塗りつぶした結果を示しています。
図 11-29 排他的ブレンドモードを使用して背景にイメージを描画
色相ブレンドモード
色相ブレンドモードでは、背景の輝度と彩度の値をソースイメージの色相と共に使用します。色相ブレンドモードを指定するには、定数 kCGBlendModeHue を関数 CGContextSetBlendMode に渡します。図 11-30 に、色相ブレンドモードを使用して、図 11-17 に示したイメージを同じ図に示した長方形の上にペイントした結果を示します。
図 11-30 色相ブレンドモードを使用して背景にイメージを描画
彩度ブレンドモード
彩度ブレンドモードでは、背景の輝度と色相の値をソースイメージの彩度と共に使用します。純粋なグレーの領域は変化をしません。彩度ブレンドモードを指定するには、定数 kCGBlendModeSaturation を CGContextSetBlendMode 関数に渡します。図 11-31 に、彩度ブレンドモードを使用して、図 11-17 に示したイメージを同じ図に示した長方形の上にペイントした結果を示します。
図 11-31 彩度ブレンドモードを使用して背景にイメージを描画
色ブレンドモード
色ブレンドモードでは、背景の輝度値をソースイメージの色相と彩度値と共に使用します。このモードではイメージのグレイレベルが保持されます。色ブレンドモードを指定するには、定数 kCGBlendModeColor を CGContextSetBlendMode 関数に渡します。図 11-32 は、色ブレンドモードを使用して、図 11-17 に示したイメージを、同じ図に示した長方形の上にペイントした結果を示します。
図 11-32 色ブレンドモードを使用して背景にイメージを描画
輝度ブレンドモード
輝度ブレンドモードは、背景の色相と彩度をソースイメージの輝度と共に使用して、色ブレンドモードで作成された効果と逆の効果を生みます。
輝度ブレンドモードを指定するには、定数 kCGBlendModeLuminosity を関数 CGContextSetBlendMode に渡します。図 11-33 は、輝度ブレンドモードを使用して、図 11-17 に示したイメージを同じ図に示した長方形の上にペイントした結果を示します。
図 11-33 輝度ブレンドモードを使用して背景にイメージを描画
前の章 次の章