Quartz 2D 之Bitmap Images and Image Masks

在Quartz中位图图像和图像掩模更像是初级的。图像和图像掩模在Quartz中都是CGImageRef 数据类型。在文章的后面你可以了解到很多创建图像的方法。一些方法需要你提供数据提供者或者元数据从而提供位图数据,一些方法通过从已有的图想创建位图或者拷贝或者通过应用一个操作的图像。不管你是怎么创建的位图,你都可以上下文中绘制位图。永远时刻记着位图是指定分辨率的位数组。

可以通过CGImageMaskCreate方法创建一个位图掩模。应用图像掩模不是唯一的方法来掩模图形。

About Bitmap Images and Image Masks  关于位图和图像掩模


一个位图图像是像素的数组集合。每个像素代表图像中的一个点。JPEG TIFF PNG 图形文件都是位图的例子。应用程序图标也是位图。但是位图仅限于矩形框,但是我们可以使用透明度,使得位图可以设计为不同的形状。 可以被剪裁,被旋转。

位图中的每个样本在指定的颜色空间里包含一个或者多个组分,在增加一个透明度。每个组分可以是1到32位之间的。在Mac OS X中,Quartz 支持浮点数。

Quartz 也支持图像掩模。一个掩模是指定了绘制区域的位图,而不是颜色。实际上,图像掩模就像是一个模板指定页面上的颜色。Quartz 使用当前的颜色绘制图像掩模。一个图像掩模有一个1到8位的深度。

Bitmap Image Information 位图信息

Quartz支持很多图形格式还有很多流行的数据格式。在iOS中,这个格式包括JPEG, GIF, PNG, TIF, ICO, GMP, XBM, and CUR,其他的位图格式和专用格式需要你指定图片格式的细节以便图像能够被正确解释。提供给方法CGImageCreate的数据必须在每个像素上交叉,而不是每个扫描线。Quartz不支持平面数据。

本章节,描述了位图相关的信息,当你使用Quartz图像(CGImageRef数据格式)创建使用时,你将会看到一些图像创建方法需要你指定一些信息,而有些方法需要你指定这些信息的子集。你需要提供的取决于位图数据的编码,以及位图是否代表一个图像或图像掩模。

Note:在操作元数据时获得最佳性能,最好使用vlmage框架。你可以使用方法vImageBuffer_InitWithCGImage 把图像数据导入进vlmage。

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

1.A bitmap data source 。位图数据来源,这个可以由Quartz数据提供者提供或者图像来源。Data Management in Quartz 2D 章节中讨论了提供给位图数据的方法。

2.An optional decode array。一个可选的解码数组。

3.An interpolation setting。插值设置。一个布尔值,指定Quartz是否在图像缩放时使用图像插值算法。

4.指定如何映射位于图形上下文的目标颜色空间内的颜色的渲染意图,此信息是不需要图像掩模。参考Setting Rendering Intent

5.dimensions。图像规格

6.像素格式,包括了组分的位数,每个像素的位数,每行的字节数。

7.对于图像,颜色空间和位图布局(Color Spaces and Bitmap Layout))信息来描述阿尔法的位置,以及位图是否使用浮点值。图像掩模不需要此信息。

Decode Array

一个可选的解码数组在不饱和图像或者反转颜色时可以将一些颜色映射到其他颜色中。这个数组包含了一对数值,为颜色的每个组分服务。当Quartz渲染图像时,它使用了线性变换把原始的组分值映射到接近目的颜色空间的指定设置变化范围内。例如,由RGB颜色组成的图像的解码数组,包含6个入口,红绿蓝各一对。

Pixel Format

像素格式包含以下信息:

① Bits per component。每个组分的位数。指定了一个像素中每个独立的颜色组分的位数。在图像掩模中,这个值是源像素的位数。例如,如果源映像是一个8位掩模,请指定每一个组件的8位。

② Bits per pixel。每个像素的位数,这是源像素的总位数。这个值最少是咩组分的位数 * 每个像素的组分数。

③ Bytes per row 。每行字节数。图像中每行水平行的字节数

Color Spaces and Bitmap Layout

为了保证Quartz能正确解释每个像素的位数,你必须制定:

