应用一:给图片打水印,不应该是画到View的Layer上,而应该画到Bitmap上,产生一张新的图片。

1.首先读入背景图,然后开启一个位图上下文,并将它画在位图上下文上:

    UIImage *bgImage = [UIImage imageNamed:@"scene"];
/**
* 创建基于位图的上下文
*
* @param size#> 图片的尺寸 description#>
* @param opaque#> 是否不透明 YES为不透明、NO透明 description#>
* @param scale#> 伸缩尺寸,写0.0是按默认尺寸 description#>
*
* @return void
*
* 执行完毕后就相当于创建了一个新的UIImage,尺寸就是传入的size
*/
UIGraphicsBeginImageContextWithOptions(bgImage.size, NO, 0.0);
// 画背景
[bgImage drawInRect:CGRectMake(0, 0, bgImage.size.width, bgImage.size.height)];

2.接下来计算要打的水印的位置,并且进行尺寸的缩放:

    // 画右下角的水印
UIImage *waterImage = [UIImage imageNamed:@"logo"];
CGFloat scale = 0.2;
CGFloat margin = 5;
CGFloat waterW = waterImage.size.width * scale;
CGFloat waterH = waterImage.size.height * scale;
CGFloat waterX = bgImage.size.width - waterW - margin;
CGFloat waterY = bgImage.size.height - waterH - margin;
[waterImage drawInRect:CGRectMake(waterX, waterY, waterW, waterH)];

3.从上下文中取出画好的图片,然后结束上下文:

    // 从上下文中取得制作完毕的UIImage对象
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); // 结束上下文
UIGraphicsEndImageContext();

4.保存图片:转为二进制数据(压缩为JPEG或者PNG图片数据,JPEG可以选择压缩质量0-1,PNG默认最好的质量)。

JPEG:第二个参数为质量

UIImageJPEGRepresentation(<#UIImage *image#>, <#CGFloat compressionQuality#>)

PNG:只有一个参数

NSData *data = UIImagePNGRepresentation(newImage);

通过搜索的方式查找Documents文件夹的方法:注意找到的路径是个数组,iOS系统只有一个路径,因此使用lastObject就可以取到。

NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"文件名.拓展名"];

应用二:生成圆形头像图片。

先开启位图上下文,然后取得这个上下文(同以前一样)画一个圆,并且开启裁剪(先开启裁剪后面的才会收到裁剪的影响)。

为了产生一个白框,应该先画一个大圆,然后在期内画一个小圆,这时候执行裁剪,因为只有这后面的部分才会执行裁剪,因此就会出现一个大圆和小圆之间的环,一般取为白色。

    // 1.加载原图
UIImage *oldImage = [UIImage imageNamed:@"me"]; // 2.开启上下文
CGFloat borderW = 2; // 圆环的宽度
CGFloat imageW = oldImage.size.width + 2 * borderW;
CGFloat imageH = oldImage.size.height + 2 * borderW;
CGSize imageSize = CGSizeMake(imageW, imageH);
UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0.0); // 3.取得当前的上下文
CGContextRef ctx = UIGraphicsGetCurrentContext(); // 4.画边框(大圆)
[[UIColor whiteColor] set];
CGFloat bigRadius = imageW * 0.5; // 大圆半径
CGFloat centerX = bigRadius; // 圆心
CGFloat centerY = bigRadius;
CGContextAddArc(ctx, centerX, centerY, bigRadius, 0, M_PI * 2, 0);
CGContextFillPath(ctx); // 画圆 // 5.小圆
CGFloat smallRadius = bigRadius - borderW;
CGContextAddArc(ctx, centerX, centerY, smallRadius, 0, M_PI * 2, 0);
// 裁剪(后面画的东西才会受裁剪的影响)
CGContextClip(ctx); // 6.画图
[oldImage drawInRect:CGRectMake(borderW, borderW, oldImage.size.width, oldImage.size.height)]; // 7.取图
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); // 8.结束上下文
UIGraphicsEndImageContext(); // 9.显示图片
self.iconView.image = newImage; // 10.写出文件
NSData *data = UIImagePNGRepresentation(newImage);
NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"new.png"];
[data writeToFile:path atomically:YES];

