Vuo  2.4.0
VuoImageMapColors.c
Go to the documentation of this file.
1
10#include "node.h"
11#include "VuoImageRenderer.h"
12#include <OpenGL/CGLMacro.h>
13
15#ifdef VUO_COMPILER
17 "title" : "VuoImageMapColors",
18 "dependencies" : [
19 "VuoImageRenderer"
20 ]
21 });
22#endif
24
29{
30 if (!image)
31 return NULL;
32
33 if (!colors)
34 return image;
35
36 static const char * fragmentShaderSource = VUOSHADER_GLSL_SOURCE(120,
37
38 uniform float gradientCount;
39 uniform sampler2D image; // the unfiltered image
40 uniform sampler2D gradientStrip;// the gradient strip to map against
41 uniform float amount; // the amount to mix gradient and image
42 varying vec2 fragmentTextureCoordinate;
43
44 // https://stackoverflow.com/questions/596216/formula-to-determine-brightness-of-rgb-color
45 float brightness(vec3 col)
46 {
47 // Digital CCIR601 (gives more weight to the green and red components):
48 return 0.299*col.r + 0.587*col.g + 0.114*col.b;
49 }
50
51 void main(void)
52 {
53 vec4 orig = texture2D(image, fragmentTextureCoordinate);
54
55 float lum = brightness(orig.rgb/orig.a);
56
57 float gradientWidth = (1./gradientCount)/2.;
58 lum = lum * (1-gradientWidth*2) + gradientWidth;
59
60 vec4 color = texture2D(gradientStrip, vec2(clamp(lum, gradientWidth, 1-gradientWidth), .5));
61
62 vec4 mixed = mix(orig, color, amount);
63 mixed *= orig.a;
64
65 gl_FragColor = mixed;
66 }
67 );
68
69 int len = VuoListGetCount_VuoColor(colors);
70
71 unsigned char* pixels = (unsigned char*)malloc(sizeof(unsigned char)*len*4);
72 int n = 0;
73 for(int i = 1; i <= len; i++)
74 {
75 VuoColor col = VuoListGetValue_VuoColor(colors, i);
76 // VuoColor is non-premultiplied, but VuoImage_makeFromBuffer() expects premultiplied colors, so premultiply them.
77 pixels[n++] = (unsigned int)(col.a*col.b*255);
78 pixels[n++] = (unsigned int)(col.a*col.g*255);
79 pixels[n++] = (unsigned int)(col.a*col.r*255);
80 pixels[n++] = (unsigned int)(col.a*255);
81 }
82
83 VuoImage gradientStrip = VuoImage_makeFromBuffer(pixels, GL_BGRA, len, 1, VuoImageColorDepth_8, ^(void *buffer){ free(buffer); });
84
85 VuoShader shader = VuoShader_make("Map Image Colors Shader");
86 VuoShader_addSource(shader, VuoMesh_IndividualTriangles, NULL, NULL, fragmentShaderSource);
87 VuoRetain(shader);
88
89 // Set `image` before `gradientStrip`, so that `image`'s scaleFactor is used for the output image.
90 VuoShader_setUniform_VuoImage(shader, "image", image);
91 VuoShader_setUniform_VuoImage(shader, "gradientStrip", gradientStrip);
92 VuoShader_setUniform_VuoReal (shader, "gradientCount", (float)len);
93 VuoShader_setUniform_VuoReal (shader, "amount", filterOpacity);
94
95 // Render.
96 VuoImage mappedImage = VuoImageRenderer_render(shader, image->pixelsWide, image->pixelsHigh, VuoImage_getColorDepth(image));
97
98 VuoRelease(shader);
99
100 return mappedImage;
101}