常见混合结果展示
图层混合后变暗
正常模式(normal)
混合色*不透明度+(100%-混合色不透明度)
void layerblend_normal(Mat &base,Mat &blend,Mat &dst,float opacity)
{
if (base.rows != blend.rows ||
base.cols != blend.cols ||
base.type() != blend.type())
return;
dst = Mat::zeros(base.rows,base.cols,base.type());
for (int h = 0;h < base.rows;h ++)
{
uchar *d1 = base.ptr<uchar>(h);
uchar *d2 = blend.ptr<uchar>(h);
uchar *d3 = dst.ptr<uchar>(h);
for (int w = 0;w < base.cols;w ++)
{
int cw = w * base.channels();
for (int c = 0;c < base.channels();c ++)
d3[cw + c] = opacity * d1[cw + c] + (1.0f - opacity) * d2[cw + c];
}
}
}
溶解模式(dissolve)
溶解模式下混合色的不透明度及填充都是100%的话,我们就看不到基色图层。降低混合色图层的不透明度后,我们就会发现结果色中出现了很多细小的颗粒。这些颗粒会随着混合色的不透明度变化。不透明度越低混合色图层就被溶解的越多。剩下的部分就越少。不透明度越高混合色图层被溶解的部分就越少,剩下的部分就越多,结果色就越接近混合色。
变暗模式(darkness)
变暗混合模式下,它会把混合色与基色进行对比,分别选择R,G,B三组数值中最小的数值,也就是最暗的颜色作为结果色的数值。这样整个画面会变得更暗,如果是彩色图像,颜色也会发生很大的改变。(位置互换不发生变化)
void layerblend_darkness(Mat &base,Mat &blend,Mat &dst)
{
if (base.rows != blend.rows ||
base.cols != blend.cols ||
base.type() != blend.type())
return;
dst = Mat::zeros(base.rows,base.cols,base.type());
for (int h = 0;h < base.rows;h ++)
{
uchar *d1 = base.ptr<uchar>(h);
uchar *d2 = blend.ptr<uchar>(h);
uchar *d3 = dst.ptr<uchar>(h);
for (int w = 0;w < base.cols;w ++)
{
int cw = w * base.channels();
for (int c = 0;c < base.channels();c ++)
d3[cw + c] = d1[cw + c] < d2[cw + c] ? d1[cw + c] : d2[cw + c];
}
}
}
正片叠底(multiply)
正片叠底混合原理:它是按照混合色与基色中的各R,G,B值计算,计算公式:结果色R=混合色R * 基色R / 255,G值与B值同样的方法计算。最后得到的R,G,B值就是结果色的颜色。由于各通道的最大值是255,因此结果色的数值比混合色及基色的数值都要小,也就是结果色要暗。(位置互换不发生变化)
void layerblend_multiply(Mat &base,Mat &blend,Mat &dst)
{
if (base.rows != blend.rows ||
base.cols != blend.cols ||
base.type() != blend.type())
return;
dst = Mat::zeros(base.rows,base.cols,base.type());
for (int h = 0;h < base.rows;h ++)
{
uchar *d1 = base.ptr<uchar>(h);
uchar *d2 = blend.ptr<uchar>(h);
uchar *d3 = dst.ptr<uchar>(h);
for (int w = 0;w < base.cols;w ++)
{
int cw = w * base.channels();
for (int c = 0;c < base.channels();c ++)
d3[cw + c] = 1.0f * d1[cw + c] * d2[cw + c] / 255;
}
}
}
颜色加深(color dark)
颜色加深可以快速增加图片的暗部。它的计算公式:结果色 = (基色 + 混合色 - 255)* 255 / 混合色。其中(基色 + 混合色 - 255)如果出现负数就直接归0。因此在基色与混合色都较暗的时候都是直接变成黑色的。这样结果色的暗部就会增加。整体效果看上去对比较为强烈.
void layerblend_color_dark(Mat &base,Mat &blend,Mat &dst)
{
if (base.rows != blend.rows ||
base.cols != blend.cols ||
base.type() != blend.type())
return;
dst = Mat::zeros(base.rows,base.cols,base.type());
for (int h = 0;h < base.rows;h ++)
{
uchar *d1 = base.ptr<uchar>(h);
uchar *d2 = blend.ptr<uchar>(h);
uchar *d3 = dst.ptr<uchar>(h);
for (int w = 0;w < base.cols;w ++)
{
int cw = w * base.channels();
for (int c = 0;c < base.channels();c ++){
d3[cw + c] = 1.0f * d1[cw + c] * d2[cw + c] / 255;
int temp = d1[cw + c] + d2[cw + c] - 255;
temp = temp < 0 ? 0 : temp;
int res = 0;
if (d2[cw + c] == 0)
res = d1[cw + c];
else
res = temp * 255.0f / d2[cw + c];
d3[cw + c] = saturate_cast<uchar>(res);
}
}
}
}
深色模式(dark)
深色混合模式比较好理解。它是通过计算混合色与基色的所有通道的数值,然后选择数值较小的作为结果色。因此结果色只跟混合色或基色相同,不会产生出另外的颜色。白色与基色混合色得到基色,黑色与基色混合得到黑色。深色模式中,混合色与基色的数值是固定的,我们颠倒位置后,混合色出来的结果色是没有变化的,此模式与变暗模式类同。