• iphone CGBitmapContextCreate()函数解释


    http://blog.sina.com.cn/s/blog_3e50cef401019cd2.html

    CGContextRef CGBitmapContextCreate (

      void *data,

      size_t width,

      size_t height,

      size_t bitsPerComponent,

      size_t bytesPerRow,

      CGColorSpaceRef colorspace,

      CGBitmapInfo bitmapInfo

      );

     参数data指向绘图操作被渲染的内存区域,这个内存区域大小应该为(bytesPerRow*height)个字节。如果对绘制操作被渲染的内存区域并无特别的要求,那么可以传递NULL给参数date。

       参数width代表被渲染内存区域的宽度。

       参数height代表被渲染内存区域的高度。

       参数bitsPerComponent被渲染内存区域中组件在屏幕每个像素点上需要使用的bits位,举例来说,如果使用32-bit像素和RGB颜色格式,那么RGBA颜色格式中每个组件在屏幕每个像素点上需要使用的bits位就为32/4=8。

       参数bytesPerRow代表被渲染内存区域中每行所使用的bytes位数。

       参数colorspace用于被渲染内存区域的“位图上下文”。

       参数bitmapInfo指定被渲染内存区域的“视图”是否包含一个alpha(透视)通道以及每个像素相应的位置,除此之外还可以指定组件式是浮点值还是整数值。

    网络上抄的一份代码:

    @implementation GLView

    #import <UIKit/UIKit.h>

    #import <QuartzCore/QuartzCore.h>

    #import <OpenGLES/ES2/gl.h>

    #import <OpenGLES/ES2/glext.h>

    #import <OpenGLES/ES1/gl.h>

    #import <OpenGLES/ES1/glext.h>

    @interface GLView : UIView {

    @private

        CAEAGLLayer *_eaglLayer;

        EAGLContext *_context;

        GLuint  _colorRenderBuffer;

        

        GLuint _position;

        GLuint _color;

    }

    @end

    #import "GLView.h"

    @implementation GLView

    // 设置LAYER class, 想要显示OPENGL的内容, 你需要把它缺省的layer设置为一个特殊的layer.

    + (Class)layerClass

    {

        return [CAEAGLLayer class];

    }

    // 设置layer为不透明, 缺省的话,CALayer是透明的, 透明的层对性能负荷很打,特别是Opengl的层.

    - (void)setupLayer

    {

        _eaglLayer = (CAEAGLLayer *)self.layer;

        _eaglLayer.opaque = YES;

    }

    // 创建content, 无论你需要OPENGL 帮你做什么 都需要这个EAGLContext, EAGLContext管理所以通过

    // opengl进行的draw的信息.

    - (void)setupContext

    {

        EAGLRenderingAPI api = kEAGLRenderingAPIOpenGLES1;

        _context = [[EAGLContext alloc] initWithAPI:api];

        if (!_context)

        {

         }

        

        if (![EAGLContext setCurrentContext:_context])

        {

            NSLog(@"Failed to set current context");

        }

    }

    // 创建render buffer(渲染缓冲)

    // renderbuffer用于存放渲染过的图像

    // glGenRenderbuffers创建一个renderbuffer,返回一个用于标记renderbuffer的名字_colorRenderBuffer;

    // 调用glBindRenderbuffer,告诉OPengl 刚创建的对象是GL_RENDERBUFFER类型的对象

    // 最后再分配空间

    - (void)setupRenderBuffer

    {

        glGenRenderbuffers(1, &_colorRenderBuffer);

        glBindRenderbuffer(GL_RENDERBUFFER, _colorRenderBuffer);

        

        

        [_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:_eaglLayer];

    }

    // 创建一个FrameBuffer,(帧缓冲区)

    // 

    - (void)setupFrameBuffer

    {

        GLuint frameBuffer;

        glGenFramebuffers(1, &frameBuffer);

        glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);

        

        // 把刚创建的render buffer 依附到frame buffer的GL_COLOR_ATTACHMENT0位置上

        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 

                                  GL_RENDERBUFFER, _colorRenderBuffer);

    }

    // 在和vertextes shader打交道前, 先清理屏幕 显示另一种颜色.

    - (void)render

    {

        

        const GLfloat squareVertices[] = {

            -0.5f, -0.5f, 

            0.5f,  -0.5f,

            -0.5f,  0.5f,

            0.5f,   0.5f,

        };

        纹理的坐标系 左下为(0, 0)点

        const GLshort squarTextureCoords[] = {

            0, 0, // top left

            0, 1,

            1, 0,

            1, 1

        };

        

        [EAGLContext setCurrentContext:context];

        

        glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer);

        glViewport(0, 0, backingWidth, backingHeight);

    //    // 告诉OPENGL 我们工作在投影模式下

        glMatrixMode(GL_PROJECTION);

    //    // 重置所有状态, 比如旋转 移动等

        glLoadIdentity();

        

        glEnable(GL_TEXTURE_2D);

        

        glOrthof(-1.0f, 1.0f, -1.5f, 1.5f, -1.0f, 1.0f);

    glMatrixMode(GL_MODELVIEW);

        

     // 设置一个RGBA颜色, 接下来会用这个颜色来涂抹全屏

        glClearColor(0.5f, 0.5f, 0.5f, 1.0f);

        glClear(GL_COLOR_BUFFER_BIT);

        

        glVertexPointer(2, GL_FLOAT, 0, squareVertices);

        glEnableClientState(GL_VERTEX_ARRAY);

        

        glTexCoordPointer(2, GL_SHORT, 0, squarTextureCoords);

        glEnableClientState(GL_TEXTURE_COORD_ARRAY);

        

       // GL_TRIANGLE_STRIP 最开始的两个顶点除非,然后遍历每个顶点,这些顶点将使用前两个顶点一齐组成三角形

        // GL_TRIANGLE_FAN 跳过开始的2个顶点, 然后遍历每个顶点,然后将这些顶点与他们前一个,以及数组的第一个顶点一齐组成三角

        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

        

        glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);

        [context presentRenderbuffer:GL_RENDERBUFFER_OES];

    }

    void)loadTexture

    {

        // 这个imageRef并不包含图片的数据

    // 注意:

    // 加载的图片大小必须是2的N次方

        CGImageRef imageRef = [[UIImage imageNamed:@"tile_floor.png"] CGImage];

        size_t width = CGImageGetWidth(imageRef);

        size_t height = CGImageGetHeight(imageRef);

        

        // RGBA个数, 每个像素4个字节

        GLubyte *textureData = (GLubyte *)malloc(width * height *4);

        CGContextRef textrureContext = CGBitmapContextCreate(

                                                     textureData, 

                                                     width, 

                                                     height, 

                                                     8, // 每个通道8位

                                                     width * 4, 

                                                              CGImageGetColorSpace(imageRef), 

                                                              kCGImageAlphaPremultipliedLast);

        CGContextDrawImage(textrureContext, CGRectMake(0, 0, width, height), imageRef);

        

        // 只需要一张纹理

        glGenTextures(1, &_texture[0]);

        

        // 激活纹理 新建的纹理名字加载到当期的纹理单元中

        glBindTexture(GL_TEXTURE_2D, _texture[0]);

        

        // 发送纹理数据到OPENGL

        // target 基本上都是GL_TEXTURE_2D

        // level 纹理的详细程序, 0表示允许图片的全部细节,

        // internal_format 和format必须相同 

        // border 必须始终为0 OPENGL es 不支持纹理边界

        // type 像素类型 每个像素占4个字节(无符号整形)

        // pixels 实际的图片数据指针

        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,GL_UNSIGNED_BYTE, textureData);

        

        // 在和缩小(远矩离)的的时候 我们会把纹理缩小.如何处理(GL_LINEAR 是平滑的, GLNEAREST是选择嘴临近的纹理像素)

        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

        glEnable(GL_TEXTURE_2D);

        

        // 

        free(textureData);

        CGContextRelease(textrureContext);

    }

    - (id)initWithFrame:(CGRect)frame

    {

        self = [super initWithFrame:frame];

        if (self) {

            [self setupLayer];

            [self setupContext];

            [self setupRenderBuffer];

            [self setupFrameBuffer];

          [self loadTexture];

            [self render];

            

        }

        return self;

    }

    - (void)dealloc

    {

        [_context release];

        _context = nil;

        

        [super dealloc];

    }

    @end

  • 相关阅读:
    1.27
    1.25
    Representation Learning with Contrastive Predictive Coding
    Learning a Similarity Metric Discriminatively, with Application to Face Verification
    噪声对比估计(负样本采样)
    Certified Adversarial Robustness via Randomized Smoothing
    Certified Robustness to Adversarial Examples with Differential Privacy
    Dynamic Routing Between Capsules
    Defending Adversarial Attacks by Correcting logits
    Visualizing Data using t-SNE
  • 原文地址:https://www.cnblogs.com/xuejinhui/p/4383705.html
Copyright © 2020-2023  润新知