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

发布于 2024-10-17 06:08:51 字数 1043 浏览 3 评论 0原文

就像罐头上写的那样 我正在使用 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

知道如何我可以加载位图或以某种方式将其复制到内存中,这样文件本身就不会被锁定?
(所以我可以在加载后立即删除它)

Simply what it says on the tin
I'm loading a bitmap from a file using Bitmap::FromFile but afterwards I want to delete it from the disk.
The problem is, Bitmap::FromFile absolutely locks the file from any changes/deletion until the loaded image is unloaded

This is because I'm storing the bitmaps in a binary file, so I want to do it in this order:
1. extract the image from binary file
2. load the image
3. delete the file extracted in #1
(just some basic protection for my image resources, I just don't want them sitting in my program directory)

Bitmap::FromFile still locks the file from deletion even when cloning the loaded image from the file like in my attempt:

    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

Any idea how I can load a bitmap or somehow copy it to memory so the file itself wouldn't be locked ?
(So i can delete it a moment after loading it)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

起风了 2024-10-24 06:08:51

你可以这样做

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

You can do it this way

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;
}
满地尘埃落定 2024-10-24 06:08:51

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

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

Take a look at Bitmap::FromStream. You should be able to use SHCreateStreamOnFileEx to open an IStream on the file. After loading your bitmap you can safely delete the stream and then the temporary file.

If the binary file is only compressed with a supported algorithm, then pass the corresponding flag to SHCreateStreamOnFileEx and have it read the archive, bypassing the extraction of the image into a temp file. Otherwise can implement the IStream interface to read the binary file and extract your image data directly.

べ映画 2024-10-24 06:08:51

如果您对 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( ));

if you interested in MFC-OLE sample:

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( ));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文