Bitmap images and image masks 绘制文档笔记
bitmap image和image mask的绘制是quartz 2d的传统项目。images和image masks在quartz里的表达是CGImageRef数据类型。有非常多可以用于创建image的方法。其中一些需要数据提供者或图像源来提供位图数据。其他功能通过复制图像或对图像执行操作来从现有图像创建图像。无论您如何在Quartz中创建位图图像,都可以将图像绘制为任何图形上下文。请记住,位图图像是以特定分辨率的位数组。如果您将位图图像绘制为与分辨率无关的图形上下文(例如PDF图形上下文),则位图会受到您创建分辨率的限制。
有一种方法可以创建一个Quartz图像蒙板——通过调用函数CGImageMaskCreate。
关于Bitmap images和image masks
一个bitmap位图(也叫采样图simple image)是一个像素(或者采样)的数组。每个像素代表图片的一个点。JPEG,TIFF和PNG图形文件是位图图像的示例。应用程序图标是位图图像。位图图像被限制为矩形形状。但是通过使用alpha组件,它们可以呈现出各种形状,并且可以旋转和裁剪。
位图中的每个样本包含指定颜色空间中的一个或多个颜色组件,以及一个指定alpha值以指示透明度的附加组件。每个组件可以从1到多达32位。在Mac OS X中,Quartz还提供对浮点组件的支持。 ColorSync为位图图像提供色彩空间支持。
Quartz也支持图像蒙版。图像蒙板是一个位图,用于指定要绘制的区域,但不指定颜色。实际上,图像蒙板充当模板以指定在页面上放置颜色的位置。 Quartz使用当前的填充颜色绘制图像蒙版。图像蒙板可以具有1到8位的深度。
位图图片信息Bitmap image Information
Quartz支持各种图像格式,并且内置了几种常用格式的知识。在iOS中,格式包括JPEG,GIF,PNG,TIF,ICO,GMP,XBM和CUR。其他位图图像格式或专有格式要求您为Quartz指定图像格式的详细信息,以确保图像正确解释。您提供给函数CGImageCreate的图像数据必须以每个像素为单位进行交错处理,而不是以每个扫描线为基准。 Quartz不支持平面数据。
本节描述了和位图关联的信息。当您创建并使用Quartz图像(使用CGImageRef数据类型)时,您会看到一些Quartz图像创建功能需要您指定所有这些信息,而其他功能需要这些信息的子集。您提供的内容取决于用于位图数据的编码,以及位图是表示图像还是图像掩码。
注意:为了在处理原始图像数据时获得最佳性能,请使用vImage框架。您可以使用vImageBuffer_InitWithCGImage函数将图像数据从CGImageRef引用导入vImage。
Quartz 使用以下信息创建bitmap (CGImageRef):
- 位图数据源,可以是Quartz数据提供者或Quartz图像源。 Quartz 2D中的数据管理描述了这两者并讨论了提供位图数据源的功能。
- 可选的解码数组decode array
- 一个插值设置,它是一个布尔值,用于指定Quartz在调整图像大小时是否应应用插值算法。一种呈现意图,指定如何映射位于图形上下文的目标颜色空间内的颜色。 图像遮罩不需要此信息。
- 图像尺寸
- 像素格式,包括每个组件的位数,每像素的位数和每行的字节数(像素格式)。
- 对于图像,颜色空间和位图布局(颜色空间和位图布局)信息来描述alpha的位置以及位图是否使用浮点值。 图像蒙版不需要这些信息。
Decode array
一个decode array 映射这个图片的颜色址到其他颜色址,这个array 可以用于淡化一个图片或者反转颜色等。数组包含了每个颜色组建的一对数字。当Quartz 绘制图片时,他应用一个线性的变换映射原始组建值到一个包含指定范围的相关数字,以适应目标color space。比如,例如,RGB颜色空间中的一个图像的Decode array包含6个条目,每个红、绿、蓝颜色组件对应一对。
像素格式 Pixel Format
像素格式有以下信息组成:
- 每个组件的位数,这是像素中每个单独颜色组件的位数。对于图像蒙板,该值是源像素中有效掩蔽位的数量。例如,如果源图像是8位掩码,则指定每个组件8位。
- 每像素比特数,即源像素中的总比特数。此值必须至少为每个组件的位数乘以每个像素的组件数。
- 每行字节数。图像中每个水平行的字节数
Color Spaces 和 Bitmap Layout
为了确保Quartz正确解释每个像素的位,您必须指定:
位图是否包含Alpha通道。 Quartz支持RGB,CMYK和灰色空间。它也支持alpha或透明度,但alpha信息不适用于所有位图图像格式。当它可用时,alpha分量可以位于像素的最高有效位或最低有效位中。
对于具有alpha分量的位图,颜色分量是否已经乘以alpha值。预乘alpha描述了一个源颜色,其组件已经乘以一个alpha值。通过消除每个颜色分量的多余乘法运算,预乘可以加快图像的渲染速度。例如,在RGB色彩空间中,使用预乘alpha生成图像会消除图像中每个像素的三次乘法运算(红色时间alpha,绿色时间alpha和蓝色时间alpha)。
样本的数据格式 – 整数或浮点值。
当您使用函数CGImageCreate创建图像时,您需要提供一个类型为CGImageBitmapInfo的bitmapInfo参数来指定位图布局信息。以下常量指定alpha分量的位置以及颜色分量是否预乘:
- kCGImageAlphaLast – alpha分量存储在每个像素的最低有效位中,例如RGBA。
- kCGImageAlphaFirst – alpha分量存储在每个像素的最高有效位中,例如ARGB。
- kCGImageAlphaPremultipliedLast – alpha分量存储在每个像素的最低有效位中,并且颜色分量已经乘以该alpha值。
- kCGImageAlphaPremultipliedFirst – alpha分量存储在每个像素的最高有效位中,并且颜色分量已经乘以该alpha值。
- kCGImageAlphaNoneSkipLast-没有alpha组件。如果像素的总尺寸大于颜色空间中颜色分量数量所需的空间,则忽略最低有效位。
- kCGImageAlphaNoneSkipFirst-没有alpha组件。如果像素的总大小大于色彩空间中色彩分量数量所需的空间,则忽略最高有效位。
- kCGImageAlphaNone-相当于kCGImageAlphaNoneSkipLast。
您可以使用常量kCGBitmapFloatComponents来指示使用浮点值的位图格式。对于浮点格式,您可以将此常量与前一列表中的适当常量进行逻辑或运算。例如,对于使用预乘alpha的128位/像素浮点格式,alpha位于每个像素的最低有效位中,则向Quartz提供以下信息:
kCGImageAlphaPremultipliedLast | kCGBitmapFloatComponents
创建一个图片Creating Images
创建一个图片,主要用到上文提及的一个bitmap包含的元素:位图数据源,可选的解码数组decode array,一个插值设置,它是一个布尔值,用于指定Quartz在调整图像大小时是否应应用插值算法。图像尺寸,像素格式,对于图像,颜色空间和位图布局(颜色空间和位图布局)信息来描述alpha的位置以及位图是否使用浮点值。
所以,如果想要从一个标准的图片文件如PNG,JPEG等创建一个CGImage对象,最简单的方式时调用CGImageSourceCreateWithURL方法创建一个数据源。然后通过CGImageSourceCreateImageAtIndex 方法从指定数据的index创建图片。如果原属图片只包含一个inage,那么index从0开始。如果image文件格式指出多个image,你需要指定开始的index来访问数据。index永远从0开始。
如果你已经绘制了一个bitmap graphics context,现在需要捕获这个绘制,绘制到一个CGImage Objec,调用CGBitmapContextCreateImage从graphics context创建CGImage。
几种功能是对现有图像进行操作的实用程序,可以进行复制,创建缩略图,也可以从较大的一部分创建图像。无论您如何创建CGImage对象,都可以使用函数CGContextDrawImage将图像绘制到图形上下文中。请记住,CGImage对象是不可变的。当你不再需要一个CGImage对象时,通过调用函数CGImageRelease来释放它。
Function | Description |
CGImageCreate | A flexible function for creating an image. You must specify all the bitmap information that is discussed in Bitmap Image Information. |
CGImageSourceCreateImageAtIndex | Creates an image from an image source. Image sources can contain more than one image. See Data Management in Quartz 2D for information on creating an image source. |
CGImageSourceCreateThumbnailAtIndex | Creates a thumbnail image of an image that is associated with an image source. See Data Management in Quartz 2D for information on creating an image source. |
CGBitmapContextCreateImage | Creates an image by copying the bits from a bitmap graphics context. |
CGImageCreateWithImageInRect | Creates an image from the data contained within a sub-rectangle of an image. |
CGImageCreateCopy | A utility function that creates a copy of an image. |
CGImageCreateCopyWithColorSpace | A utility function that creates a copy of an image and replaces its color space. |
创建一个Image Mask
Quartz位图图像蒙版的使用方式与艺术家使用丝网印刷的方式相同。一个bitmap image决定哪些颜色被通过,哪些颜色不行。image mask的每个采样值指定当前填充颜色在特定位置北遮罩的量。言本质指定mask的不透明度。更大的值呈现更大的不透明度而且指定Quartz绘制更少颜色的位置。你可以把言本质想象成一个反向alpha值。1是透明的,0时不透明。
图片蒙板时1,2,4,8位没组。对于1位mask,采样值1指定mask的当前填充颜色部分。样本值为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。
同理,bit越大,掩码值增量越小,控制越精细。
函数CGImageMaskCreate根据您提供的位图图像信息创建Quartz图像蒙版,并在位图图像信息中对此进行了讨论。除了不提供色彩空间信息,位图信息常量或渲染意图之外,您提供的用于创建图像蒙版的信息与创建图像所提供的信息相同。
CGImageRef CGImageMaskCreate (
|
size_t width,
|
size_t height,
|
size_t bitsPerComponent,
|
size_t bitsPerPixel,
|
size_t bytesPerRow,
|
CGDataProviderRef provider,
|
const CGFloat decode[],
|
bool shouldInterpolate
|
);
|
蒙版图片
蒙版技术通过控制那部分图片被绘制来提供许多有趣的效果。你可以:
- 应用一个图片蒙版到一个图片。你也可以使用一个图片作为蒙版来达到相反效果。
- 使用颜色遮掩部分图片,包括被称为chroma键屏蔽的技术
- 将图形上下文剪切到图像或图像蒙板上,当Quartz将内容绘制到剪裁的上下文中时,该蒙版可以有效地蒙蔽图像(或任何类型的图形)。
使用蒙版图片遮盖一张目标图
CGImageCreateWithMask返回一个图片,这个图片是有应用一个 图片蒙版到一个image创建的。这个方法有两个参数:
- 你希望遮盖的图片。这个图片不能是一个蒙版图片或者有蒙版颜色。
- 通过CGImageMaskCreate创建的蒙版。不用蒙版而使用图片也是可以的,但是这样会有非常不同的操作结果。
图像遮罩的源样本是一个反向阿尔法值。 图像蒙板样本值(S):
- 等于1时,阻止绘制相应的图像样本。
- 等于0时,允许在全覆盖范围内绘制相应的图像样本。
- 大于0且小于1时,允许用(1-S)的阿尔法值绘制相应的图像样本。
使用色彩遮盖一张目标图
函数CGImageCreateWithMaskingColors通过屏蔽一个颜色或一系列的颜色创建一个图像。
函数CGImageCreateWithMaskingColors有两个参数:
1. 一个不是图像蒙版的图像,也不是将图像蒙版或蒙版颜色应用于其他图像的结果。
2. 一组颜色组件,用于指定函数在图像中掩盖的颜色或颜色范围。
颜色分量数组中元素的数量必须等于图像颜色空间中颜色分量数量的两倍。对于色彩空间中的每个颜色分量,提供指定要遮罩的颜色范围的最小值和最大值。要仅遮盖一种颜色,请将最小值设置为等于最大值。颜色分量数组中的值按以下顺序提供:
{min [1],max [1],… min [N],max [N]},其中N是分量的数量。
如果图像使用整数像素分量,则颜色分量数组中的每个值必须在[0 .. 2 ^ bitsPerComponent – 1]范围内。如果图像使用浮点像素组件,则每个值可以是任何作为有效颜色组件的浮点数。
如果图像样本的颜色值落入范围内,则不会绘制图像样本:
{c [1],… c [N]}
其中对于1≤i≤N,min [i] <= c [i] <= max [i]
未涂漆样品下方的任何物品(如当前的填充颜色或其他图形)均会显示。
Masking light to mid-range brown colors in an image:
CGImageRef myColorMaskedImage;
|
const CGFloat myMaskingColors[6] = {124, 255, 68, 222, 0, 165};
|
myColorMaskedImage = CGImageCreateWithMaskingColors (image,
|
myMaskingColors);
|
CGContextDrawImage (context, myContextRect, myColorMaskedImage);
|
Masking shades of brown to black
CGImageRef myMaskedImage;
|
const CGFloat myMaskingColors[6] = { 0, 124, 0, 68, 0, 0 };
|
myColorMaskedImage = CGImageCreateWithMaskingColors (image,
|
myMaskingColors);
|
CGContextDrawImage (context, myContextRect, myColorMaskedImage);
|
Masking a range of colors and setting a fill color and
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);
|
使用裁切上下文方式遮盖一张目标图
CGContextClipToMask方法映射一个蒙版到一个矩形并且将其与图形上下文的当前剪切区域相交。接受以下参数:
- 你要剪辑的graphics context。
- 要应用遮盖的矩形
- 调用函数CGImageMaskCreate创建的图像蒙版。 您可以提供图像而不是图像蒙版,以达到与提供图像蒙版相反的效果。 该图像必须使用Quartz图像创建功能创建,但不能是将遮罩或遮罩颜色应用于其他图像的结果。
关于图片的混合模式
您可以使用Quartz 2D混合模式(请参阅设置混合模式)合成两个图像,或将图像合成到已经绘制到图形上下文的任何内容上。
在背景上合成图像的一般步骤如下:
- 绘制背景。
- 通过使用其中一种混合模式常量调用函数CGContextSetBlendMode来设置混合模式。The blend modes are based upon those defined in the PDF Reference, Fourth Edition, Version 1.5, Adobe Systems, Inc.)
- 通过调用函数CGContextDrawImage来绘制要在背景上合成的图像。
此代码片段使用“变暗”混合模式在背景上合成一个图像:
CGContextSetBlendMode (myContext, kCGBlendModeDarken);
|
CGContextDrawImage (myContext, myRect, myImage2);
|
end