什么是Bitmap?

Bitmap叫做位图,每一个像素点由1-32bit组成。每个像素点包括多个颜色组件和一个Alpha组件(例如:RGBA)。

iOS中指出如下格式的图片 JPEG, GIF, PNG, TIF, ICO, GMP, XBM,和 CUR。其他格式的图片要给Quartz2D传入图片的数据分布信息。


数据类型CGImageRef

在Quartz中,Bitmap的数据由CGImageRef封装。由以下几个函数可以创建CGImageRef对象

  • CGImageCreate - 最灵活,但也是最复杂的一种方式,要传入11个参数,这个方法最后讲解。
  • CGImageSourceCreate-ImageAtIndex-通过已经存在的Image对象来创建
  • CGImageSourceCreate-ThumbnailAtIndex- 和上一个函数类似,不过这个是创建缩略图
  • CGBitmapContextCreateImage - 通过Copy Bitmap Graphics来创建
  • CGImageCreateWith-ImageInRect -通过在某一个矩形内数据来创建

例子一,在一个bitmap context绘制,并且重新生成一张图片

先看看一个方法,创建bitmap context-CGBitmapContextCreate
函数体

CGContextRef _Nullable CGBitmapContextCreate (
void * _Nullable data,
size_t width,
size_t height,
size_t bitsPerComponent,
size_t bytesPerRow,
CGColorSpaceRef _Nullable space,
uint32_t bitmapInfo
);

参数

  • data 是一个指针,指向存储绘制的bitmap context的实际数据的地址,最少大小为bytesPerRow* height.可以传入null,让quartz自动分配计算
  • width/height bitmap的宽度,高度,以像素为单位
  • bytesPerRow 每一行的byte数目。如果data传入null,这里传入0,则会自动计算
  • 一个component占据多少位。对于32bit的RGBA空间,则是8(8*4=32)。
  • space 颜色空间,一般就是DeviceRGB
  • bitmapInfo,一个常量,指定了是否具有alpha通道,alpha通道的位置,像素点存储的数据类型是float还是Integer等信息。

其中bitmapInfo可以传入的参数如下,通过名字就能看出来,这里不加注释了

enum CGImageAlphaInfo {
kCGImageAlphaNone,
kCGImageAlphaPremultipliedLast,
kCGImageAlphaPremultipliedFirst,
kCGImageAlphaLast,
kCGImageAlphaFirst,
kCGImageAlphaNoneSkipLast,
kCGImageAlphaNoneSkipFirst,
kCGImageAlphaOnly
};

原图(1280*800)

效果

重新绘制成200*100,并在图片中间加上我们自定义的绘制

代码

    CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();
CGSize targetSize = CGSizeMake(200, 100);
CGContextRef bitmapContext = CGBitmapContextCreate(NULL,
targetSize.width,
targetSize.height,
8,
targetSize.width * 4,
rgb,
kCGImageAlphaPremultipliedFirst);
CGRect imageRect;
imageRect.origin = CGPointMake(0, 0);
imageRect.size = targetSize;
UIImage * imageToDraw = [UIImage imageNamed:@"image.jpg"];
CGContextDrawImage(bitmapContext,imageRect,imageToDraw.CGImage);
CGContextAddArc(bitmapContext,100,40, 20,M_PI_4, M_PI_2, true);
CGContextSetLineWidth(bitmapContext, 4.0);
CGContextStrokePath(bitmapContext); CGImageRef imageRef = CGBitmapContextCreateImage(bitmapContext);
UIImage * image = [[UIImage alloc] initWithCGImage:imageRef]; CGImageRelease(imageRef);
CGContextRelease(bitmapContext);
CGColorSpaceRelease(rgb); UIImageView * imageView = [[UIImageView alloc] initWithImage:image];
imageView.center = self.view.center;
[self.view addSubview:imageView];

例子二,截取图片的一部分

效果

