图片解码常见的图片压缩格局次要是PNG和JPEG,在iOS的程序开发中,个别不须要获取一张图片解码后的数据,但如果须要对像素进行操作,可能就须要理解怎么获取相干的像素值。位图图像(bitmap),是由多个像素点排列组成的。当咱们对PNG和JPG进行解码后,应该获取到一组像素点数据,这样一组数据就组成了解码后的位图。图片解码能够看做一次解压缩,所以位图占用的空间会更大,位图所占的空间很好计算,图片的面积*每个像素占用的字节。+ (nullable UIImage *)imageWithContentsOfFile:(NSString *)path;
通常会应用 imageWithContentsOfFile 来加载一张图片,这样创立 UIImage 时并不会在这里进行解码, 当 UIImage 被绘制时才会解码。
CGImageCGImage 的解释是位图或者图片蒙版,也就是说能够通过 CGImage 来读取像素值。当间接对 CGImage 的像素读取时能够应用上面的形式。
NSData *imageData = [NSData dataWithContentsOfFile:imagePath];CFDataRef dataRef = (__bridge CFDataRef)imageData;CGImageSourceRef source = CGImageSourceCreateWithData(dataRef, nil);CGImageRef cgImage = CGImageSourceCreateImageAtIndex(source, 0, nil);width = (int)CGImageGetWidth(cgImage);height = (int)CGImageGetHeight(cgImage);size_t pixelCount = width * height;CGDataProviderRef provider = CGImageGetDataProvider(cgImage);CFDataRef data = CGDataProviderCopyData(provider);CFRelease(data);CGImageRelease(cgImage); CFRelease(source);这种读取像素的形式无奈指定色彩格局,而是读取图片原有的色彩空间所组成像素的组合。须要留神的是,所有创立进去的数据都须要调用相应的release来进行开释。这里创立 CGImage 的办法也能够对 CGImage 的缓存形式进行设置。而且当咱们从 CGImage 的 dataProvider 中获取数据时,目前只能拷贝一份到 CFDataRef 中,而无奈间接读取。
CGBitmapContext以 RGB 色彩空间为例, 色彩相干的数据可能有以上这么多,CGImage 有相干的办法能够读取相应的数据,但有些办法iOS12之后才反对。
typedef CF_ENUM(uint32_t, CGImageAlphaInfo) { kCGImageAlphaNone, /* For example, RGB. */ kCGImageAlphaPremultipliedLast, /* For example, premultiplied RGBA */ kCGImageAlphaPremultipliedFirst, /* For example, premultiplied ARGB */ kCGImageAlphaLast, /* For example, non-premultiplied RGBA */ kCGImageAlphaFirst, /* For example, non-premultiplied ARGB */ kCGImageAlphaNoneSkipLast, /* For example, RBGX. */ kCGImageAlphaNoneSkipFirst, /* For example, XRGB. */ kCGImageAlphaOnly /* No color data, alpha data only */};typedef CF_ENUM(uint32_t, CGImageByteOrderInfo) { kCGImageByteOrderMask = 0x7000, kCGImageByteOrderDefault = (0 << 12), kCGImageByteOrder16Little = (1 << 12), kCGImageByteOrder32Little = (2 << 12), kCGImageByteOrder16Big = (3 << 12), kCGImageByteOrder32Big = (4 << 12)} CG_AVAILABLE_STARTING(10.0, 2.0);typedef CF_ENUM(uint32_t, CGImagePixelFormatInfo) { kCGImagePixelFormatMask = 0xF0000, kCGImagePixelFormatPacked = (0 << 16), kCGImagePixelFormatRGB555 = (1 << 16), /* Only for RGB 16 bits per pixel */ kCGImagePixelFormatRGB565 = (2 << 16), /* Only for RGB 16 bits per pixel */ kCGImagePixelFormatRGB101010 = (3 << 16), /* Only for RGB 32 bits per pixel */ kCGImagePixelFormatRGBCIF10 = (4 << 16), /* Only for RGB 32 bits per pixel */} CG_AVAILABLE_STARTING(10.14, 12.0);typedef CF_OPTIONS(uint32_t, CGBitmapInfo) { kCGBitmapAlphaInfoMask = 0x1F, kCGBitmapFloatInfoMask = 0xF00, kCGBitmapFloatComponents = (1 << 8), kCGBitmapByteOrderMask = kCGImageByteOrderMask, kCGBitmapByteOrderDefault = kCGImageByteOrderDefault, kCGBitmapByteOrder16Little = kCGImageByteOrder16Little, kCGBitmapByteOrder32Little = kCGImageByteOrder32Little, kCGBitmapByteOrder16Big = kCGImageByteOrder16Big, kCGBitmapByteOrder32Big = kCGImageByteOrder32Big} CG_AVAILABLE_STARTING(10.0, 2.0);#ifdef __BIG_ENDIAN__# define kCGBitmapByteOrder16Host kCGBitmapByteOrder16Big# define kCGBitmapByteOrder32Host kCGBitmapByteOrder32Big#else /* Little endian. */# define kCGBitmapByteOrder16Host kCGBitmapByteOrder16Little# define kCGBitmapByteOrder32Host kCGBitmapByteOrder32Little#endif图片中单个像素的组成依据色彩空间,排列,以及占位有很多排列组合的形式,所以为了防止解决过多的状况,可能应用 CGBitmapContext 是一种对使用者来说比拟敌对的形式。CGBitmapContext 能够用来把位图按位画进内存的画布。画布上每个像素点都是依照 CGBitmapContext 中指定的色彩空间来排布的。在 CGBitmapContext 创立时,须要传入一些参数来指定咱们须要的画布是什么样的。
...