美文网首页
OpenGL ES 、UIKit坐标系

OpenGL ES 、UIKit坐标系

作者: 似奔跑的野马 | 来源:发表于2018-06-24 22:09 被阅读0次

在iOS开发中,会接触不同的绘制框架。Core Graphics、Quartz、以及更底层的OpenGL ES。

坐标系

UIKit坐标系是原点位于左上角,y轴向下。
Core Graphics 和Quartz 原点位于左下角,y轴向上。
OpenGL ES坐标系原点位于中心,y轴向上。

在使用Core Graphics 绘制时,需要翻转坐标系。注意后面的矩阵(缩放矩阵)先生效。

CGContextTranslateCTM(context, 0, height);
CGContextScaleCTM(context, 1.0, -1.0);
CGContextDrawImage(context, CGRectMake(0, 0, width, height), uiImage.CGImage);

OpenGL ES中通过照片创建纹理,然后展示到屏幕时,需要翻转照片。

    UIImage *image = [UIImage imageNamed:@"scene.jpg"];
    CGImageRef imageRef = image.CGImage;
    size_t width = CGImageGetWidth(imageRef);
    size_t height = CGImageGetHeight(imageRef);
    
    GLubyte *bytes = (GLubyte *)malloc(width * height * 4);
    CGColorSpaceRef color = CGColorSpaceCreateDeviceRGB();
    CGContextRef context =  CGBitmapContextCreate(bytes, width, height, 8, width * 4, color, kCGImageAlphaPremultipliedLast);
   //翻转坐标系
    CGContextTranslateCTM(context, 0, height);
    CGContextScaleCTM(context, 1.0, -1.0);
    CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
    CGColorSpaceRelease(color);
    if(imageRef) {
        CFRelease(imageRef);
    }

通过bytes创建纹理,然后通过OpenGL ES的颜色缓存渲染到屏幕时,照片才能正常显示。
Core Graphics 是以左上角为原点,y轴向下的方式保存照片的。OpenGL ES是Y轴向上的。绘制的时候,会将照片数据的原点放到左下角,因此需要翻转坐标系。

OpenGL ES 获取图像数据

直接从帧缓存读取颜色数据,核心glReadPixel函数。

- (void)readPixel
{
    NSInteger width = self.frame.size.width * [UIScreen mainScreen].scale;;
    NSInteger height = self.frame.size.height * [UIScreen mainScreen].scale;;
    GLvoid *pixels = malloc(width * height * 4);
    glBindRenderbuffer(GL_RENDERBUFFER, _colorRenderBuffer);
    //刷新,保证不是展示缓存,也可以获取颜色数据
    glFlush();
    
    glReadPixels(0, 0, (int)width, (int)height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
    
    CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, pixels, width * height * 4, NULL);
    CGBitmapInfo bitmapInfo = kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast;
    CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
    
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGImageRef imageRef =  CGImageCreate(width, height, 8, 8 * 4, width * 4, colorSpace, bitmapInfo, provider, NULL, NO, renderingIntent);
    //此处的照片数据是y轴翻转的,需要翻转y轴
    UIImage *tempImage = [UIImage imageWithCGImage:imageRef];
    CGColorSpaceRelease(colorSpace);
    CGDataProviderRelease(provider);
    
    //此处的size是以点为单位,如果获取的是像素需要 通过 w / [UIScreen mainScreen].scale
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(width, height), YES, [UIScreen mainScreen].scale);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
    //获取最终的照片
    UIImage *flipImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    if(imageRef) {
        CFRelease(imageRef);
    }
    free(pixels);
}

总结

  • CGImageCreate·创建照片的速度比较快,底层不会复制照片数据。
  • CGBitmapContextCreate会复制照片数据。
    GLubyte *bytes = (GLubyte *)malloc(width * height * 4);
    CGColorSpaceRef color = CGColorSpaceCreateDeviceRGB();
    CGContextRef context =  CGBitmapContextCreate(bytes, width, 
  height, 8, width * 4, color, kCGImageAlphaPremultipliedLast);

具体使用哪个根据情况,如果需要复制,获取直接对照片数据进行其他操作,则使用CGBitmapContextCreate

相关文章

网友评论

      本文标题:OpenGL ES 、UIKit坐标系

      本文链接:https://www.haomeiwen.com/subject/qjisyftx.html