在OpenGL中对于大长腿的实现相当于对图片部分区域做拉伸,然后缓存成在帧缓冲区作为下一次操作的原始图片,从而达到多重修改的目的,而真正的原图本身没有发生改变。
现在来一步步分析:
第一步初始化基本组件;
第二步是区域划分,顶点坐标和纹理坐标的对应,下一次绘制都是需要重新对应;
第三步拉伸和显示 baseEffect做图像处理后的展示;
第四步图片获取存取(顶点坐标和纹理坐标->GLSL绘制图片->帧缓冲区->纹理/新图片 滤镜链)当次处理的结果,作为下一次处理的原始图片;
重点方法解析:
GLuintframeBuffer;
GLuinttexture;
glGenFramebuffers(1, &frameBuffer);//glGenFramebuffers 生成帧缓存区对象名称;
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);//glBindFramebuffer 绑定一个帧缓存区对象;
glFramebufferTexture2D 纹理图片加载帧缓存区
生成帧缓冲区后保存临时的纹理对象/帧缓存区对象;
self.tmpTexture= texture;
self.tmpFrameBuffer= frameBuffer;
从帧缓冲区中获取图片
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);//读取像素
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, buffer, size, NULL);//使用data和size 数组来访问buffer数据
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();//颜色空间格式;
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;//位图图形的组件信息 - 默认的
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;//颜色映射
CGImageRefimageRef =CGImageCreate(width, height, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider,NULL,NO, renderingIntent);//将帧缓存区里像素点绘制到一张图片上
//. 此时的 imageRef 是上下颠倒的,调用 CG 的方法重新绘制一遍,刚好翻转过来
UIGraphicsBeginImageContext(CGSizeMake(width, height)); //创建一个图片context
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextDrawImage(context,CGRectMake(0,0, width, height), imageRef);//将图片绘制上去
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();//从context中获取图片
UIGraphicsEndImageContext(); //结束图片context处理
UIImageWriteToSavedPhotosAlbum(image,self,@selector(image:didFinishSavingWithError:contextInfo:),nil);//保存图片