① 是否一个位图包含透明度。Quartz支持RGB CMYK 和灰色颜色空间。它也支持透明度。尽管在所有的位图图像格式中透明度信息是不支持的。

② 对于有透明度组分的位图。透明度组分是否已经被前乘。前乘提高了渲染效率减少了每个颜色组分和透明度的相乘。例如,在RGB颜色空间中进行,与透明度前乘消除了(红色、绿色 、蓝色 与透明度的相乘)。

③ 样本点的格式--整形或者浮点数。

当你使用方法CGImageCreate创建一个图像,你需要提供一个参数指针和CGImageBitmapInfo格式的类型(指定layout信息)。下列的常量指定了透明度的位置和颜色组分是否被前乘。

kCGImageAlphaLast:存储在 每个像素里最不重要的位数 如RGBA。

kCGImageAlphaFirst:存储在最重要的位数。如ARGB。

kCGImageAlphaPremultipliedLast:存储在最不要重要的位数,颜色组分已经和透明度前乘。

kCGImageAlphaPremultipliedFirst:存储在最重要的位数,颜色组分已经和透明度前乘。

kCGImageAlphaNoneSkipLast:没有透明度。最不重要的位数被忽略

kCGImageAlphaNoneSkipFirst:没有透明度。最重要的位数被忽略

kCGImageAlphaNone: 等同于kCGImageAlphaNoneSkipLast

你可以使用kCGBitmapFloatComponents 声明位图为浮点值。在逻辑上采用或。 比如每个像素128位的浮点可以使用前程透明度,如:kCGImageAlphaPremultipliedLast|kCGBitmapFloatComponents

图11-2 可视化描述了在CMYK和RGB颜色空间中像素代表了什么,16 和32位的格式。32位像素采用8位每组分。16为像素采用5位每组分。Quartz 2D也支持128位的,下图没有展示。

Creating Images 创建图像

表中例举了Quartz提供创建CGImage对象的方法。创建的方法取决于图像源数据。最灵活的方法是 CGImageCreate。它可以创建来自于任意一种数据源的。然而大部分你使用的复杂功能你必须指定所有的位图信息。在使用这个方法的时候,你必须对Bitmap Image Information.特别熟悉。

如果你从标准的数据格式 PNG 或者 JPEG创建一个CGImage对象,最简单的办法就是 调用方法CGImageSourceCreateWithURL创建一个图像源,然后调用方法CGImageSourceCreateImageAtIndex,指定下标。

如果你绘制在位图上下文上,想捕捉,调用方法CGBitmapContextCreateImage

一些方法是对现有图像操作的实用工具。可以创建一个副本,创建一个缩略图,或者从一个较大的图截取一部分。不管你创建CGImage对象的方式,你使用CGContextDrawImage方法绘制在图形上下文上。永远记住CGImage是不可变的。当你不需要一个CGImage对象时,调用方法CGImageRelease释放掉。

以下章节将讨论:

    A subimage from an existing image 来自现有图像的子图像

   An image from a bitmap graphics context 来自位图上下文的图像

你可以参考的信息:

Data Management in Quartz 2Ddiscusses how to read and write image data.

CGImage Reference,CGImageSource Reference, andCGBitmapContext Referencefor further information on the functions listed inTable 11-1and their parameters.

Creating an Image From Part of a Larger Image
方法CGImageCreateWithImageInRect可以帮助你创建一个子图像从已经存在的图像。图11-3说明提取了字母A 通过一个矩形框指定A的位置。

使用方法CGImageCreateWithImageInRect返回的图像保留了对原图像的引用,意味着调用完这个方法后需要释放掉源图像

11-4 展示了 大图截取为小图,然后小图绘制在一个大的矩形框中。

 代码片段:

Creating an Image from a Bitmap Graphics Context 从位图上下文中创建一个图像

从已经存在的位图上下文创建一个图像的方法是调用 CGBitmapContextCreateImage。这个方法返回的CGImage是一个拷贝的操作,因此后续的位图上下文的变化不会影响返回的CGImage的内容。

Creating an Image Mask 创建一个图像掩模

位图掩模决定了颜色是如何传输的,而不是颜色如何被使用的。图像掩模谁1,2,4,8位每组分。对于1位掩模,样本值1 就代表禁用当前的填充颜色,0 代表被绘制在上下文时代表的颜色。对于2,4,或者8位掩模代表灰度值,每个组分映射到范围0 ~1,使用下面的公式:

例如,一个4位掩模有值的范围从0到1的1 / 15的增量。当一个8位掩模样本值缩小到0.7时,颜色被绘制时,透明度为 1-MaskSampleValue,为0.3.

创建一个位图掩模使用方法CGImageMaskCreate,需要提供位图图像信息。这和创建一个图像需要提供的信息是一样的,除了你不提供颜色空间信息或者渲染意图。

Masking Images 掩模图像

掩模技术通过控制图像哪些部分需要绘制从而实现有趣的效果。

1.可以使用一个图像作为图像掩模

2.使用颜色来掩盖图像的部分,其中包括被称为色度抠像的技术

3.将图形上下文剪辑到图像或图像掩模上

Masking an Image with an Image Mask   使用图像掩模掩模图像

CGImageCreateWithMask这个方法返回了一个图像被用来掩模。这个方法需要两个参数:

        1.你需要被掩模的图像。这个图像不能是一个掩模图像,或者有掩盖颜色。

        2.CGImageMaskCreate,通过这个方法创建一个图像掩模。

  样本值和透明度是相反的。1 代表着禁止,0代表可以覆盖。

11-5 原图

11-6 展示了使用方法CGImageMaskCreate.创建掩模。

the result :白色区域不绘制,灰色区域透明度 =  1- s

Masking an Image with an Image 使用图像

CGImageMaskCreate,使用这个方法,如果还是使用之前的方法CGImageCreateWithMask,使用图像掩模效果是这样的,

同样的样本值,在被用作图像样本和掩模样本的时候效果是截然不同的。

Masking an Image with Color 用颜色掩蔽图像

CGImageCreateWithMaskingColors 这个方法创建了一个掩模通过一个颜色或者一系列颜色。使用这个方法你可以实现chroma key masking 色度抠像。

需要两个参数:一个非掩模的图像,一个颜色组分的数组:指定颜色变化。

在颜色分量数组中的元素的数目必须等于图像的颜色空间的颜色分量的两倍。对于颜色空间中的每个颜色组件,提供一个最小值和一个指定颜色的范围的最大值。如果只是掩盖一个颜色,设置最小值等于最大值。颜色分量数组中的值按以下顺序提供:

{min[1], max[1], ... min[N], max[N]}, N代表 组分的数量。

对于整形来说,颜色组分数组的每个值的变化范围在[0 .. 2^bitsPerComponent - 1]。浮点数可以是任意的有效的颜色组分。

实现效果

代码片段:

另一种:

代码片段:


也可以替代填充颜色:

代码片段:

Masking an Image by Clipping the Context 通过裁剪上下文实现掩模。

CGContextClipToMask这个方法,使用矩形裁剪区域与上下文相交,你可以提供下面的参数:

1. 你要裁剪的上下文

2.你要掩模的矩形框

3.CGImageMaskCreate 通过这个方法创建掩模。你需要提供一个图像替代图像掩模,图像掩模会实现相反的效果。图像必须被Quartz创建方法创建,但是它 不能是把图像或者遮盖颜色应用到另一个图像的结果。

裁剪区域取决于你提供的图象掩模或者通过CGContextClipToMask创建的图像。当你提供图像掩模时,你将会得到和Masking an Image with an Image Mask,描述里相同的效果,除了上下文被裁剪。当你提供一个图像,被裁剪的上下文和Masking an Image with an Image.描述的是类似的效果。

上图如果是作为图像掩模,通过方法CGImagMaskCreate创建,然后提供给CGContextclipToMask作为参数,允许绘制黑色 ,不允许绘制白色,灰色透明度为1-s,s 为样本值,然后调用方法CGContextDrawImage,你会得到和11-15乡土的结果。

如果 不是图像掩模,是图像,结果是相反的。如图:

Using Blend Modes with Images 使用图像混合模式

你可以使用Quartz 2D图像混合模式混合多个图片或者把一个图像覆盖在上下文中上。本节讨论合成图像覆盖在背景图。

合成图像背景的步骤如下:

1.绘制背景

2.CGContextSetBlendMode 调用这个方法选择合适模式。

