ImageEdit
Input:
{"image"}, {"enum RGB R G B", "RGB", "RGB"}, {"float", "R", "1"}, {"float", "G", "1"}, {"float", "B", "1"}, {"float", "Luminace", "1"}, {"float", "ContrastRatio", "1"}, {"float", "Saturation", "1"}, {"bool", "Average", "0"}, {"bool", "Invert", "0"}
Output:
default
R
G
B
edit
Average
Invert
Average + Invert
struct ImageEdit: INode {
virtual void apply() override {
auto image = get_input<PrimitiveObject>("image");
auto RGB = get_input2<std::string>("RGB");
auto Average = get_input2<bool>("Average");
auto Invert = get_input2<bool>("Invert");
float R = get_input2<float>("R");
float G = get_input2<float>("G");
float B = get_input2<float>("B");
float L = get_input2<float>("Luminace");
float ContrastRatio = get_input2<float>("ContrastRatio");
float Si = get_input2<float>("Saturation");
float H = 0, S = 0, V = 0;
if(RGB == "RGB") {
for (auto i = 0; i < image->verts.size(); i++) {
float R1 = image->verts[i][0];
float G1 = image->verts[i][1];
float B1 = image->verts[i][2];
R1 *= R;
G1 *= G;
B1 *= B;
zeno::RGBtoHSV(R1, G1, B1, H, S, V);
S = S + (S - 0.5)*(Si-1);
V = V + (V - 0.5)*(L-1);
zeno::HSVtoRGB(H, S, V, R1, G1, B1);
image->verts[i][0] = R1;
image->verts[i][1] = G1;
image->verts[i][2] = B1;
}
}
if(RGB == "R") {
for (auto i = 0; i < image->verts.size(); i++) {
float R1 = R * image->verts[i][0];
float G1 = 0;
float B1 = 0;
R1 *= R;
G1 *= G;
B1 *= B;
zeno::RGBtoHSV(R1, G1, B1, H, S, V);
S = S + (S - 0.5)*(Si-1);
V = V + (V - 0.5)*(L-1);
zeno::HSVtoRGB(H, S, V, R1, G1, B1);
image->verts[i][0] = R1 ;
image->verts[i][1] = G1 ;
image->verts[i][2] = B1 ;
}
}
if(RGB == "G") {
for (auto i = 0; i < image->verts.size(); i++) {
float R1 = 0;
float G1 = G * image->verts[i][1];
float B1 = 0;
R1 *= R;
G1 *= G;
B1 *= B;
zeno::RGBtoHSV(R1, G1, B1, H, S, V);
S = S + (S - 0.5)*(Si-1);
V = V + (V - 0.5)*(L-1);
zeno::HSVtoRGB(H, S, V, R1, G1, B1);
image->verts[i][0] = R1 ;
image->verts[i][1] = G1 ;
image->verts[i][2] = B1 ;
}
}
if(RGB == "B") {
for (auto i = 0; i < image->verts.size(); i++) {
float R1 = 0;
float G1 = 0;
float B1 = B * image->verts[i][2];
R1 *= R;
G1 *= G;
B1 *= B;
zeno::RGBtoHSV(R1, G1, B1, H, S, V);
S = S + (S - 0.5)*(Si-1);
V = V + (V - 0.5)*(L-1);
zeno::HSVtoRGB(H, S, V, R1, G1, B1);
image->verts[i][0] = R1;
image->verts[i][1] = G1;
image->verts[i][2] = B1;
}
}
for (auto i = 0; i < image->verts.size(); i++) {
image->verts[i] = image->verts[i] + (image->verts[i]-0.5) * (ContrastRatio-1);
}
if(Average){
for (auto i = 0; i < image->verts.size(); i++) {
float R = image->verts[i][0];
float G = image->verts[i][1];
float B = image->verts[i][2];
float avr = (R + G + B)/3;
image->verts[i][0] = avr ;
image->verts[i][1] = avr ;
image->verts[i][2] = avr ;
}
}
if(Invert){
for (auto i = 0; i < image->verts.size(); i++) {
image->verts[i] = 1 - image->verts[i];
}
}
set_output("image", image);
}
};
ZENDEFNODE(ImageEdit, {
{
{"image"},
{"enum RGB R G B", "RGB", "RGB"},
{"float", "R", "1"},
{"float", "G", "1"},
{"float", "B", "1"},
{"float", "Luminace", "1"},
{"float", "ContrastRatio", "1"},
{"float", "Saturation", "1"},
{"bool", "Average", "0"},
{"bool", "Invert", "0"},
},
{
{"image"}
},
{},
{ "comp" },
});
EditRGB
Input:
{"image"}, {"enum RGB R G B", "RGB", "RGB"}, {"float", "R", "1"}, {"float", "G", "1"}, {"float", "B", "1"}, {"bool", "Average", "0"}, {"bool", "Invert", "0"},
Output:
default
edit
Average
Invert
Average + Invert
struct EditRGB : INode {
virtual void apply() override {
auto image = get_input<PrimitiveObject>("image");
auto RGB = get_input2<std::string>("RGB");
auto Average = get_input2<bool>("Average");
auto Invert = get_input2<bool>("Invert");
float R = get_input2<float>("R");
float G = get_input2<float>("G");
float B = get_input2<float>("B");
if(RGB == "RGB") {
for (auto i = 0; i < image->verts.size(); i++) {
float R1 = R * image->verts[i][0];
float G1 = G * image->verts[i][1];
float B1 = B * image->verts[i][2];
image->verts[i][0] = R1 ;
image->verts[i][1] = G1 ;
image->verts[i][2] = B1 ;
}
}
if(RGB == "R") {
for (auto i = 0; i < image->verts.size(); i++) {
float R1 = R * image->verts[i][0];
float G1 = 0;
float B1 = 0;
image->verts[i][0] = R1 ;
image->verts[i][1] = G1 ;
image->verts[i][2] = B1 ;
}
}
if(RGB == "G") {
for (auto i = 0; i < image->verts.size(); i++) {
float R1 = 0;
float G1 = G * image->verts[i][1];
float B1 = 0;
image->verts[i][0] = R1 ;
image->verts[i][1] = G1 ;
image->verts[i][2] = B1 ;
}
}
if(RGB == "B") {
for (auto i = 0; i < image->verts.size(); i++) {
float R1 = 0;
float G1 = 0;
float B1 = B * image->verts[i][2];
image->verts[i][0] = R1;
image->verts[i][1] = G1;
image->verts[i][2] = B1;
}
}
if(Average){
for (auto i = 0; i < image->verts.size(); i++) {
float R = image->verts[i][0];
float G = image->verts[i][1];
float B = image->verts[i][2];
float avr = (R + G + B)/3;
image->verts[i][0] = avr ;
image->verts[i][1] = avr ;
image->verts[i][2] = avr ;
}
}
if(Invert){
for (auto i = 0; i < image->verts.size(); i++) {
image->verts[i] = 1 - image->verts[i];
}
}
set_output("image", image);
}
};
ZENDEFNODE(EditRGB, {
{
{"image"},
{"enum RGB R G B", "RGB", "RGB"},
{"float", "R", "1"},
{"float", "G", "1"},
{"float", "B", "1"},
{"bool", "Average", "0"},
{"bool", "Invert", "0"},
},
{
{"image"}
},
{},
{ "comp" },
});
EditHSV
Input:
{"image"}, {"enum default edit red orange yellow green cyan blue purple ", "Hue", "edit"}, {"float", "H", "1"}, {"float", "S", "1"}, {"float", "V", "1"},
Output:
default
edit
red
orange
yellow
green
cyan
blue
purple
struct EditHSV : INode {
virtual void apply() override {
auto image = get_input<PrimitiveObject>("image");
float H = 0, S = 0, V = 0;
auto Hue = get_input2<std::string>("Hue");
float Hi = get_input2<float>("H");
float Si = get_input2<float>("S");
float Vi = get_input2<float>("V");
if(Hue == "default"){
for (auto i = 0; i < image->verts.size(); i++) {
float R = image->verts[i][0];
float G = image->verts[i][1];
float B = image->verts[i][2];
zeno::RGBtoHSV(R, G, B, H, S, V);
H = H + (H - 0.5)*(Hi-1);
S = S + (S - 0.5)*(Si-1);
V = V + (V - 0.5)*(Vi-1);
zeno::HSVtoRGB(H, S, V, R, G, B);
image->verts[i][0] = R;
image->verts[i][1] = G;
image->verts[i][2] = B;
}
}
if(Hue == "edit"){
for (auto i = 0; i < image->verts.size(); i++) {
float R = image->verts[i][0];
float G = image->verts[i][1];
float B = image->verts[i][2];
zeno::RGBtoHSV(R, G, B, H, S, V);
H = Hi;
S = S + (S - 0.5)*(Si-1);
V = V + (V - 0.5)*(Vi-1);
zeno::HSVtoRGB(H, S, V, R, G, B);
image->verts[i][0] = R;
image->verts[i][1] = G;
image->verts[i][2] = B;
}
}
if(Hue == "red"){
for (auto i = 0; i < image->verts.size(); i++) {
float R = image->verts[i][0];
float G = image->verts[i][1];
float B = image->verts[i][2];
zeno::RGBtoHSV(R, G, B, H, S, V);
H = 0;
S = S + (S - 0.5)*(Si-1);
V = V + (V - 0.5)*(Vi-1);
zeno::HSVtoRGB(H, S, V, R, G, B);
image->verts[i][0] = R;
image->verts[i][1] = G;
image->verts[i][2] = B;
}
}
if(Hue == "orange"){
for (auto i = 0; i < image->verts.size(); i++) {
float R = image->verts[i][0];
float G = image->verts[i][1];
float B = image->verts[i][2];
zeno::RGBtoHSV(R, G, B, H, S, V);
H = 30;
S = S + (S - 0.5)*(Si-1);
V = V + (V - 0.5)*(Vi-1);
zeno::HSVtoRGB(H, S, V, R, G, B);
image->verts[i][0] = R;
image->verts[i][1] = G;
image->verts[i][2] = B;
}
}
if(Hue == "yellow"){
for (auto i = 0; i < image->verts.size(); i++) {
float R = image->verts[i][0];
float G = image->verts[i][1];
float B = image->verts[i][2];
zeno::RGBtoHSV(R, G, B, H, S, V);
H = 60;
S = S + (S - 0.5)*(Si-1);
V = V + (V - 0.5)*(Vi-1);
zeno::HSVtoRGB(H, S, V, R, G, B);
image->verts[i][0] = R;
image->verts[i][1] = G;
image->verts[i][2] = B;
}
}
if(Hue == "green"){
for (auto i = 0; i < image->verts.size(); i++) {
float R = image->verts[i][0];
float G = image->verts[i][1];
float B = image->verts[i][2];
zeno::RGBtoHSV(R, G, B, H, S, V);
H = 120;
S = S + (S - 0.5)*(Si-1);
V = V + (V - 0.5)*(Vi-1);
zeno::HSVtoRGB(H, S, V, R, G, B);
image->verts[i][0] = R;
image->verts[i][1] = G;
image->verts[i][2] = B;
}
}
if(Hue == "cyan"){
for (auto i = 0; i < image->verts.size(); i++) {
float R = image->verts[i][0];
float G = image->verts[i][1];
float B = image->verts[i][2];
zeno::RGBtoHSV(R, G, B, H, S, V);
H = 180;
S = S + (S - 0.5)*(Si-1);
V = V + (V - 0.5)*(Vi-1);
zeno::HSVtoRGB(H, S, V, R, G, B);
image->verts[i][0] = R;
image->verts[i][1] = G;
image->verts[i][2] = B;
}
}
if(Hue == "blue"){
for (auto i = 0; i < image->verts.size(); i++) {
float R = image->verts[i][0];
float G = image->verts[i][1];
float B = image->verts[i][2];
zeno::RGBtoHSV(R, G, B, H, S, V);
H = 240;
S = S + (S - 0.5)*(Si-1);
V = V + (V - 0.5)*(Vi-1);
zeno::HSVtoRGB(H, S, V, R, G, B);
image->verts[i][0] = R;
image->verts[i][1] = G;
image->verts[i][2] = B;
}
}
if(Hue == "purple"){
for (auto i = 0; i < image->verts.size(); i++) {
float R = image->verts[i][0];
float G = image->verts[i][1];
float B = image->verts[i][2];
zeno::RGBtoHSV(R, G, B, H, S, V);
H = 300;
S = S + (S - 0.5)*(Si-1);
V = V + (V - 0.5)*(Vi-1);
zeno::HSVtoRGB(H, S, V, R, G, B);
image->verts[i][0] = R;
image->verts[i][1] = G;
image->verts[i][2] = B;
}
}
set_output("image", image);
}
};
ZENDEFNODE(EditHSV, {
{
{"image"},
{"enum default edit red orange yellow green cyan blue purple ", "Hue", "edit"},
{"float", "H", "1"},
{"float", "S", "1"},
{"float", "V", "1"},
},
{
{"image"}
},
{},
{ "comp" },
});
RGBtoHSV & HSVtoRGB
void RGBtoHSV(float r, float g, float b, float &h, float &s, float &v) {
float rd = r;
float gd = g;
float bd = b;
float cmax = fmax(rd, fmax(gd, bd));
float cmin = fmin(rd, fmin(gd, bd));
float delta = cmax - cmin;
if (delta != 0) {
if (cmax == rd) {
h = fmod((gd - bd) / delta, 6.0);
} else if (cmax == gd) {
h = (bd - rd) / delta + 2.0;
} else if (cmax == bd) {
h = (rd - gd) / delta + 4.0;
}
h *= 60.0;
if (h < 0) {
h += 360.0;
}
}
s = (cmax != 0) ? delta / cmax : 0.0;
v = cmax;
}
void HSVtoRGB(float h, float s, float v, float &r, float &g, float &b)
{
int i;
float f, p, q, t;
if( s == 0 ) {
// achromatic (grey)
r = g = b = v;
return;
}
h /= 60; // sector 0 to 5
i = floor( h );
f = h - i; // factorial part of h
p = v * ( 1 - s );
q = v * ( 1 - s * f );
t = v * ( 1 - s * ( 1 - f ) );
switch( i ) {
case 0:
r = v;
g = t;
b = p;
break;
case 1:
r = q;
g = v;
b = p;
break;
case 2:
r = p;
g = v;
b = t;
break;
case 3:
r = p;
g = q;
b = v;
break;
case 4:
r = t;
g = p;
b = v;
break;
default: // case 5:
r = v;
g = p;
b = q;
break;
}
}