2022-09-08 19:48:06 +02:00
|
|
|
#include "image_utils.h"
|
|
|
|
|
|
|
|
|
|
namespace image
|
|
|
|
|
{
|
2024-01-04 10:34:33 -05:00
|
|
|
image::Image<uint16_t> blend_images(image::Image<uint16_t> &img1, image::Image<uint16_t> &img2)
|
2022-09-08 19:48:06 +02:00
|
|
|
{
|
|
|
|
|
size_t width = std::min<int>(img1.width(), img2.width());
|
|
|
|
|
size_t height = std::min<int>(img1.height(), img2.height());
|
|
|
|
|
image::Image<uint16_t> img_b(width, height, img1.channels());
|
2022-09-23 20:46:41 +02:00
|
|
|
bool are_rgba = img1.channels() == 4 && img2.channels() == 4;
|
|
|
|
|
|
2022-09-08 19:48:06 +02:00
|
|
|
for (int c = 0; c < img1.channels(); c++)
|
|
|
|
|
{
|
2022-09-23 20:46:41 +02:00
|
|
|
if (are_rgba)
|
2022-09-08 19:48:06 +02:00
|
|
|
{
|
2022-09-23 20:46:41 +02:00
|
|
|
for (size_t i = 0; i < height * width; i++)
|
|
|
|
|
{
|
|
|
|
|
if (img1.channel(3)[i] == 0)
|
2022-10-04 23:14:45 +02:00
|
|
|
{
|
2022-09-23 20:46:41 +02:00
|
|
|
img_b.channel(c)[i] = img2.channel(c)[i];
|
2022-10-04 23:14:45 +02:00
|
|
|
img_b.channel(3)[i] = 65535;
|
|
|
|
|
}
|
|
|
|
|
else if (img2.channel(3)[i] == 0)
|
|
|
|
|
{
|
2022-09-23 20:46:41 +02:00
|
|
|
img_b.channel(c)[i] = img1.channel(c)[i];
|
2022-10-04 23:14:45 +02:00
|
|
|
img_b.channel(3)[i] = 65535;
|
|
|
|
|
}
|
2022-09-23 20:46:41 +02:00
|
|
|
else
|
2022-10-04 23:14:45 +02:00
|
|
|
{
|
|
|
|
|
img_b.channel(c)[i] = c == 3 ? 65535 : ((size_t(img1.channel(c)[i]) + size_t(img2.channel(c)[i])) / 2);
|
|
|
|
|
img_b.channel(3)[i] = 65535;
|
|
|
|
|
}
|
2022-09-23 20:46:41 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
for (size_t i = 0; i < height * width; i++)
|
|
|
|
|
{
|
|
|
|
|
if ((img1.channels() == 3 ? (uint64_t)img1.channel(0)[i] + (uint64_t)img1.channel(1)[i] + (uint64_t)img1.channel(2)[i] : img1.channel(c)[i]) == 0)
|
|
|
|
|
img_b.channel(c)[i] = img2.channel(c)[i];
|
2022-10-04 23:14:45 +02:00
|
|
|
else if ((img2.channels() == 3 ? (uint64_t)img2.channel(0)[i] + (uint64_t)img2.channel(1)[i] + (uint64_t)img2.channel(2)[i] : img2.channel(c)[i]) == 0)
|
2022-09-23 20:46:41 +02:00
|
|
|
img_b.channel(c)[i] = img1.channel(c)[i];
|
|
|
|
|
else
|
|
|
|
|
img_b.channel(c)[i] = (size_t(img1.channel(c)[i]) + size_t(img2.channel(c)[i])) / 2;
|
|
|
|
|
}
|
2022-09-08 19:48:06 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return img_b;
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-04 10:34:33 -05:00
|
|
|
image::Image<uint16_t> merge_images_opacity(image::Image<uint16_t> &img1, image::Image<uint16_t> &img2, float op)
|
2022-09-08 19:48:06 +02:00
|
|
|
{
|
|
|
|
|
size_t width = std::min<int>(img1.width(), img2.width());
|
|
|
|
|
size_t height = std::min<int>(img1.height(), img2.height());
|
|
|
|
|
image::Image<uint16_t> img_b(width, height, img1.channels());
|
2022-09-23 20:46:41 +02:00
|
|
|
bool are_rgba = img1.channels() == 4 && img2.channels() == 4;
|
|
|
|
|
|
2022-09-08 19:48:06 +02:00
|
|
|
for (int c = 0; c < img1.channels(); c++)
|
|
|
|
|
{
|
|
|
|
|
for (size_t i = 0; i < height * width; i++)
|
|
|
|
|
{
|
2022-09-23 20:46:41 +02:00
|
|
|
if (are_rgba)
|
2022-09-08 19:48:06 +02:00
|
|
|
{
|
2022-09-23 20:46:41 +02:00
|
|
|
if (op == 1.0)
|
|
|
|
|
{
|
|
|
|
|
if (img2.channel(3)[i] != 0)
|
|
|
|
|
img_b.channel(c)[i] = img2.channel(c)[i];
|
|
|
|
|
else
|
|
|
|
|
img_b.channel(c)[i] = img1.channel(c)[i];
|
|
|
|
|
}
|
|
|
|
|
else if (op == 0.0)
|
|
|
|
|
{
|
|
|
|
|
if (img1.channel(3)[i] != 0)
|
|
|
|
|
img_b.channel(c)[i] = img1.channel(c)[i];
|
|
|
|
|
else
|
|
|
|
|
img_b.channel(c)[i] = img2.channel(c)[i];
|
|
|
|
|
}
|
2022-09-08 19:48:06 +02:00
|
|
|
else
|
2022-09-23 20:46:41 +02:00
|
|
|
img_b.channel(c)[i] = img2.channel(3)[i] != 0
|
|
|
|
|
? std::min<int>(65535, img1.channel(c)[i] * (1.0f - op) + img2.channel(c)[i] * op)
|
|
|
|
|
: img1.channel(c)[i];
|
2022-09-08 19:48:06 +02:00
|
|
|
}
|
2022-09-23 20:46:41 +02:00
|
|
|
else
|
2022-09-08 19:48:06 +02:00
|
|
|
{
|
2022-09-23 20:46:41 +02:00
|
|
|
if (op == 1.0)
|
|
|
|
|
{
|
|
|
|
|
if (img2.channel(c)[i] != 0)
|
|
|
|
|
img_b.channel(c)[i] = img2.channel(c)[i];
|
|
|
|
|
else
|
|
|
|
|
img_b.channel(c)[i] = img1.channel(c)[i];
|
|
|
|
|
}
|
|
|
|
|
else if (op == 0.0)
|
|
|
|
|
{
|
|
|
|
|
if (img1.channel(c)[i] != 0)
|
|
|
|
|
img_b.channel(c)[i] = img1.channel(c)[i];
|
|
|
|
|
else
|
|
|
|
|
img_b.channel(c)[i] = img2.channel(c)[i];
|
|
|
|
|
}
|
2022-09-08 19:48:06 +02:00
|
|
|
else
|
2022-09-23 20:46:41 +02:00
|
|
|
img_b.channel(c)[i] = std::min<int>(65535, img1.channel(c)[i] * (1.0f - op) + img2.channel(c)[i] * op);
|
2022-09-08 19:48:06 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return img_b;
|
|
|
|
|
}
|
|
|
|
|
}
|