【问题标题】:How to overlay one image on top of another? C++如何将一张图像叠加在另一张图像之上? C++
【发布时间】:2013-05-22 05:21:21
【问题描述】:

我有两个 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() 循环的样子:

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;
        }

    }
}

显然它仍然需要工作。

【问题讨论】:

  • 你的bool Pixel::operator==(const Pixel&amp; other)不应该返回反向值吗?
  • @Spook Ha,你是对的。当我作为操作员使用它时,我不小心把它留下了!=。我想我找到了问题的根源......在我无法编辑 .g 和 .b 值之后。这是我加载图像的方式,不知何故它搞砸了(P6格式)。我可以将顶部图像的轮廓覆盖到底部图像上。所以一些调整,可能会完成。

标签: c++ image overlay


【解决方案1】:

这行看起来不对:

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);
}

最后,既然你有一个相等运算符,那么为什么不使用 add 和 assignment ('=') 来保持你的编码器尽可能整洁

【讨论】:

    猜你喜欢
    • 2011-01-29
    • 1970-01-01
    • 2014-07-07
    • 1970-01-01
    • 1970-01-01
    • 2019-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多