两年前发表在简书的文章,迁移到优快云备份。原文链接:https://www.jianshu.com/p/2d6014b226d6
想要学习此效果需要掌握的技能有:
1.了解CALayer及自定义
2.了解CADisplayLink及其用法
3.了解CoreGraphics及相关API
核心思想就是:获取一张图片的每个像素的信息,然后生成相应个数的像素粒子,绘制在自定义的CALayer上,再使用CADisplayLink改变每个粒子的位置,并重新绘制,达到动画的效果。
一、获取图片元数据
根据CoreGraphics的相关API能获取到UIImage的元数据(rawData
),rawData
是个一维数组,里面存着每个像素点的RGBA数据,储存顺序为RGBARGBARGBA…分别是从第一行开始第一个像素的RGBA,第二个元素的RGBA……
根据CGImageGetWidth()
|CGImageGetHeight()
能得到以像素为单位的图片宽高,然后就可以用两个for循环得到所有像素点的位置和颜色信息了,然后再用自定义model保存起来。
- (NSArray*)getRGBAsFromImage:(UIImage*)image {
//1. get the image into your data buffer.
CGImageRef imageRef = [image CGImage];
NSUInteger imageW = CGImageGetWidth(imageRef);
NSUInteger imageH = CGImageGetHeight(imageRef);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
NSUInteger bytesPerPixel = 4; //一个像素4字节
NSUInteger bytesPerRow = bytesPerPixel * imageW;
unsigned char *rawData = (unsigned char*)calloc(imageH*imageW*bytesPerPixel, sizeof(unsigned char)); //元数据
NSUInteger bitsPerComponent = 8;
CGContextRef context = CGBitmapContextCreate(rawData, imageW, imageH, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast|kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colorSpace);
CGContextDrawImage(context, CGRectMake(0, 0, imageW, imageH), imageRef);
CGContextRelease(context);
//2. Now your rawData contains the image data in the RGBA8888 pixel format.
CGFloat addY = (_maxParticleCount == 0) ? 1 : (imageH/_maxParticleCount);
CGFloat addX = (_