Created
August 19, 2016 17:51
-
-
Save vgoltv/32dc2c8823568ebe1578181a07b6e60b to your computer and use it in GitHub Desktop.
display CIImage via GLKView
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// FWKCIImageView.h | |
// LineEngraver | |
// | |
// Created by Viktor Goltvyanytsya on 8/8/16. | |
// | |
// | |
#import <UIKit/UIKit.h> | |
@interface FWKCIImageView : UIView | |
- (CIImage *)ciImage; | |
- (void)setCiImage:(CIImage *)image; | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// FWKCIImageView.m | |
// LineEngraver | |
// | |
// Created by Viktor Goltvyanytsya on 8/8/16. | |
// | |
// | |
#import "FWKCIImageView.h" | |
#import <GLKit/GLKView.h> | |
#include <OpenGLES/ES2/gl.h> | |
#include <OpenGLES/ES2/glext.h> | |
@interface FWKCIImageView ()<GLKViewDelegate> | |
{ | |
CIImage *_ciImage; | |
EAGLContext *_eaglContext; | |
CIContext *_ciContext; | |
GLKView *_glView; | |
} | |
@end | |
@implementation FWKCIImageView | |
-(void)dealloc; | |
{ | |
_ciImage = nil; | |
_eaglContext = nil; | |
_ciContext = nil; | |
if( _glView ) | |
{ | |
[_glView removeFromSuperview]; | |
} | |
_glView = nil; | |
} | |
- (id)initWithFrame:(CGRect)frame | |
{ | |
self = [super initWithFrame:frame]; | |
if (self) { | |
// Initialization code | |
[self setBackgroundColor:[UIColor clearColor]]; | |
[self setAutoresizesSubviews:NO]; | |
[self setTranslatesAutoresizingMaskIntoConstraints:NO]; | |
_eaglContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; | |
_eaglContext.multiThreaded = YES; | |
_ciContext = [CIContext | |
contextWithEAGLContext:_eaglContext | |
options: @{kCIContextUseSoftwareRenderer: @NO} ]; | |
_glView = [[GLKView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height) context:_eaglContext]; | |
_glView.enableSetNeedsDisplay = NO; | |
_glView.delegate = self; | |
_glView.drawableDepthFormat = GLKViewDrawableDepthFormat24; | |
[self addSubview:_glView]; | |
[EAGLContext setCurrentContext:_eaglContext]; | |
} | |
return self; | |
} | |
- (CIImage *)ciImage | |
{ | |
return _ciImage; | |
} | |
- (void)setCiImage:(CIImage *)image | |
{ | |
_ciImage = image; | |
[self _drawCIImage:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)]; | |
} | |
- (void)setFrame:(CGRect)frame | |
{ | |
BOOL changed = !CGSizeEqualToSize(self.frame.size, frame.size); | |
[super setFrame:frame]; | |
if (changed && _ciImage) | |
{ | |
[self _drawCIImage:frame]; | |
} | |
} | |
#pragma mark -GLKViewDelegate methods | |
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect | |
{ | |
} | |
#pragma mark -Private methods | |
- (void)_drawCIImage:(CGRect)frame | |
{ | |
[_glView bindDrawable]; | |
if (_eaglContext != [EAGLContext currentContext]) | |
{ | |
[EAGLContext setCurrentContext:_eaglContext]; | |
} | |
// clear eagl view to grey | |
glClearColor(0.5, 0.5, 0.5, 1.0); | |
glClear(GL_COLOR_BUFFER_BIT); | |
// set the blend mode to "source over" so that CI will use that | |
glEnable(GL_BLEND); | |
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); | |
if (_ciImage) | |
{ | |
[_glView setFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)]; | |
CGSize imageSize = _ciImage.extent.size; | |
CGFloat drawableWidth = _glView.drawableWidth; | |
CGFloat drawableHeight = _glView.drawableHeight; | |
CGRect drawFrame = CGRectMake(0, 0, drawableWidth, drawableHeight); | |
CGFloat imageAR = imageSize.width / imageSize.height; | |
CGFloat viewAR = drawFrame.size.width / drawFrame.size.height; | |
if (imageAR > viewAR) | |
{ | |
drawFrame.origin.y += (drawFrame.size.height - drawFrame.size.width / imageAR) / 2.0; | |
drawFrame.size.height = drawFrame.size.width / imageAR; | |
} | |
else | |
{ | |
drawFrame.origin.x += (drawFrame.size.width - drawFrame.size.height * imageAR) / 2.0; | |
drawFrame.size.width = drawFrame.size.height * imageAR; | |
} | |
[_ciContext drawImage:_ciImage inRect:drawFrame fromRect:[_ciImage extent]]; | |
} | |
[_glView display]; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment