您的位置:首页 > 移动开发 > IOS开发

iOS 2D绘图详解(Quartz 2D)之Bitmap

2015-11-03 13:53 561 查看
原创Blog,转载请注明出处

http://blog.csdn.net/hello_hwc?viewmode=list

我的stackoverflow





前五篇基础博客路径

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

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

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

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

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

什么是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 Bitmap Quartz2D