3.绘制图像在背景上 通过调用CGContextDrawImage。

示例:

Normal Blend Mode:Quartz中默认的模式,当你当前使用的是其他模式,你可以明确设置为默认模式。有两种方式:传递常量kCGBlendModeNormal为正常模式给方法CGContextSetBlendMode,或者保存图形状态(假定之前的图形状态使用的是正常模式)使用CGContextRestoreGState
。图11-18中前景透明度为1.0,所以背景被完全覆盖。

Multiply Blend Mode:叠加的混合模式。最终的图像颜色和两个贡献者的黑色一样。调用方法CGContextSetBlendMode,传递常量kCGBlendModeMultiply,11-19展示了叠加模式,图片覆盖在矩形框上。

Screen Blend Mode:背景图与前景图的反转,颜色和两个贡献者的颜色一样轻。调用方法CGContextSetBlendMode,传递常量kCGBlendModeScreen。

Overlay Blend Mode:叠加混合模式或复合或过滤源图像样本使用背景图像样本,这取决于背景样本的颜色。结果是覆盖现有的图片样本,保留亮点和阴影背景。背景色与源图像混合,已反应背景的亮度和暗度。

Darken Blend Mode:变暗混合模式创建复合图像样本选择深色样品从源图像或背景。源图像样本,是比背景图像样本颜色较深的,取代了相应的背景样本。kCGBlendModeDarken

Lighten Blend Mode:减轻混合模式创建复合图像样本,通过选择较轻的样品从源图像或背景。源图像样本,是比背景图像样本更轻,取代了相应的背景样本。常量:kCGBlendModeLighten。

Color Dodge Blend Mode:色彩混合模式变亮背景图像样本反映源图像样本。指定黑色的源图像样本值保持不变。常量:kCGBlendModeColorDodge

Color Burn Blend Mode:色彩混合模式变暗背景图像样本反映源图像样本。指定白色保持不变的源图像样本值。常量:

Soft Light Blend Mode:柔光模式可以变暗或变亮的颜色,根据源图像样本的颜色。如果源图像样本的颜色比50%灰色亮,背景的淡化,类似于Color Dodge Blend Mode。如果源图像样本的颜色比50%灰色暗,背景变暗,类似Color Burn Blend Mode。如果源图像样本颜色等于50%灰度,背景不改变。常量:kCGBlendModeHardLight;

Difference Blend Mode:不同的混合模式的源图像中减去样品颜色从背景图像样本的颜色,或者相反,这取决于样品的亮度值更大。原图样式黑色的没有变化。常量:kCGBlendModeDifference

Exclusion Blend Mode:排除混合模式产生的差分混合模式的一个较低的Difference Blend Mode版本。常量:kCGBlendModeExclusion

Hue Blend Mode:调混合模式使用的背景的亮度和饱和度值的源图像的色调。常量:kCGBlendModeHue。

Saturation Blend Mode:饱和混合模式使用的是源图像的饱和度和背景的亮度。常量:kCGBlendModeSaturation。

Color Blend Mode:颜色混合模式使用源图像的饱和度和背景的亮度。这种模式保留了图像中的灰度级。常量:kCGBlendModeColor。

Luminosity Blend Mode:光度混合模式使用的是背景的饱和度和亮度和源图像的亮度达到一种和Color Blend Mode相反的效果。常量:kCGBlendModeLuminosity

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

推荐阅读更多精彩内容

  • 位图图像和图像蒙板就像Quartz中的任何图形图元。 Quartz中的图像和图像蒙板都由CGImageRef数据类...
    权宜平和阅读 1,655评论 0 3
  • 本文转载自:http://southpeak.github.io/2015/01/05/quartz2d-11/ ...
    idiot_lin阅读 905评论 1 1
  • 兔子看着像煤球一样的小奶猫,扯了扯长长的耳朵,用咬掉半截的胡萝卜碰了碰。 小奶猫紧闭着眼睛,丝毫没有反应。 “这么...
    浅呓七阅读 405评论 3 3
  • 1、 在我没有生娃前, 偶然知道汪培珽《喂故事书长大的孩子》,了解阅读对孩子的重要性,就坚持给外甥女买绘本。如今,...
    半朵花_c0b8阅读 187评论 1 2