C ++ GDI +从文件加载图像,然后在*卸载图像之前删除文件*

时间:2011-02-12 13:57:59

标签: c++ file bitmap gdi+ locked

简直就是锡上的内容 我正在使用Bitmap :: FromFile从文件加载位图,但之后我想从磁盘中删除它。
问题是,Bitmap :: FromFile绝对锁定文件的任何更改/删除,直到加载的图像被卸载

这是因为我将位图存储在二进制文件中,所以我想按此顺序执行:
1.从二进制文件中提取图像
2.加载图像
3.删除#1中提取的文件 (只是对我的图像资源的一些基本保护,我只是不希望它们位于我的程序目录中)

Bitmap :: FromFile仍然会将文件从删除中锁定,即使从文件中克隆加载的图像也是如此:

    Bitmap* tempbmp = Bitmap::FromFile(fileanddir.c_str(),false);
    Rect temprect( 0, 0, tempbmp->GetWidth(), tempbmp->GetHeight() );

    // make the image to be used as a clone to the temporary
    // bitmap to avoid file locking
    image_to_be_used = tempbmp->Clone(temprect, PixelFormatDontCare);

    // delete temporary loaded bitmap since it shouldn't be needed
    delete tempbmp;

    // delete the file itself, too bad the file is locked
    int theresult = remove(tocharptr(fileanddir)); 
    // returns -1, also: manually deleting at this point gives the error
    // that the file is being used by another person/program

知道如何加载位图或以某种方式将其复制到内存中以便文件本身不会被锁定吗? (所以我可以在加载后删除它一段时间)

3 个答案:

答案 0 :(得分:4)

你可以这样做

Gdiplus::Bitmap* LoadImageFromFileWithoutLocking(const WCHAR* fileName) {
    using namespace Gdiplus;
    Bitmap src( fileName );
    if ( src.GetLastStatus() != Ok ) {
        return 0;
    }
    Bitmap *dst = new Bitmap(src.GetWidth(), src.GetHeight(), PixelFormat32bppARGB);

    BitmapData srcData;
    BitmapData dstData;
    Rect rc(0, 0, src.GetWidth(), src.GetHeight());

    if (src.LockBits(& rc, ImageLockModeRead, PixelFormat32bppARGB, & srcData) == Ok)
    {
        if ( dst->LockBits(& rc, ImageLockModeWrite, PixelFormat32bppARGB, & dstData) == Ok ) {
            uint8_t * srcBits = (uint8_t *) srcData.Scan0;
            uint8_t * dstBits = (uint8_t *) dstData.Scan0;
            unsigned int stride;
            if (srcData.Stride > 0) { 
                stride = srcData.Stride;
            } else {
                stride = - srcData.Stride;
            }
            memcpy(dstBits, srcBits, src.GetHeight() * stride);

            dst->UnlockBits(&dstData);
        }
        src.UnlockBits(&srcData);
    }
    return dst;
}

答案 1 :(得分:3)

看看Bitmap::FromStream。您应该可以使用SHCreateStreamOnFileEx在文件上打开IStream。加载位图后,您可以安全地删除流,然后删除临时文件。

如果二进制文件仅使用支持的算法进行压缩,则将相应的标志传递给SHCreateStreamOnFileEx并让它读取存档,从而绕过将图像提取到临时文件中。否则可以实现IStream接口来读取二进制文件并直接提取图像数据。

答案 2 :(得分:1)

如果您对MFC-OLE示例感兴趣:

CFile file;
CFileException fe;
CString strFileName = "C:\\yours.bmp";

if (!file.Open(strFileName, CFile::modeRead | CFile::shareDenyNone , &fe))
{
    return;
}
COleStreamFile stream;
if(!stream.CreateMemoryStream(NULL))
{
    return;
}
BYTE buf[1024];
int readed = 0;
do
{
    readed = file.Read(buf,1024);
    stream.Write(buf,readed);
}
while(readed > 0);

file.Close();
stream.SeekToBegin();
USES_CONVERSION;
m_pImage = new Gdiplus::Bitmap(stream.GetStream( ));