0

Looking at GPUImagePosterizeFilter it seems like an easy adaptation to replace colors with pixels from textures. Say I have an image that is made from 10 greyscale colors. I would like to replace each of the pixel ranges from the 10 colors with pixels from 10 different texture swatches.

What is the proper way to create the textures? I am using the code below (I am not sure on the alpha arguments sent to CGBitmapContextCreate).

CGImageRef spriteImage = [UIImage imageNamed:fileName].CGImage;
size_t width = CGImageGetWidth(spriteImage);
size_t height = CGImageGetHeight(spriteImage);

GLubyte * spriteData = (GLubyte *) calloc(width*height*4, sizeof(GLubyte));
CGContextRef spriteContext = CGBitmapContextCreate(spriteData, width, height, 8, width*4, CGImageGetColorSpace(spriteImage), kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGContextDrawImage(spriteContext, CGRectMake(0, 0, width, height), spriteImage);
CGContextRelease(spriteContext);

GLuint texName;
glGenTextures(1, &texName);
glBindTexture(GL_TEXTURE_2D, texName);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, spriteData);
free(spriteData);
return texName;

What is the proper way to pass the texture to the filter? In my main I have added:

uniform sampler2D fill0Texture;

In the code below texture is whats passed from the function above.

glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture);
glUniform1i(fill0Uniform, 1);

When ever I try to get an image from the spriteContext its nil and when I try using pixels from fill0Texture they are always black. I have thought about doing this with 10 chroma key iterations, but I think replacing all the pixels in a modified GPUImagePosterizeFilter is the way to go.

genpfault
  • 51,148
  • 11
  • 85
  • 139
Joe Andolina
  • 648
  • 1
  • 11
  • 23
  • You'll probably need to set that up as a two-input filter and pass in your image as a GPUImagePicture as the second input. Rather than doing that, though, you might want to look at using a GPUImageLookupFilter instead as a second pass after your posterization: http://liovch.blogspot.com/2012/07/add-instagram-like-effects-to-your-ios.html – Brad Larson Feb 27 '14 at 20:24
  • I got everything working with a version of PosterizeFilter. But now I will look into the LookupFilter. – Joe Andolina Feb 28 '14 at 03:03

1 Answers1

0

In order to match colors against the output from the PosterizeFilter, I am using the following code.

float testValue = 1.0 - (float(idx) / float(colorLevels));
vec4 keyColor = vec4(testValue, testValue, testValue, 1.0);

vec4 replacementColor = texture2D( tx0, textureCoord(idx));

float select = step(distance(keyColor,srcColor),.1);
return select * replacementColor;

If the color(already Posterized) passed in matches then the replacement color is returned. The textureCoord(idx) call looks up the replacement color from a gltexture.

Joe Andolina
  • 648
  • 1
  • 11
  • 23