博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS 2D绘图详解(Quartz 2D)之Bitmap
阅读量:4346 次
发布时间:2019-06-07

本文共 4442 字,大约阅读时间需要 14 分钟。

什么是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,进行绘制

UIGraphicsBeginImageContextUIGraphicsEndImageContext

通过一下方法来获取当前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();

转载于:https://www.cnblogs.com/Free-Thinker/p/5949014.html

你可能感兴趣的文章
34 帧动画
查看>>
二次剩余及欧拉准则
查看>>
thymeleaf 自定义标签
查看>>
关于WordCount的作业
查看>>
UIView的layoutSubviews,initWithFrame,initWithCoder方法
查看>>
STM32+IAP方案 实现网络升级应用固件
查看>>
用74HC165读8个按键状态
查看>>
jpg转bmp(使用libjpeg)
查看>>
linear-gradient常用实现效果
查看>>
sql语言的一大类 DML 数据的操纵语言
查看>>
VMware黑屏解决方法
查看>>
JAVA 基础 / 第八课:面向对象 / JAVA类的方法与实例方法
查看>>
Thrift源码分析(二)-- 协议和编解码
查看>>
考勤系统之计算工作小时数
查看>>
4.1 分解条件式
查看>>
关于C++ const成员的一些细节
查看>>
《代码大全》学习摘要(五)软件构建中的设计(下)
查看>>
C#检测驱动是否安装的问题
查看>>
web-4. 装饰页面的图像
查看>>
微信测试账户
查看>>