代码

    UIImage * imageToDraw = [UIImage imageNamed:@"image.jpg"];
CGImageRef partImageRef = CGImageCreateWithImageInRect(imageToDraw.CGImage, CGRectMake(0, 0,300, 200));
UIImage * partImage = [[UIImage alloc] initWithCGImage:partImageRef];
UIImageView * imageView = [[UIImageView alloc] initWithImage:partImage];
imageView.center = self.view.center;
[self.view addSubview:imageView];

看看CGImageCreate这个方法

CGImageRef _Nullable CGImageCreate (
size_t width,
size_t height,
size_t bitsPerComponent,
size_t bitsPerPixel,
size_t bytesPerRow,
CGColorSpaceRef _Nullable space,
CGBitmapInfo bitmapInfo,
CGDataProviderRef _Nullable provider,
const CGFloat * _Nullable decode,
bool shouldInterpolate,
CGColorRenderingIntent intent
);

参数

  • width/height 图片的像素宽度,高度
  • bitsPerComponent 每个component的占用bit个数,和上文提到的一样
  • bitsPerPixel 每个像素点占用的bit个数。例如32bit RGBA中,就是32
  • bytesPerRow 每一行占用的byte个数
  • colorspace 颜色空间
  • bitmapInfo 和上文提到的那个函数一样
  • provider bitmap的数据源
  • decode 解码array,传入null,则保持原始数据
  • interpolation 是否要像素差值来平滑图像
  • intent 指定了从一个颜色空间map到另一个颜色空间的方式

UIKit中的Bitmap

成对使用来创建bitmap context,进行绘制

UIGraphicsBeginImageContext

UIGraphicsEndImageContext

通过一下方法来获取当前context就可以绘制了。

UIGraphicsGetCurrentContext

然后通过,UIGraphicsGetImageFromCurrentImageContext来生成图片

例如
调整图片的大小

+ (UIImage*)imageWithImage:(UIImage*)image
scaledToSize:(CGSize)newSize;
{
UIGraphicsBeginImageContext( newSize );
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext(); return newImage;
}

截屏

   UIWindow * keyWindow = [UIApplication sharedApplication].keyWindow;
UIGraphicsBeginImageContextWithOptions(keyWindow.bounds.size, NO, [UIScreen mainScreen].scale);
CGContextRef context = UIGraphicsGetCurrentContext();
[keyWindow.layer renderInContext:context];
UIImage * screenShot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