应用三:屏幕截图

截图的原理:将View的layer渲染到上下文,然后取出图片保存。

一个细节:应该延迟截图,让按钮恢复非点击状态。

作为ImageView的一个功能,将屏幕截图作为分类扩充方法:注意从layer捕捉的方法

#import "UIImage+MJ.h"

@implementation UIImage (MJ)
+ (instancetype)captureWithView:(UIView *)view
{
// 1.开启上下文
UIGraphicsBeginImageContextWithOptions(view.frame.size, NO, 0.0); // 2.将控制器view的layer渲染到上下文
[view.layer renderInContext:UIGraphicsGetCurrentContext()]; // 3.取出图片
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); // 4.结束上下文
UIGraphicsEndImageContext(); return newImage;
}
@end

如果要存入系统相册,应该调用UIImageWriteToSavedPhotoAlbum方法,注意回调函数应该用官方建议的方法:

UIImageWriteToSavedPhotosAlbum(img, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);

回调函数的写法:

- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo
{
if (error) { // 保存失败
[MBProgressHUD showError:@"保存失败"];
} else { // 保存成功
[MBProgressHUD showSuccess:@"保存成功"];
}
}

应用四:背景平铺。

使用Quartz2D可以将一个小图片完全平铺到背景:注意到colorWithPatternImage可以设置背景图。

    UIImage *oldImage = [UIImage imageNamed:@"me"];
UIGraphicsBeginImageContextWithOptions(self.view.frame.size, NO, 0.0);
[oldImage drawInRect:self.view.bounds];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
self.view.backgroundColor = [UIColor colorWithPatternImage:newImage];

总结:

1.因为只有drawRect:方法中才能取出上下文,因此应该在这里绘图。

2.View内部有一个layer层,drawRect:方法获取的是view的layer,view显示全靠layer,view还有一个响应事件的作用。

3.产生图片的方法:

先开启图形上下文

UIGraphicsBeginImageContextWithOptions...

然后可以在需要绘图时按原来的方法获取上下文

然后取图:UIImage *newImage =UIGraphicsGetImageFromCurrentImageContext();

最后不要忘了结束上下文:UIGraphicsEndImageContext();

(五十)Quartz2D生成图片的一些应用的更多相关文章

  1. 第三百五十六天 how can I 坚持

    一年了,三百五十六天.写个算法算下对不对. 今天突然想买辆自行车了.云马智行车,还是捷安特,好想买一辆. 网好卡.貌似少记了一天呢,357了.好快. 睡觉了,还没锻炼呢,太晚了. 1458748800 ...

  2. 第三百五十五天 how can I 坚持

    快一年了,三百五十五天了,等写个程序算算时间,看看日期和天数能不能对的上,哈哈. 计划还是未制定,天气预报还是没有写完,立马行动,发完这个博客,立马行动. 计划:设计模式1个月,三大框架3个月,计算机 ...

  3. 【Visual C++】游戏开发五十六 浅墨DirectX教程二十三 打造游戏GUI界面(一)

    本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/16384009 作者:毛星云 ...

  4. Gradle 1.12用户指南翻译——第五十二章. Maven 插件

    本文由CSDN博客貌似掉线翻译,其他章节的翻译请参见:http://blog.csdn.net/column/details/gradle-translation.html翻译项目请关注Github上 ...

  5. Java进阶(五十二)利用LOG4J生成服务日志

    Java进阶(五十二)利用LOG4J生成服务日志 前言 由于论文写作需求,需要进行流程挖掘.前提是需要有真实的事件日志数据.真实的事件日志数据可以用来发现.监控和提升业务流程. 为了获得真实的事件日志 ...

  6. SQL注入之Sqli-labs系列第五十关,第五十一关,第五十二关,第五十三关(ORDER BY堆叠注入)

    0x1第五十关 源码中使用的mysqli_multi_query()函数,而之前使用的是mysqli_query(),区别在于mysqli_multi_query()可以执行多个sql语句,而mysq ...

  7. 热泪盈眶的五十岁 | James Altucher

    我是一名程序员,但我不爱看技术博客,因为要吸取知识点,看源代码.官方文档和书永远比看技术博客要好.对于博客这种偏碎片的媒介,我倾向于看一些短小精炼.有一点深度的叙述,Altucher刚好符我目前的品味 ...

  8. hdu 1290_献给杭电五十周年校庆的礼物

    Description 或许你曾经牢骚满腹或许你依然心怀忧伤或许你近在咫尺或许你我天各一方 对于每一个学子母校 永远航行在生命的海洋 今年是我们杭电建校五十周年,这是一个值得祝福的日子.我们该送给母校 ...

  9. 第三百五十九节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)介绍以及安装

    第三百五十九节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)介绍以及安装 elasticsearch(搜索引擎)介绍 ElasticSearch是一个基于 ...

  10. 第三百五十八节,Python分布式爬虫打造搜索引擎Scrapy精讲—将bloomfilter(布隆过滤器)集成到scrapy-redis中

    第三百五十八节,Python分布式爬虫打造搜索引擎Scrapy精讲—将bloomfilter(布隆过滤器)集成到scrapy-redis中,判断URL是否重复 布隆过滤器(Bloom Filter)详 ...

