У меня есть два изображения RGB (формат ppm), и я хочу иметь возможность накладывать любой пиксель, который не является чисто черным, на нижнем изображении.
Я могу успешно загружать изображения, сохранять изображения, копировать изображения … но я не могу создать изображение из двух изображений так, как я описал выше.
Я не собираюсь включать весь код, который у меня есть, но важные части для достижения этого:
struct Pixel
{
unsigned int r;
unsigned int g;
unsigned int b;
}
Я перегружен оператором == для более простого сравнения:
bool Pixel::operator==(const Pixel& other)
{
if(r != other.r)
{
return true;
}
else if(g != other.g)
{
return true;
}
else if(b != other.b)
{
return true;
}
else
{
return false;
}
}
В моем классе Pic у меня есть этот метод:
Pic Pic::overlay(const Pic& top, Pixel mask)
{
for(int h = 0; h < height; h++)
{
for(int w = 0; w < width; w++)
{
if(!(top.pixels[h][w] == mask))
{
pixels[h][w] = top.pixels[h][w]; // pixels[][] is a Pixel array
}
}
}
return *this;
}
Мой основной файл имеет это:
Pic top;
Pic bot;
Pic overlay;
Pixel mask:
mask.r = 0;
mask.g = 0;
mask.b = 0;
top.loadimage("top.ppm"); //loadimage() loads the image in and all the data
bot.loadimage("bot.ppm"); //samme thing
overlay = bot.overlay(bot, mask);
overlay.saveimage("overlay.ppm");
Очевидно, оператор = перегружен для класса Pic.
Вот такие у меня проблемы:
В методе наложения, если я оставлю оператор if, как описано выше, верхнее изображение будет отображаться в сохраненном файле. Если я сделаю это без! (), Он покажет нижнее изображение.
Если я полностью избавлюсь от этого оператора if () и попытаюсь изменить отдельные пиксели, например:
pixels[h][w].r = pixels[h][w].r - 50;
Сохраненное изображение будет изменено, все выглядит странно, по понятным причинам.
Однако … .b и .g не влияют на изображение.
У меня нет идей … Я играл с этим в течение 2 дней, и я не могу понять, что не так. В моей программе все работает как нужно, кроме этого метода наложения.
РЕДАКТИРОВАТЬ: Итак, я обнаружил одну из проблем в своем коде, и она вернулась к тому, как я загружал изображения в формате PPM P6. Вместо того, чтобы отдельно загружать каждый пиксель как 1 байт, я пытался загрузить их все вместе, поэтому он создал такие амортизационные элементы, которые происходят со структурами и двоичным чтением при сжатии … Теперь я могу наложить верхнее изображение на нижнее изображение, но не все цвета показывают. Тем не менее, лучше, чем раньше.
Вот что я изменил в цикле вложенного для () оверлея, чтобы он выглядел так:
for(int h = 0; h < height; h++)
{
for(int w = 0; w < width; w++)
{
if(top.pixels[h][w].r != mask.r &&
top.pixels[h][w].g != mask.g &&
top.pixels[h][w].b != mask.b )
{
pixels[h][w].r = top.pixels[h][w].r;
pixels[h][w].g = top.pixels[h][w].g;
pixels[h][w].b = top.pixels[h][w].b;
}
}
}
Очевидно, это все еще требует работы.
Эта строка выглядит неправильно:
overlay = bot.overlay(bot, mask);
Не должно ли это быть:
overlay = bot.overlay(top, mask);
И если вам нужен более короткий способ написания теста на равенство, то вам может понравиться это:
bool Pixel::operator==(const Pixel& other)
{
return (r==other.r && g==other.g && b==other.b);
}
Наконец, поскольку у вас есть оператор равенства, почему бы не добавить и не присвоить (‘=’), чтобы ваш кодер был как можно более аккуратным?
Других решений пока нет …