什么是Bitmap?
Bitmap叫做位图,每一个像素点由1-32bit组成。每个像素点包括多个颜色组件和一个Alpha组件(例:RGBA)。
iOS中指出如下格式的图片 JPEG, GIF, PNG, TIF, ICO, GMP, XBM,和 CUR。其他格式的图片要给Quartz2D传入图片的数据分布信息。
数据类型CGImageRef
在Quartz中,Bitmap的数据由CGImageRef封装。由以下几个函数可以创建CGImageRef对象
1 2 3 4 5
| CGImageCreate - 最灵活,但也是最复杂的一种方式,要传入11个参数,这个方法最后讲解。 CGImageSourceCreate-ImageAtIndex-通过已经存在的Image对象来创建 CGImageSourceCreate-ThumbnailAtIndex- 和上一个函数类似,不过这个是创建缩略图 CGBitmapContextCreateImage - 通过Copy Bitmap Graphics来创建 CGImageCreateWith-ImageInRect -通过在某一个矩形内数据来创建
|
在一个bitmap context绘制,并且重新生成一张图片
先看看一个方法,创建bitmap context- CGBitmapContextCreate
1 2 3 4 5 6 7 8 9
| CGContextRef _Nullable CGBitmapContextCreate ( void * _Nullable data, size_t width, size_t height, size_t bitsPerComponent, size_t bytesPerRow, CGColorSpaceRef _Nullable space, uint32_t bitmapInfo );
|
参数:
1 2 3 4 5 6
| * 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可以传入的参数如下,通过名字就能看出来,这里不加注释了
1 2 3 4 5 6 7 8 9 10
| enum CGImageAlphaInfo { kCGImageAlphaNone, kCGImageAlphaPremultipliedLast, kCGImageAlphaPremultipliedFirst, kCGImageAlphaLast, kCGImageAlphaFirst, kCGImageAlphaNoneSkipLast, kCGImageAlphaNoneSkipFirst, kCGImageAlphaOnly };
|
原图(1280*800)
效果
重新绘制成200*100,并在图片中间加上我们自定义的绘制
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| 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];
|
截取图片的一部分
效果
代码
1 2 3 4 5 6
| 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
这个方法
1 2 3 4 5 6 7 8 9 10 11 12 13
| 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 );
|
参数
1 2 3 4 5 6 7 8 9 10
| * 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,进行绘制
1 2 3
| UIGraphicsBeginImageContext UIGraphicsEndImageContext
|
通过一下方法来获取当前context就可以绘制了。
1
| UIGraphicsGetCurrentContext
|
然后通过,UIGraphicsGetImageFromCurrentImageContext来生成图片
例: 调整图片的大小
1 2 3 4 5 6 7 8 9 10
| + (UIImage*)imageWithImage:(UIImage*)image scaledToSize:(CGSize)newSize; { UIGraphicsBeginImageContext( newSize ); [image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)]; UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return newImage; }
|
例: 截屏
1 2 3 4 5 6
| UIWindow * keyWindow = [UIApplication sharedApplication].keyWindow; UIGraphicsBeginImageContextWithOptions(keyWindow.bounds.size, NO, [UIScreen mainScreen].scale); CGContextRef context = UIGraphicsGetCurrentContext(); [keyWindow.layer renderInContext:context]; UIImage * screenShot = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext();
|