随机推荐

  1. Git 常用命令速查表(图文+表格)

    一. Git 常用命令速查 git branch 查看本地所有分支git status 查看当前状态 git commit 提交 git branch -a 查看所有的分支git branch -r ...

  2. Docker 网络

    Docker 的网络实现其实就是利用了 Linux 上的网络名字空间和虚拟网络设备(特别是 veth pair).建议先熟悉了解这两部分的基本概念再阅读本章. 基本原理 首先,要实现网络通信,机器需要 ...

  3. 毕业论文内容框架指导-适用于MIS系统

    摘要: 背景.要做什么.选用什么技术.按照什么过程.原理.或者步骤去做.最后做出了什么东西.做出来的东西有什么用. 1. 前言 系统的背景与意义:为什么要做这个系统 ? 现状调查:别人做的怎么样? 系 ...

  4. ngx.re.match使用示例

    s='...12ab345cde...' r, e = ngx.re.match(s,'(\\d+)([a-z]+)(?<num>\\d+)(?<word>[a-z]+)') ...

  5. pxe无人值守安装linux机器笔记

    最近做一些集群的测试的工作,做服务器测试最根本就是要安装系统,曾经我们用十几个光驱并行安装光驱的日子过去了,自从有了pxe一两天搭建好一个集群不是梦!当然做多了集群的搭建工作最多的感受就是,其实运维工 ...

  6. Programming In Scala笔记-第五章、Scala中的变量类型和操作

    这一章的一些基础性的东西,主要包括Scala中的基本变量类型,以及相关的一些操作符. 一.简单类型 下表中列出Scala语言中的基本类型,以及其字节长度,其中Byte, Short, Int, Lon ...

  7. N个鸡蛋放到M个篮子中

    N个鸡蛋放到M个篮子中,篮子不能为空,要满足:对任意不大于N的数量,能用若干个篮子中鸡蛋的和表示. 写出函数,对输入整数N和M,输出所有可能的鸡蛋的放法. 比如对于9个鸡蛋5个篮子 解至少有三组: 1 ...

  8. oracle伪列

    Oracle的伪列以及伪表 oracle系统为了实现完整的关系数据库功能,系统专门提供了一组成为伪列(Pseudocolumn)的数据库列,这些列不是在建立对象时由我们完成的,而是在我们建立时由Ora ...

  9. git中status指令总是提示内容被修改的解决

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 最近在用git提交项目修改时发现一个问题,就是多次 git a ...

  10. linux下的环境变量

    环境变量有时候要查找,但是经常忘记有哪些文件,现在做一个总结: /etc/profile                 此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行.并从/e ...