使用opengl对图像进行模糊处理

使用opengl对图像进行模糊处理

本文介绍了使用opengl对图像进行模糊处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的要求与这个问题

我现在处于在opengl视图上设置UIImage的情况.以下是我用来设置uiimage的完整代码.还包括绘图代码.使用下面的代码,我可以设置图像并在其上绘图.

I am right now at situation where i set UIImage on my opengl view.Below is the complete code i used to set uiimage. Also it includes the drawing code.Using below code I am able to set image and drawing on it.

当我未在背景中设置图像时,它允许我绘制模糊且平滑的图形

when i do not set image in background it allows me to draw blur and smooth drawing

但是如果我设置背景图像,它将绘制实体图

but if i set background image it draws solid drawing

我要在背景图像上平滑绘制.

I want smooth drawing on background image.

我已经使用了苹果的GLPaint代码进行绘图.

I have used some of GLPaint code of apple for drawing.

 - (id)initWithCoder:(NSCoder*)coder
{
    CGImageRef      brushImage;
    CGContextRef    brushContext;
    GLubyte         *brushData;
    size_t          width, height;

    if ((self = [super initWithCoder:coder]))
    {
        CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
        eaglLayer.opaque = NO;
        eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
                                        [NSNumber numberWithBool:YES], kEAGLDrawablePropertyRetainedBacking,
                                        kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat,
                                        nil];

        _context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
        if (!_context || ![EAGLContext setCurrentContext:_context])
        {
            return nil;
        }

        {
            brushImage = [UIImage imageNamed:@"Brush.png"].CGImage;

            width = CGImageGetWidth(brushImage);
            height = CGImageGetHeight(brushImage);

            if(brushImage) {
                brushData = (GLubyte *) calloc(width * height * 4, sizeof(GLubyte));
                brushContext = CGBitmapContextCreate(brushData, width, width, 8, width * 4, CGImageGetColorSpace(brushImage), kCGImageAlphaPremultipliedLast);
                CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
                CGContextDrawImage(brushContext, CGRectMake(0.0, 0.0, (CGFloat)width, (CGFloat)height), brushImage);
                CGContextRelease(brushContext);
                glGenTextures(1, &brushTexture);
                glBindTexture(GL_TEXTURE_2D, brushTexture);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
                glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, brushData);
                free(brushData);
            }
        }

        // Setup OpenGL states
        glMatrixMode(GL_PROJECTION);
        CGRect frame = self.bounds;
        glOrthof(0, frame.size.width, 0, frame.size.height, -1, 1);
        glViewport(0, 0, frame.size.width , frame.size.height);
        glMatrixMode(GL_MODELVIEW);

        glDisable(GL_DITHER);
        glEnable(GL_TEXTURE_2D);
        glEnableClientState(GL_VERTEX_ARRAY);

        glEnable(GL_BLEND);
        glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

        glEnable(GL_POINT_SPRITE_OES);
        glTexEnvf(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, GL_TRUE);
        glPointSize(10);

    }
    return self;
}



  - (void)layoutSubviews
    {
        [EAGLContext setCurrentContext:_context];
        [self destroyFramebuffer];
        [self createFramebuffer];

        if (texture)    {
            [self _updateContent];
            glDeleteTextures(1, &texture);
            texture = 0;
        }
    }


    - (void)_updateContent {
        NSUInteger width = self.frame.size.width;
        NSUInteger height = self.frame.size.height;

        CGFloat texWidth = (1.0 * width)/TEX_SIZE;
        CGFloat texHeight = (1.0 * height)/TEX_SIZE;

        GLfloat verts[12] = {
            0, height,
            width, height,
            width, 0,
            0, height,
            0, 0,
            width, 0
        };

        GLfloat txcoord[12] = {
            0, texHeight,
            texWidth, texHeight,
            texWidth, 0,
            0, texHeight,
            0, 0,
            texWidth, 0
        };

        [EAGLContext setCurrentContext:_context];
        glBindFramebufferOES(GL_FRAMEBUFFER_OES, _viewFramebuffer);
        glVertexPointer(2, GL_FLOAT, 0, verts);
        glTexCoordPointer(2, GL_FLOAT, 0, txcoord);
        glDrawArrays(GL_TRIANGLES, 0, 6);

        glDisableClientState(GL_TEXTURE_COORD_ARRAY);

        glBindRenderbufferOES(GL_RENDERBUFFER_OES, _viewRenderbuffer);
        [_context presentRenderbuffer:GL_RENDERBUFFER_OES];

        glDisable(GL_TEXTURE_2D);
        glDisable(GL_BLEND);

    }


   - (void)setContent:(UIImage*)image
{

    if (image) {
        //        self.isNotEmpty = YES;
        CGImageRef contentImage = image.CGImage;

        [EAGLContext setCurrentContext:_context];

        CGFloat w = CGImageGetWidth(contentImage);
        CGFloat h = CGImageGetHeight(contentImage);

        GLubyte *data = (GLubyte *)calloc(TEX_SIZE * TEX_SIZE * 4, sizeof(GLubyte));

        CGContextRef ctx = CGBitmapContextCreate(data, TEX_SIZE, TEX_SIZE, 8, TEX_SIZE * 4, CGImageGetColorSpace(contentImage), kCGImageAlphaPremultipliedLast);
        CGContextScaleCTM(ctx, 1, -1);
        CGContextTranslateCTM(ctx, 0, -TEX_SIZE);
        CGContextDrawImage(ctx, CGRectMake(0, 0, w, h), contentImage);
        CGContextRelease(ctx);

        if (!texture) {
            glGenTextures(1, &texture);
        }
        glBindTexture(GL_TEXTURE_2D, texture);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TEX_SIZE, TEX_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
        free(data);
    }
    [self setNeedsLayout];
    glDisable(GL_VERTEX_ARRAY);
}

