About Bitmap Images and Image Masks
  bitmap image是一系列的像素,这些像素中的每一个代表了图片中的一个点。bitmap image可以是JPEG TIFF PNG,GIF,ICO,GMP,CUR等格式。
  image mask是一个用于表征哪个部分需要画出。image mask就像是用于表征色彩放在页面的哪一部分(where to place color on the page.)
Creating Images
  创建CGImageRef类型的对象的函数有很多:
  1、CGImageCreate:
  2、CGImageSourceCreateImageAtIndex:与CGImageSourceCreateWithURL连用
  3、CGImageSourceCreateThumbnilAtIndex:与上同
  4、CGBitmapContextCreateImage:获取被画在context中的图形,构成一个图片
  5、CGImageCreateWithImageInRect:截取小图片(规则截取)
Masking Images
  mask技术通过控制另一个图片的那一部分被显示,产生出有意思的效果。
  mask的方法有一下几种:
  1、通过image mask
  2、通过image
  3、通过context
  4、通过color
Masking an Image with an Image Mask
  前提要求:
      作为mask的图片,颜色的组成为黑白两色的。黑色部分最终体现为被mask图片的显示的部分,白色部分不显示。两个图片最好都是png格式的。
  步骤:
  1、创建image mask
     通过函数CGImageMaskCreate创建一个CGImageRef的数据mask
  2、通过上一步创建的mask,与另一张图片(source)结合创建一个新的图片masked
     通过函数CGImageCreateWithMask,参数为上述两个CGImageRef的图片,返回值为masked
  3、masked既是最终需要的。可以通过CGContextDrawImage画在屏幕上。也可以通过转化为NSData类型的数据data,调用[data writeToFile@"" aumatically:YES]写入一个文件。
  注意:如果想让不显示的部分真正的是透明的,需要将context所处的View的opaqe设置为NO,既是把view设置为透明。


如上面三幅图所示:分别为原图片(source),提供mask的图片(mask),结果(masked)。
  代码:

-(CGImageRef) CopyImageAndAddAlphaChannel :(CGImageRef) sourceImage
{CGImageRef retVal = NULL;size_t width = CGImageGetWidth(sourceImage);size_t height = CGImageGetHeight(sourceImage);CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();CGContextRef offscreenContext = CGBitmapContextCreate(NULL, width, height,8, 0, colorSpace, kCGImageAlphaPremultipliedLast);if (offscreenContext != NULL) {CGContextDrawImage(offscreenContext, CGRectMake(0, 0, width, height), sourceImage);retVal = CGBitmapContextCreateImage(offscreenContext);CGContextRelease(offscreenContext);}CGColorSpaceRelease(colorSpace);return retVal;
}- (UIImage*)maskImage:(UIImage *)image withMask:(UIImage *)maskImage {CGImageRef maskRef = maskImage.CGImage;CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),CGImageGetHeight(maskRef),CGImageGetBitsPerComponent(maskRef),CGImageGetBitsPerPixel(maskRef),CGImageGetBytesPerRow(maskRef),CGImageGetDataProvider(maskRef), NULL, false);CGImageRef sourceImage = [image CGImage];CGImageRef imageWithAlpha = sourceImage;//add alpha channel for images that don’t have one (ie GIF, JPEG, etc…)//this however has a computational costif (CGImageGetAlphaInfo(sourceImage) == kCGImageAlphaNone) {imageWithAlpha = [self CopyImageAndAddAlphaChannel :sourceImage];}CGImageRef masked = CGImageCreateWithMask(imageWithAlpha, mask);CGImageRelease(mask);//release imageWithAlpha if it was created by CopyImageAndAddAlphaChannelif (sourceImage != imageWithAlpha) {CGImageRelease(imageWithAlpha);}UIImage* retImage = [UIImage imageWithCGImage:masked];CGImageRelease(masked);return retImage;
}

