Bitmap Images and Image Masks

位图图像和图像蒙板就像Quartz中的任何图形图元。 Quartz中的图像和图像蒙板都由CGImageRef数据类型表示。正如你将在本章后面看到的,有多种功能可以用来创建图像。其中一些需要数据提供者或图像源来提供位图数据。其他功能通过复制图像或通过对图像应用操作从现有图像创建图像。无论你如何在Quartz中创建位图图像,都可以将图像绘制到任何图形上下文的风格。请记住,位图图像是以特定分辨率的位数组。如果将位图图像绘制到独立于分辨率的图形上下文(例如PDF图形上下文),位图将受到创建它的分辨率的限制。

有一种方法来创建一个Quartz图像蒙板 - 通过调用函数CGImageMaskCreate。您将看到如何在创建图像掩码中创建一个。应用图像掩码不是屏蔽图形的唯一方法。使用颜色屏蔽图像,使用图像掩码屏蔽图像和通过剪切上下文来屏蔽图像的部分讨论了Quartz中可用的所有屏蔽方法。

关于位图图像和图像掩码

位图图像(或采样图像)是像素(或样本)的阵列。 每个像素表示图像中的单个点。 JPEG,TIFF和PNG图形文件是位图图像的示例。 应用程序图标是位图图像。 位图图像被限制为矩形形状。 但是使用alpha组件,它们可以呈现为各种形状,并且可以旋转和剪切,如图11-1所示。

11-1 位图图像

位图中的每个样本包含指定颜色空间中的一个或多个颜色分量,以及指定用于指示透明度的Alpha值的一个附加分量。 每个组件可以从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图像创建函数需要您指定所有这些信息,而其他函数需要此信息的一个子集。 您提供的内容取决于用于位图数据的编码,以及位图是否表示图像或图像掩码。

注:为了在使用原始图像数据时获得最佳性能,请使用vImage框架。 您可以使用vImageBuffer_InitWithCGImage函数将图像数据从CGImageRef引用导入vImage。 有关详细信息,请参阅加速发行说明。

Quartz在创建位图图像(CGImageRef)时使用以下信息:

  • 位图数据源,可以是Quartz数据提供程序或Quartz图像源。 Quartz 2D中的数据管理描述了这两种功能,并讨论了提供位图数据源的功能。
  • 可选的解码数组(Decode Array)。
  • 插值设置,它是一个布尔值,指定Quartz在调整图像大小时应应用插值算法。
  • 渲染意图,指定如何映射位于图形上下文的目标颜色空间中的颜色。图像掩码不需要此信息。有关详细信息,请参阅设置呈现意图。
  • 图像尺寸。
  • 像素格式,包括每个分量的位数,每像素的位数和每行的字节数(像素格式)。
  • 对于图像,颜色空间和位图布局(颜色空间和位图布局)信息来描述alpha的位置以及位图是否使用浮点值。图像掩码不需要此信息。

解码数组

解码阵列将图像颜色值映射到其他颜色值,这对于诸如使图像去饱和或反转颜色的任务是有用的。 该数组包含每个颜色分量的一对数字。 当Quartz渲染图像时,将应用线性变换将原始组件值映射到适合目标颜色空间的指定范围内的相对数。 例如,用于RGB颜色空间中的图像的解码阵列包含六个条目,对于每个红色,绿色和蓝色分量一对。

像素格式

像素格式由以下信息组成:

  • 每分量比特,其是像素中每个单独颜色分量中的比特数。 对于图像掩码,该值是源像素中的有效掩码位的数目。 例如,如果源图像是8位掩码,请为每个分量指定8位。
  • 每像素的位,其是源像素中的位的总数。 该值必须至少为每个组件的位数乘以每个像素的组件数。
  • 每行字节数。 图像中每水平行的字节数。

颜色空间和位图布局