//在touchedMoved上调用

//Called on touchedMoved

- (void) renderLineFromPoint:(CGPoint)start toPoint:(CGPoint)end
{
    glEnable(GL_BLEND);
    if(1){
        sharedDelegate = [AppDelegate appDelegate];

        static GLfloat*     vertexBuffer = NULL;
        static NSUInteger   vertexMax = 64;
        NSUInteger          vertexCount = 0,
        count,
        i;
        GLenum err;

        glColor4f(1.0, 0.0, 1.0, 1.0);

        // Convert locations from Points to Pixels
        CGFloat scale = self.contentScaleFactor;
        start.x *= scale;
        start.y *= scale;
        end.x *= scale;
        end.y *= scale;

        // Allocate vertex array buffer
        if(vertexBuffer == NULL)
            vertexBuffer = malloc(vertexMax * 2 * sizeof(GLfloat));

        // Add points to the buffer so there are drawing points every X pixels
        count = MAX(ceilf(sqrtf((end.x - start.x) * (end.x - start.x) + (end.y - start.y) * (end.y - start.y)) / kBrushPixelStep), 1);
        for(i = 0; i < count; ++i) {
            if(vertexCount == vertexMax) {
                vertexMax = 2 * vertexMax;
                vertexBuffer = realloc(vertexBuffer, vertexMax * 2 * sizeof(GLfloat));
            }

            vertexBuffer[2 * vertexCount + 0] = start.x + (end.x - start.x) * ((GLfloat)i / (GLfloat)count);
            vertexBuffer[2 * vertexCount + 1] = start.y + (end.y - start.y) * ((GLfloat)i / (GLfloat)count);
            vertexCount += 1;
        }

        if(sharedDelegate.boolIsEraser)
        {
            glColor4f(1.0, 1.0, 1.0, 0.5);
            glBlendFunc( GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);
        }
        // Render the vertex array
        glVertexPointer(2, GL_FLOAT, 0, vertexBuffer);
        glDrawArrays(GL_POINTS, 0, vertexCount);

        if(sharedDelegate.boolIsEraser){
            // at last restore the  mixed-mode
            glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
        }

        glBindRenderbufferOES(GL_RENDERBUFFER_OES, _viewRenderbuffer);
        [_context presentRenderbuffer:GL_RENDERBUFFER_OES];

        err = glGetError();
        if (err != GL_NO_ERROR)
            NSLog(@"Error in frame. glError: 0x%04X", err);

    }
}

有什么解决方法可以做到这一点?我几乎可以实现我的目标,但是却被困在这里.任何帮助将不胜感激.

Any workaround to accomplish this?I am almost there to my goal but badly stuck here.Any help will be appreciated.

推荐答案

我找到了解决方法...

I got the solution...

剩下的事情是我需要在opengl视图中绘制UIImage之后设置我的opengl状态.我初始化画笔纹理时所做的同样的事情...

The thing remaining was I need to set my opengl states after i draw UIImage in opengl view. The same thing i did when i initialized brush texture...

我只是在_updateContent方法之后在LayoutSubviews方法中添加了以下代码

I just added below code in LayoutSubviews method after _updateContent method

        // Setup OpenGL states
        glMatrixMode(GL_PROJECTION);
        CGRect frame = self.bounds;
        glOrthof(0, frame.size.width, 0, frame.size.height, -1, 1);
        glViewport(0, 0, frame.size.width , frame.size.height);
        glMatrixMode(GL_MODELVIEW);

        glDisable(GL_DITHER);
        glEnable(GL_TEXTURE_2D);
        glEnableClientState(GL_VERTEX_ARRAY);

        glEnable(GL_BLEND);
        glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

        glEnable(GL_POINT_SPRITE_OES);
        glTexEnvf(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, GL_TRUE)

现在此代码运行正常..

and now this code is working perfectly..

这篇关于使用opengl对图像进行模糊处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-21 12:28