2011-02-12 3 views
2

주석으로 간단히 말합니다. Bitmap :: FromFile을 사용하여 파일에서 비트 맵을로드하지만 이후에 삭제하려고합니다. 디스크에서.
문제는 비트 맵 :: FROMFILE 절대적으로 변경에서 파일을 잠금입니다 /로드 된 이미지가 나는 바이너리 파일의 비트 맵을 저장하고있어 때문이다, 그래서 그것을 수행 할C++ GDI + 파일에서 이미지를로드 한 다음 파일을 삭제하기 전에 * 이미지를 언로드하기 전에

을 언로드 될 때까지 삭제 이 순서 :
1. 추출 이진 파일에서 이미지
2.로드 이미지가
3. #에서 추출 된 파일을 삭제 한
(내 이미지 리소스에 대한 단지 몇 가지 기본적인 보호, 난 그냥 그들을 원하지 않는 내 프로그램 디렉토리에 있음)

Bitmap :: FromFile이 파일을 계속 잠근다 fr 내 시도에 같은 파일에서로드 된 이미지를 복제, 심지어 톰 삭제 :

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

Bitmap::FromStream을 살펴보십시오. SHCreateStreamOnFileEx을 사용하여 파일에서 IStream을 열 수 있습니다. 비트 맵을로드 한 후 안전하게 스트림과 임시 파일을 삭제할 수 있습니다.

바이너리 파일이 지원되는 알고리즘으로 압축 된 경우 SHCreateStreamOnFileEx에 해당 플래그를 전달하고 이미지를 임시 파일로 추출하지 않고 아카이브를 읽게하십시오. 그렇지 않으면 IStream 인터페이스를 구현하여 이진 파일을 읽고 이미지 데이터를 직접 추출 할 수 있습니다.

+0

감사 할 수 있습니다! 작동하도록했습니다. 답변을 수락했습니다. – BNelsey

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()); 
3

당신은 이런 식

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

내 날을 저장했습니다. –

+1

이 코드는 애니메이션 이미지의 첫 번째 프레임 만 사용합니다. – zenden2k

관련 문제