iOS 2D绘图详解(Quartz 2D)之Bitmap的更多相关文章

  1. iOS 2D绘图详解(Quartz 2D)之路径(点,直线,虚线,曲线,圆弧,椭圆,矩形)

    前言:一个路径可以包含由一个或者多个shape以及子路径subpath,quartz提供了很多方便的shape可以直接调用.例如:point,line,Arc(圆弧),Curves(曲线),Ellip ...

  2. iOS 2D绘图详解(Quartz 2D)之概述

    前言:最近在研究自定义控件,由于想要彻底的定制控件的视图还是要继承UIView,虽然对CALayer及其子类很熟练,但是对Quartz 2D这个强大的框架仍然概念模棱两可.于是,决定学习下,暂定7篇文 ...

  3. iOS 2D绘图详解(Quartz 2D)之阴影和渐变(Shadow,Gradient)

    前言:这个系列写道这里已经是第五篇了,本文会介绍下阴影和渐变的基础知识,以及一些基本的Demo Code展示,应该还会有两篇,介绍下Bitmap绘制以及Pattern等知识. Shadow shado ...

  4. iOS开发 绘图详解

    Quartz概述 Quartz是Mac OS X的Darwin核心之上的绘图层,有时候也认为是CoreGraphics.共有两种部分组成   Quartz Compositor,合成视窗系统,管理和合 ...

  5. iOS 2D绘图详解(Quartz 2D)之Transform(CTM,Translate,Rotate,Scale)

    前言:Quartz默认采用设备无关的user space来进行绘图,当context(画板)建立之后,默认的坐标系原点以及方向也就确认了,可以通过CTM(current transformation ...

  6. iOS 2D绘图详解(Quartz 2D)之路径(stroke,fill,clip,subpath,blend)

    Stroke-描边 影响描边的因素 线的宽度-CGContextSetLineWidth 交叉线的处理方式-CGContextSetLineJoin 线顶端的处理方式-CGContextSetLine ...

  7. iOS中-Qutarz2D详解及使用

    在iOS中Qutarz2D 详解及使用 (一)初识 介绍 Quartz 2D是二维绘图引擎. 能完成的工作有: 绘制图形 : 线条\三角形\矩形\圆\弧等 绘制文字 绘制\生成图片(图像) 读取\生成 ...

  8. 【转】Android Canvas绘图详解(图文)

    转自:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2012/1212/703.html Android Canvas绘图详解(图文) 泡 ...

  9. 转载]IOS LBS功能详解[0](获取经纬度)[1](获取当前地理位置文本 )

    原文地址:IOS LBS功能详解[0](获取经纬度)[1](获取当前地理位置文本作者:佐佐木小次郎 因为最近项目上要用有关LBS的功能.于是我便做一下预研. 一般说来LBS功能一般分为两块:一块是地理 ...

随机推荐

  1. strtok和strtok_r

    1.strtok()函数的用法 函数原型:char *strtok(char *s, const char *delim); Function:分解字符串为一组字符串.s为要分解的字符串,delim为 ...

  2. web前端笔试题

    1, 判断字符串是否是这样组成的,第一个必须是字母,后面可以是字母.数字.下划线,总长度为5-20 var reg = /^[a-zA-Z][a-zA-Z_0-9]{4,19}$/; reg.test ...

  3. gcc命令行详解

    介绍] ----------------------------------------- 常见用法: GCC 选项 GCC 有超过100个的编译选项可用. 这些选项中的许多你可能永远都不会用到, 但 ...

  4. MyEclipse10导入工程jsp报错问题

    好多时候,再用myecplise进行项目开发的时候,遇到导入工程的时候,工程内的jsp页面好多都报错.这是什么原因造成的呢?​ 我对于我遇到的问题及解决方法,跟大家分享一下.​ 我的Jsp页面报错的原 ...

  5. 徐汉彬:亿级Web系统搭建——单机到分布式集群(转载)

    文章转载自http://www.csdn.net/article/2014-11-06/2822529/1 当一个Web系统从日访问量10万逐步增长到1000万,甚至超过1亿的过程中,Web系统承受的 ...

  6. iOS9对SDK的影响(iOS9适配必看)

      1.大部分社交平台接口不支持https协议. 问题描述:在iOS9下,系统默认会拦截对http协议接口的访问,因此无法获取http协议接口的数据.对ShareSDK来说,具体表现可能是,无法授权. ...

  7. c# 运行时替换某文件源代码(将XML 转换成 某个枚举并写入源文件)

    var sr = new StreamReader(Server.MapPath("~/WEB-INF/rule.config")); XmlDocument doc = new ...

  8. 2010“架构师接龙”问答--杨卫华VS赵劼(转)

    add by zhj:虽然是几年前的文章,但还是很有参考价值的 原文:http://blog.zhaojie.me/2010/05/programmer-magazine-2010-5-archite ...

  9. c#通过操作mongodb gridfs实现文件的数据库存储

    @(编程) 源码 using MongoDB.Driver; using MongoDB.Driver.GridFS; using System.IO; namespace Wisdombud.Mon ...

  10. 闲置的eSATA接口,会影响Windows 7的启动速度

      为方便用户连接外置硬盘等设备,很多中高 端主板上都有至少一个eSATA接口.事实上,很多人可能根本就不用eSATA接口,你想过没有,正是这个无所事事的eSATA接口,可能无意中就拖慢了 你的Win ...