希望大家注意下CopyImageAndAddAlphaChan nel函数中的,CGBitmapContextCreate函数的最后一个参数,这里我用的是kCGImageAlphaPremultipli edLast。
Masking an Image with an Image
 
 通过image进行mask,这一部分我没有用代码实际的去尝试,大家有兴趣可以试试。
Masking an image with Color
   该项技术主要是想通过提供一个color的阈值,对图片进行mask。达到的效果如下图所示:

   实现这种效果的方法是CGImageCreateWithMasking Colors,参数为CGImageRef和float的color数组。
   针对这个color数组格式如下:{min[1],max[1],min[2],max[2],min[3],max[3]···min[n],max[n]},其中的n表示的是当前的color space的元素的个数,比如当前采用rgb三原色,则n=3。
   该方法实现的过程大致表述如下:对图片的任何一个像素点,他的color是c[1],c[2],c[3],c[n],如果满足min[i]< c[i] <max[i]对所有的0到n成立,则这个像素点不被显示。
   特别注意:
   1、原图片(source)的格式应该是没有alpha通道的,如果提供的是png,由于png貌似都是有alpha的,需要先将png转化为jpeg,之后再通过maskwithcolor实现mask
   2、color数组的格式和取值范围是0到255
代码:

- (UIImage *)maskImage:(UIImage *)image withColor:(float *)color
{CGImageRef sourceImage = image.CGImage;CGImageAlphaInfo info = CGImageGetAlphaInfo(sourceImage);   if (info != kCGImageAlphaNone) {NSData *buffer = UIImageJPEGRepresentation(image, 1);UIImage *newImage = [UIImage imageWithData:buffer];sourceImage = newImage.CGImage;}CGImageRef masked = CGImageCreateWithMaskingColors(sourceImage, color);UIImage *retImage = [UIImage imageWithCGImage:masked];  CGImageRelease(masked);return retImage;
}

这部分我是这样实现的,在view中实现touch,在touch begain的时候获取该点的rgb,touch end的时候获取该点的rgb,之后clip to colors。效果如下:

Masking an Image by Clipping the Context
   这种技术的手段是通过将context clip,这样所有画在这个context的图片,就相应的被mask了。
   采用的函数是CGContextClipToMask,这里还是需要给它提供一个通过CGImageMaskCreate创建的mask。将source图片通过CGContextDrawImage之后,通过CGBitmapContextCreateIma ge获取对应的masked。
   当然这里还可以通过与path的知识结合,通过调用CGContextClip,实现画哪里clip哪里。
代码:

- (void)clipContext:(CGContextRef)context withMask:(UIImage *)maskImage
{CGImageRef maskRef = maskImage.CGImage;CGImageRef masked = CGImageMaskCreate(CGImageGetWidth(maskRef),CGImageGetHeight(maskRef),CGImageGetBitsPerComponent(maskRef),CGImageGetBitsPerPixel(maskRef),CGImageGetBytesPerRow(maskRef),CGImageGetDataProvider(maskRef), NULL, false);CGContextClipToMask(context, CGRectMake(0, 0, 768, 1024), masked);CGImageRelease(masked);
}

针对第二种clip path的,我实现的效果:(左边是source,右边是masked)

另外,最后指出一点,UIImage的drawRect函数仅仅在第一次加载的时候被调用一次,之后如果在view里面添加了东西,需要刷新的时候需要调用setNeedsDisplay函数。