为了确保Quartz正确解释每个像素的位,必须指定:

  • 位图是否包含Alpha通道。 Quartz支持RGB,CMYK和灰色色彩空间。它还支持alpha或透明度,虽然alpha信息不是在所有位图图像格式中可用。当其可用时,alpha分量可以位于像素的最高有效位或最低有效位。

  • 对于具有alpha分量的位图,无论颜色分量是否已经乘以alpha值。预乘alpha描述其源成分已经乘以α值的源色彩。预翻转通过消除每个颜色分量的额外乘法运算来加速图像的渲染。例如,在RGB颜色空间中,利用预乘α渲染图像消除了图像中的每个像素的三个乘法运算(红色乘以alpha,绿色乘以alpha和蓝色乘以alpha)。
    样本的数据格式 - 整数或浮点值。

  • 当使用函数CGImageCreate创建图像时,提供一个bitmapInfo参数,类型为CGImageBitmapInfo,以指定位图布局信息。以下常量指定alpha组件的位置以及颜色组件是否预乘:

  • kCGImageAlphaLast - 将alpha分量存储在每个像素(例如,RGBA)的最低有效位中。

  • kCGImageAlpha首先,alpha分量存储在每个像素的最高有效位中,例如,ARGB。

  • kCGImageAlphaPremultipliedLast - alpha分量存储在每个像素的最低有效位中,颜色分量已经乘以该alpha值。

  • kCGImageAlphaPremultipliedFirst - alpha分量存储在每个像素的最高有效位,颜色分量已经乘以该alpha值。

  • kCGImageAlphaNoneSkipLast - 没有alpha组件。如果像素的总大小大于颜色空间中的颜色分量的数量所需的空间,则忽略最低有效位。

  • kCGImageAlphaNoneSkipFirst - 没有alpha组件。如果像素的总大小大于颜色空间中的颜色分量的数量所需的空间,则忽略最高有效位。

  • kCGImageAlphaNone - 等价于kCGImageAlphaNoneSkipLast。

您可以使用常量kCGBitmapFloatComponents来指示使用浮点值的位图格式。对于浮点格式,您将此常量与上一列表中的适当常数进行逻辑或运算。例如,对于使用预乘α的128位每像素浮点格式,alpha位于每个像素的最低有效位,您向Quartz提供以下信息:

kCGImageAlphaPremultipliedLast | kCGBitmapFloatComponents

图11-2直观地描述了在使用16位或32位整数格式的CMYK和RGB颜色空间中表示像素的方式。 32位整数像素格式每个分量使用8位。 16位整数格式每个组件使用5位。 Quartz 2D还支持128位浮点像素格式,每个组件使用32位。 128位格式未在图中显示。

11-2 32位和16位像素格式用于Quartz 2D中的CMYK和RGB颜色空间

创建图像

表11-1列出了Quartz提供的用于创建CGImage对象的函数。图像创建功能的选择取决于图像数据的来源。最灵活的功能是CGImageCreate。它从任何种类的位图数据创建图像。但是,它是最复杂的功能,因为您必须指定所有位图信息。要使用此功能,您需要熟悉位图图像信息中讨论的主题。

如果要从使用标准图像格式(例如PNG或JPEG)的图像文件创建CGImage对象,最简单的解决方法是调用函数CGImageSourceCreateWithURL创建图像源,然后调用函数CGImageSourceCreateImageAtIndex从而创建一个图像在图像源中的特定索引处的图像数据。如果原始图像文件只包含一个图像,则提供0作为索引。如果图像文件格式支持包含多个图像的文件,则需要提供适当图像的索引,请记住索引值从0开始。

如果你绘制了一个位图图形上下文的内容,并想要捕获该图形到一个CGImage对象,调用函数CGBitmapContextCreateImage。

几个函数是对现有图像进行操作的实用程序,以便进行复制,创建缩略图或从较大的一部分创建图像。无论如何创建CGImage对象,都可以使用函数CGContextDrawImage将图像绘制到图形上下文。记住,CGImage对象是不可变的。当你不再需要一个CGImage对象时,通过调用CGImageRelease函数释放它。

创建图像的函数

以下部分讨论如何创建:

  • 来自现有图像的子图像
  • 来自位图图形上下文的图像

您可以参考这些来源获取更多信息:

  • Quartz 2D中的数据管理讨论如何读取和写入图像数据。
  • CGImage参考,CGImageSource参考和CGBitmapContext参考有关表11-1中列出的功能及其参数的更多信息。

