Bitmap

什么是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
);
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

参数

  • 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 
};
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

原图(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];
 
 
  • 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
  • 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

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

效果 

代码

    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];
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

看看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
);
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

参数

  • 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
 
 
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

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

UIGraphicsGetCurrentContext
 
 
  • 1
  • 1

然后通过,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;
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

截屏

   UIWindow * keyWindow = [UIApplication sharedApplication].keyWindow;
    UIGraphicsBeginImageContextWithOptions(keyWindow.bounds.size, NO, [UIScreen mainScreen].scale);
    CGContextRef context = UIGraphicsGetCurrentContext();
    [keyWindow.layer renderInContext:context];
    UIImage * screenShot = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值