C ++ .NET - 如何配置位图?

时间:2012-05-20 12:38:48

标签: c++ .net bitmap c++-cli

我想从文件加载位图,对其执行一些操作,并将其保存在相同的文件名下。模式是:

Bitmap in = gcnew Bitmap(fileName);
Bitmap out = gcnew Bitmap(in.Width, in.Height, in.PixelFormat);

fill [out] with data from [in]

out.Save(fileName);

但这不起作用。这很明显。我无法保存到仍然打开的文件(因为位图)。问题是:我怎么关闭位图?!我尝试了很多方法,但没有任何作用。调用Dispose在C#中工作,但此方法在C ++中受到保护。调用删除也不起作用。解决方案是什么?

编辑: 在一个位图上操作也不起作用。但我发现了一个问题。调用删除工作。我忘了将我的位图声明为指针

Bitmap^ in = gcnew Bitmap(fileName);
Bitmap^ out = gcnew Bitmap(in.Width, in.Height, in.PixelFormat);

fill [out] with data from [in]

delete in;
out.Save(fileName);

2 个答案:

答案 0 :(得分:1)

这是C ++ / CLI编码中的常见陷阱,您正在使用stack semantics。换句话说,您没有使用^帽子声明引用类型变量。这使编译器自动在作用域块的末尾发出Dispose()调用。非常方便,并且在C ++中模拟了RAII模式,但它在这里受到了影响。您希望在保存新位图之前处置in位图。

有两种方法可以做到这一点。您可以通过添加大括号来玩范围块游戏:

Bitmap^ out;
try {
    {
        Bitmap in(fileName);
        out = gcnew Bitmap(in.Width, in.Height, in.PixelFormat);
        // etc..
    }   // <== "in" gets disposed here
    out->Save(fileName);
}
finally {
    delete out;
}

但这有点难看,特别是因为在这个非常具体的情况下它需要与out混淆。另一种方法是明确地做所有事情:

Bitmap^ out;
Bitmap^ in;
try {
    in = gcnew Bitmap(fileName);
    out = gcnew Bitmap(in->Width, in->Height, in->PixelFormat);
    // etc..
    delete in;
    in = nullptr;
    out->Save(fileName);
}
finally {
    delete in;
    delete out;
}

答案 1 :(得分:0)

您不需要out位图。只需编辑in并保存即可。另外我建议使用CImage类

CImage image;
image.Load(filename);
fill [image] with whatever data you want
image.Save(filename);