从较大图像的一部分创建图像

函数CGImageCreateWithImageInRect允许您从现有的Quartz图像创建子图像。 图11-3示出通过提供指定字母“A”的位置的矩形来从更大的图像中提取包含字母“A”的图像。

11-3 从较大图像创建的子图像

由函数CGImageCreateWithImageInRect返回的图像保留对原始图像的引用,这意味着您可以在调用此函数后释放原始图像。

图11-4显示了提取图像的一部分以创建另一个图像的另一个示例。在这种情况下,公鸡的头部从较大的图像中提取,然后绘制成大于子图像的矩形,有效地放大图像。

清单11-1显示了创建并绘制子图像的代码。 CGContextDrawImage函数绘制公鸡头部的矩形的尺寸是提取的子图像尺寸的两倍。列表是一个代码片段。你需要声明适当的变量,创建公鸡图像,并处置公鸡图像和公鸡头子图像。因为代码是一个片段,它不显示如何创建图像被绘制的图形上下文。你可以使用任何你喜欢的图形上下文的风味。有关如何创建图形上下文的示例,请参阅图形上下文。

11-4 一个图像,从它拍摄的一个子图像,绘制使其放大
// 建子图像并将其放大绘制的代码
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位掩码具有以1/15的增量在从0到1的范围内的值。 0或1的组件值代表极端 - 完全阻止油漆,并完全允许油漆。 0和1之间的值允许使用公式1 - MaskSampleValue进行局部绘画。 例如,如果8位掩码的样本值缩放到0.7,则颜色将被绘制为具有(1-0.7)的α值,即为0.3。

函数CGImageMaskCreate从您提供的位图图像信息中创建一个Quartz图像掩码,这将在位图图像信息中讨论。 您提供用于创建图像掩码的信息与创建图像时所提供的信息相同,但您不提供颜色空间信息,位图信息常量或渲染意图,您可以通过查看函数 示例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返回通过向图像应用图像蒙版所创建的图像。 此函数有两个参数:

  • 您要应用蒙版的图像。 此图像不能是图像掩码或具有与其关联的掩蔽颜色(请参阅使用颜色掩蔽图像)。
  • 通过调用函数CGImageMaskCreate创建的图像掩码。 它可以提供一个图像而不是图像蒙版,但是给出了一个非常不同的结果。 请参阅使用图像屏蔽图像。

图像掩码的源样本用作逆alpha值。 图像掩码样本值(S):

  • 等于1块绘制相应的图像样本。
  • 等于0允许以完全覆盖的方式绘制相应的图像样本。
  • 大于0和小于1允许用α值(1-S)绘制对应的图像样本。

图11-5显示了使用Quartz图像创建函数创建的图像,图11-6显示了使用函数CGImageM创建的图像掩码

11-5 原始图像
11-6 图像蒙版

注意,原始图像中对应于掩模的黑色区域的区域在所得到的图像中显示通过(图11-7)。 与面罩的白色区域相对应的区域不被涂漆。 对应于掩模中的灰色区域的区域使用等于1减去图像掩模样本值的中间alpha值来绘制。

11-7 将图像蒙版应用于原始图像所产生的图像

用图像掩蔽图像

您可以使用函数CGImageCreateWithMask来用另一个图像来遮蔽图像,而不是使用图像遮罩。你可以这样做,以达到与使用图像蒙板掩蔽图像时相反的效果。而不是传递使用函数CGImageMaskCreate创建的图像掩码,而是提供从一个Quartz图像创建函数创建的图像。

用作掩码(但不是Quartz图像掩码)的图像的源样本作为alpha值操作。图像样本值(S):

  • 等于1允许在全覆盖下绘制相应的图像样本。
  • 等于0块绘制相应的图像样本。
  • 大于0和小于1允许用α值绘制相应的图像样本。

图11-8显示了通过调用函数CGImageCreateWithMask将图11-6所示的图像应用于图11-5所示的图像而得到的图像。在这种情况下,假设使用Quartz图像创建函数(如CGImageCreate)创建图11-6所示的图像。将图11-8与图11-7进行比较,看看相同的样本值,当用作图像样本而不是图像掩码样本时,实现了相反的效果。