Bitmap image and image mask相关推荐

  1. duilib入门问题集

    引入duilib时请确保引入头文件开始时先引入COMUTIL.H头文件 #include "COMUTIL.H" #include "UIlib.h" duil ...

  2. linux内核源码剖析 博客,【Linux内存源码分析】页面迁移

    页面迁移其实是伙伴管理算法中的一部分,鉴于其特殊性,特地另行分析.它是2007年的时候,2.6.24内核版本开发时,新增碎片减少策略(the fragmentation reduction strat ...

  3. linux内核那些事之buddy(anti-fragment机制)(4)

    程序运行过程中,有些内存是短暂的驻留 用完一段时间之后就可以将内存释放以供后面再次使用,但是有些内存一旦申请之后,会长期使用而得不到释放.长久运行有可能造成碎片.以<professional l ...

  4. java登录界面圆形头像_自定义圆形头像

    在很多应用中,我们看到,个人主页里面的头像一般都是圆的,设计成圆的会使整个界面布局变的优雅漂亮.那么,怎么使头像变圆呢?有的人说可以在上面加一个中间为透明圆形的png图,用它来遮盖住头像不就行了嘛,但 ...

  5. duilib之源码分析

    Duilib入门教程 http://www.cnblogs.com/Alberl/p/3342030.html http://blog.csdn.net/wogel/article/details/9 ...

  6. 深入理解GO语言:GC原理及源码分析

    Go 中的runtime 类似 Java的虚拟机,它负责管理包括内存分配.垃圾回收.栈处理.goroutine.channel.切片(slice).map 和反射(reflection)等.Go 的可 ...

  7. android 头像球_【Android 界面效果44】Android之圆头像实例

    在很多应用中,我们看到,个人主页里面的头像一般都是圆的,设计成圆的会使整个界 面布 局变的优雅漂亮.那么,怎么使头像变圆呢?有的人说可以在上面加一个中间为透明圆形的png图,用它来遮盖住头像不就行了嘛 ...

  8. Android:圆形头像

    http://blog.csdn.net/doublefi123/article/details/8795282 在很多应用中,我们看到,个人主页里面的头像一般都是圆的,设计成圆的会使整个界面布局变的 ...

  9. Virtualbox源码分析4:VMM虚拟化实现源码分析1

    文章目录 Virtualbox源码分析4:VMM虚拟化框架实现源码分析 4.1 VMX原理 4.1.1 VMX的状态转化: 4.1.2 VMCS 4.1.3 VMExit:VMX异常 Virtualb ...

最新文章

  1. mysql主从复制(master-slave)_mysql主从复制------Master-Slave搭建及注意事项
  2. 【Java Web开发指南】解析Spring中Ioc和DI(入门Demo)
  3. 方程组c语言编程,最小二乘解方程组C语言编程.doc
  4. 在Init之前究竟执行了什么?
  5. [css] css中兼容ie浏览器的前缀是什么?
  6. bzoj1269 文本编辑器 splay
  7. 怎样测量地图上曲线的长度_测量长度的特殊方法
  8. 夏令时 DST (Daylight Saving Time) java中的夏令时。
  9. 蠕虫Sexy View短信攻击诺基亚3250等手机
  10. C语言字符型数据scanf,scanf()函数如何输入字符型数据?
  11. android 选择 播放器,Android 播放--播放器里面 demo 类的说明与选择
  12. Vue仿微信朋友圈项目
  13. 使用PS蒙版功能去水印以及Word中的图片合并功能合并公司Logo图片
  14. 一枚钻戒如何成功借势世界杯,与粉丝秀恩爱
  15. ​携程网全国各城市酒店数据​评论数据
  16. Activiti6 流程模型图中文显示为方块□□
  17. 知道邻边和斜边求角度_知道一个角度和一条对边怎样求斜边和邻边
  18. Django使用旧有的数据库
  19. Educational Codeforces Round 88 (Rated for Div. 2) C. Mixing Water (思维,数学)
  20. 【Python爬虫】爬取云班课资源,活动

热门文章

  1. 什么是跳板机(堡垒机)
  2. 开发工具-Docker学习
  3. 怎样查看linux时间,如何在Linux中查看你的时区
  4. 【Unity 2D AABB碰撞检测】铸梦之路
  5. java二维数组怎么看_java、二维数组详解!
  6. C3P0数据库连接池的解析
  7. 太极拳“根”的技术之研究
  8. 计算机机房双电源供电,计算机机房供电系统的优化(论文).doc
  9. 端到端安全能力,态势感知抵御潜在风险
  10. ubuntu查看内存占用