对应于图像黑色区域的原始图像中的区域不会在生成的图像中绘制(图11-8)。对应于白色区域的区域被涂漆。使用等于掩蔽图像样本值的中间α值来绘制对应于掩模中的灰色区域的区域。

11-8 由图像遮蔽原始图像产生的图像

用颜色遮蔽图像

函数CGImageCreateWithMaskingColors通过屏蔽提供给函数的图像中的一种颜色或一系列颜色来创建图像。 使用此功能,您可以执行类似于图11-9所示的色键掩码,或者您可以屏蔽一系列颜色,类似于图11-11,图11-12和图11-13所示。

函数CGImageCreateWithMaskingColors有两个参数:

  • 不是图像蒙版并且不是将图像蒙版或蒙版颜色应用于其他图像的结果的图像。
  • 指定颜色或颜色范围的颜色组件数组,以便函数在图像中进行遮罩。
11-9 色度键掩码

颜色分量数组中的元素数量必须等于图像颜色空间中颜色分量数量的两倍。对于颜色空间中的每个颜色分量,提供一个最小值和一个最大值,指定要屏蔽的颜色范围。要仅遮蔽一种颜色,请将最小值设置为等于最大值。颜色分量数组中的值按以下顺序提供:

{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所示,两只老虎的图像使用每个分量8位的RGB颜色空间。要掩蔽此图像中的一系列颜色,您需要在0到255的范围内提供最小和最大颜色分量值。


11-10 原始图像

清单11-3显示了一个代码片段,它设置了一个颜色组件数组,并将该数组提供给函数CGImageCreateWithMaskingColors,以实现图11-11所示的结果。

// 将光线遮蔽到图像中的中等棕色颜色
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所示的结果。 此示例屏蔽较暗的颜色范围。

// 掩蔽后的图像颜色从深棕色到黑色
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所示图像的代码片段。

// 遮蔽一系列颜色并设置填充颜色
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混合模式(请参阅设置混合模式)来合成两个图像,或者在已经绘制到图形上下文的任何内容上合成图像。 本节讨论在背景图形上合成图像。

在背景上合成图像的一般过程如下:

  1. 绘制背景。
  2. 通过使用混合模式常量之一调用函数CGContextSetBlendMode设置混合模式。 (混合模式基于在PDF参考,第四版,1.5版,Adobe Systems,Inc。中定义的模式)
  3. 通过调用函数CGContextDrawImage在背景上绘制要合成的图像。

此代码片段使用“darken”混合模式在背景上合成一个图像:

CGContextSetBlendMode (myContext, kCGBlendModeDarken);
CGContextDrawImage (myContext, myRect, myImage2);

本节的其余部分使用Quartz提供的每种混合模式,在由图左侧所示的画矩形组成的背景上绘制图11-17右侧所示的图像。 在所有情况下,矩形首先被绘制到图形上下文。 然后,通过调用函数CGContextSetBlendMode设置混合模式,传递适当的混合模式常量。 最后,跳线的图像被绘制到图形上下文。

11-17 背景图(左)和前景图(右)

Normal Blend Mode

正常混合模式在源图像样本上涂覆背景图像样本。 正常混合模式是Quartz的默认混合模式。 如果您正在使用另一种混合模式并想要切换到正常混合模式,则只需显式设置正常混合模式。 您可以通过将常量kCGBlendModeNormal传递到函数CGContextSetBlendMode或通过使用函数CGContextRestoreGState恢复图形状态(假设先前的图形状态使用正常混合模式)来设置正常混合模式。

图11-18显示了使用正常混合模式在同一图中所示的矩形上绘制如图11-17所示的图像的结果。 在此示例中,使用alpha值1.0绘制图像,因此背景完全被图像遮挡。

11-18 使用正常混合模式在背景上绘制图像

Multiply Blend Mode

乘法混合模式将源图像样本与背景图像样本相乘。 所得图像中的颜色至少与两种贡献的样品颜色中的任一种一样暗。

通过将常量kCGBlendModeMultiply传递给函数CGContextSetBlendMode,可以指定乘法混合模式。 图11-19显示了使用乘法混合模式在同一图中所示的矩形上绘制图11-17所示的图像的结果。

11-19 使用乘法混合模式在背景上绘制图像

Screen Blend Mode

屏幕混合模式将源图像样本的逆与背景图像样本的逆相乘,以获得至少与两个贡献样本颜色中的任一个一样轻的颜色。

通过将常量kCGBlendModeScreen传递给函数CGContextSetBlendMode,可以指定屏幕混合模式。 图11-20显示了使用屏幕混合模式在同一图中所示的矩形上绘制如图11-17所示的图像的结果。

11-20 使用屏幕混合模式在背景上绘制图像

Overlay Blend Mode

叠加混合模式根据背景样本的颜色,将源图像样本与背景图像样本相乘或进行筛选。 结果是覆盖现有的图像样本,同时保留背景的高光和阴影。 背景颜色与源图像混合以反映背景的亮度或暗度。

通过将常量kCGBlendModeOverlay传递给函数CGContextSetBlendMode来指定覆盖混合模式。 图11-21显示了使用覆盖混合模式在同一图中所示的矩形上绘制如图11-17所示的图像的结果。

11-21 使用覆盖混合模式在背景上绘制图像

Darken Blend Mode

变暗混合模式通过从源图像或背景中选择较暗的样本来创建复合图像样本。比较背景图像样本更暗的源图像样本替换相应的背景样本。

通过将常量kCGBlendModeDarken传递给函数CGContextSetBlendMode来指定暗混合模式。图11-22显示了使用暗混合模式在同一图中所示的矩形上绘制图11-17所示的图像的结果。

11-22 使用深色混合模式在背景上绘制图像

Lighten Blend Mode

淡化混合模式通过从源图像或背景中选择较浅的样本来创建复合图像样本。 比背景图像样本更亮的源图像样本替换相应的背景样本。

通过将常量kCGBlendModeLighten传递到函数CGContextSetBlendMode,指定减轻混合模式。 图11-23显示了使用淡化混合模式在同一图中所示的矩形上绘制图11-17所示的图像的结果。

11-23 使用淡化混合模式在背景上绘制图像

Color Dodge Blend Mode

颜色闪避混合模式增亮背景图像样本以反映源图像样本。 指定黑色的源图像样本值保持不变。

通过将常量kCGBlendModeColorDodge传递给函数CGContextSetBlendMode,可以指定颜色闪避混合模式。 图11-24显示了使用颜色闪避混合模式在同一图中所示的矩形上绘制如图11-17所示的图像的结果。

11-24 使用颜色闪避混合模式在背景上绘制图像

Color Burn Blend Mode

彩色混合模式使背景图像样本变暗以反映源图像样本。 指定白色的源图像样本值保持不变。

通过将常量kCGBlendModeColorBurn传递给函数CGContextSetBlendMode,可以指定颜色混合模式。 图11-25显示了使用颜色混合模式在同一图中所示的矩形上绘制如图11-17所示的图像的结果。

11-25 使用颜色混合模式在背景上绘制图像

Soft Light Blend Mode

柔光混合模式根据源图像样本颜色使颜色变暗或变亮。 如果源图像样本颜色比50%灰色浅,则背景变亮,类似于躲闪。 如果源图像样本颜色比50%灰色深,则背景变暗,类似于燃烧。 如果源图像样本颜色等于50%灰色,则背景不变。

等于纯黑色或纯白色的图像样本会产生较暗或较亮的区域,但不会产生纯黑色或白色。 整体效果类似于通过在源图像上照射漫射聚光灯实现的效果。

通过将常量kCGBlendModeSoftLight传递给函数CGContextSetBlendMode,可以指定柔光混合模式。 图11-26显示了使用柔光混合模式在同一图中所示的矩形上绘制如图11-17所示的图像的结果。

11-26 使用柔和光混合模式在背景上绘制图像

Hard Light Blend Mode

硬光混合模式可以倍增或屏幕颜色,具体取决于源图像样本颜色。 如果源图像样本颜色比50%灰色浅,则背景被减轻,类似于筛选。 如果源图像样本颜色比50%灰色深,则背景变暗,类似于乘法。 如果源图像样本颜色等于50%灰色,则源图像不变。 等于纯黑色或纯白色的图像样本导致纯黑色或白色。 整体效果类似于通过在源图像上照射严酷的聚光灯实现的效果。

通过将常量kCGBlendModeHardLight传递给函数CGContextSetBlendMode,可以指定硬光混合模式。 图11-27显示了使用硬光混合模式在同一图中所示的矩形上绘制如图11-17所示的图像的结果。

11-27 使用硬光混合模式在背景上绘制图像

Difference Blend Mode

差分混合模式从背景图像样本颜色中减去源图像样本颜色,或者相反,这取决于哪个样本具有较大的亮度值。 黑色的源图像样本值不产生变化; 白色反转背景颜色值。

通过将常量kCGBlendModeDifference传递给函数CGContextSetBlendMode,可以指定差异混合模式。 图11-28显示了使用差异混合模式在同一图中所示的矩形上绘制如图11-17所示的图像的结果。

11-28 使用差异混合模式在背景上绘制图像

Exclusion Blend Mode

排除混合模式产生差异混合模式的低对比度版本。 黑色的源图像样本值不产生变化; 白色反转背景颜色值。

可以通过将常量kCGBlendModeExclusion传递给函数CGContextSetBlendMode来指定排除混合模式。 图11-29显示了使用排除混合模式在同一图中所示的矩形上绘制如图11-17所示的图像的结果。

11-29 使用排除混合模式在背景上绘制图像

Hue Blend Mode

色相混合模式使用背景的亮度和饱和度值与源图像的色调。 通过将常量kCGBlendModeHue传递给函数CGContextSetBlendMode,可以指定色调混合模式。 图11-30显示了使用色相混合模式在同一图中所示的矩形上绘制如图11-17所示的图像的结果。

11-30 使用色相混合模式在背景上绘制图像

Saturation Blend Mode

饱和度混合模式使用背景的亮度和色调值与源图像的饱和度。 纯灰色区域不产生变化。 通过将常量kCGBlendModeSaturation传递给函数CGContextSetBlendMode来指定饱和混合模式。 图11-31显示了使用饱和混合模式在同一图中所示的矩形上绘制如图11-17所示的图像的结果。

11-31 使用饱和度混合模式在背景上绘制图像

Color Blend Mode

颜色混合模式使用背景的亮度值与源图像的色调和饱和度值。 此模式保留图像中的灰度级。 通过将常量kCGBlendModeColor传递给函数CGContextSetBlendMode,可以指定颜色混合模式。 图11-32显示了使用颜色混合模式在同一图中所示的矩形上绘制如图11-17所示的图像的结果。

11-32 使用颜色混合模式在背景上绘制图像

Luminosity Blend Mode

亮度混合模式使用背景的色调和饱和度与源图像的亮度创建与由颜色混合模式创建的效果相反的效果。

你通过传递常量kCGBlendModeLuminosity到函数CGContextSetBlendMode指定光度混合模式。 图11-33显示了使用光度混合模式在同一图中所示的矩形上绘制如图11-17所示的图像的结果。

11-33 使用光度混合模式在背景上绘制图像
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容

  • 在Quartz中位图图像和图像掩模更像是初级的。图像和图像掩模在Quartz中都是CGImageRef 数据类型。...
    雪_晟阅读 666评论 1 3
  • 本文转载自:http://southpeak.github.io/2015/01/05/quartz2d-11/ ...
    idiot_lin阅读 881评论 1 1
  • 路径定义一个或多个形状或子路径。 子路径可以由直线,曲线或两者组成。 它可以打开或关闭。 子路径可以是简单的形状,...
    权宜平和阅读 799评论 0 1
  • 图形上下文表示绘图目的地。它包含绘图系统执行任何后续绘图命令所需的绘图参数和所有特定于设备的信息。图形上下文定义基...
    权宜平和阅读 747评论 0 0
  • 1 五年,在我25岁的时候,上帝赐给我圣灵告诉我30岁要发生的事情,上帝告诉我,30岁我有精神病人公司。有一个属于...
    潘蓝一阅读 699评论 1 1