2011-10-30 5 views
3

BMP.Height 또는 BMP.Width를 설정하려고 할 때 BMP 파일로 작업하려고하면 "EOutofresources - 저장 공간이 충분하지 않습니다"라는 메시지가 나타납니다. 이러한 지침을 수행 한 후에 스택 추적은 다음과 같습니다 (이 순서대로) : ntdll.dll.RtlLeaveCriticalSection, kernel32.dll.FileTimeToDosDateTime, GDI32.dll.GdiReleaseDC, GDI32.dll.PatBlt, kernel32.dll.ReadFile 또는 이와 유사 :비트 맵으로 작업 할 때 "저장 공간이 부족합니다"오류가 발생했습니다.

|7E429130|user32.dll   GetParent     
|7C90FF2D|ntdll.dll   RtlGetNtGlobalFlags  
|77F15A00|GDI32.dll   GdiReleaseDC 
|7C83069E|kernel32.dll  FileTimeToDosDateTime 
|7C9010E0|ntdll.dll   RtlLeaveCriticalSection 
|  |my function (where I set BMP.Height or BMP.Width) 

순간에 나는 메모리 조각화로 무언가를해야한다고 확신했다. 시스템은 내 이미지를 처리하기에 충분한 양의 램이 있었지만 메모리가 조각 났으므로 내 이미지를 저장할만큼 큰 블록이 없었다. 그러나 Windows를 시작한 후 11 초에 한 번 발생했습니다. 내 프로그램은 이미지를 한 번만 처리하는 루프를 순환합니다! 따라서 RAM 조각화와 관련이 없습니다.

다른 상황 (하지만 여전히 도면 관련) 나는이 오류가 발생했습니다 경우는 다음과 같습니다 :

|77F16A7E|GDI32.dll   IntersectClipRect  
|77F16FE5|GDI32.dll   BitBlt    
|7E429011|user32.dll   OffsetRect   
|7E42A97D|user32.dll   CallWindowProcA   
|7E42A993|user32.dll   CallWindowProcA   
|7C9010E0|ntdll.dll   RtlLeaveCriticalSection 
|7E4196C2|user32.dll   DispatchMessageA  
|7E4196B8|user32.dll   DispatchMessageA  
|0058A2E1|UTest.exe   UTest.dpr 
|7C90DCB8|ntdll.dll   ZwSetInformationThread 

내가 BMP.Height 후 스택 추적에서 'RtlLeaveCriticalSection'호출이 항상있다 생각합니다.

Windows 레지스트리 키를 편집하여 가능한 해결책을 가리키는 this 게시물이 있습니다. 그러나이 게시물은 Windows XP에만 적용됩니다. 내 오류 승 7


에도 나타납니다 동안 나는 그러나 그는 오류를 수정보고 돌아 왔어요 아무도 때까지 (그들 중 일부는 디스크에 파일을 저장하는 연결 가까운) 많은 유사한 게시물을 참조하십시오.


는 업데이트 :

요청한 바와 같이,이 오류가 나타납니다 코드 : 내 실험에서

procedure TMyBitmap.SetLargeSize(iWidth, iHeight: Integer); 
CONST ctBytesPerPixel= 3; 
begin 
{ Protect agains huge/empty images } 
if iWidth<  1 then iWidth:=  1 else 
if iWidth> 32768 then iWidth:= 32768; 

if iHeight<  1 then iHeight:=  1 else 
if iHeight> 32768 then iHeight:= 32768; 

{ Set image type } 
if iWidth * iHeight * ctBytesPerPixel > 9000000 {~9MB}      
then HandleType:= bmDIB           { Pros and cons: -no hardware acceleration, +supports larger images } 
else HandleType:= bmDDB;              

{ Total size is higher than 1GB? } 
if (iWidth* iHeight* ctBytesPerPixel) > 1*GB then 
    begin 
    Width := 8000;               { Set a smaller size } 
    Height := 8000;               { And rise an error } 
    RAISE Exception.Create('Image is too large.'); 
    end; 

{ Set size } 
Width := iWidth;       <----------------- HERE 
Height:= iHeight; 
end; 
+1

소스 코드를 표시하십시오. 메모리 문제보다 리소스 누출 (즉, 핸들 누출) 소리가납니다. – Yahia

+0

비트 맵의 ​​크기는 얼마입니까? –

+0

비트 맵의 ​​크기는 제한되지 않습니다. 일반적으로 일반 디지털 카메라 사진 (4-16 Mpixels)이어야합니다. – Ampere

답변

4

는, 최대 비트 맵 크기에 따라 달라집니다

  • OS 버전 (예 : XP는 세븐보다 작은 비트 맵 리소스를 허용합니다).
  • OS 버전 (64 비트 OS는 32 비트 OS보다 더 큰 리소스 할당을 허용).
  • 현재 설치된 RAM (무료);
  • 이미 할당 된 비트 맵 수 (공유 된 리소스이기 때문에).

엄청난 양의 데이터로 작업을 시작할 때 (비트 맵 해상도 이상) 비트 맵 할당을 성공적으로 수행 할 수 있는지 확신 할 수 없습니다.

  • 비트 맵 리소스를하지 할당,하지만, 작업을 직접 Win32에서 비트 블리트 API를 사용하는 일반 메모리 블록을 그릴 - :

    다음은 몇 가지 잠재적 인 솔루션 (나는 그들 중 일부를 사용했습니다)이 있습니다 하지만 일부 전용 프로세스 기능을 작성하거나 일부 타사 라이브러리를 사용해야하고 32 비트 OS에서 IMHO VirtualAlloc API (큰 블록 메모리를 위해 FastMM4에서 호출 한 API)는 더 많은 메모리를 할당 할 수 없습니다. 하나의 인접 메모리;

  • 이전 버전의 기능 향상 : 거대한 RAM 블록 (환영 XE2 컴파일러)을 처리하기 위해 64 비트 프로세스를 사용하거나 임시 저장을 위해 파일을 사용하고 처리를 위해 내용을 메모리 맵핑합니다 (PhotoShop 또는 기타 핸들 거대한 메모리) - 충분한 RAM을 가지고 있다면, 임시 파일을 사용하는 것이 더 느릴 필요가 없습니다 (디스크에 데이터가 기록되지 않습니다);
  • 큰 그림을 작은 그림으로 바둑판 식으로 배열하십시오. JPEG 라이브러리는 그림의 일부만 렌더링 할 수 있으며 쉽게 비트 맵 리소스에 맞습니다.
  • 모든 비트 맵 리소스가 공유되므로 모든 비트 맵 리소스가 공유되지 않도록하십시오 (예 : 비트 맵에서 읽는 경우 해당 내용을 임시 메모리 블록이나 파일에 복사하고 해당 리소스를 릴리스 한 다음 목적지 비트 맵;
  • 성능에 대해 제대로 작성한 다음 빠르게 처리하십시오. 구현 초기에 "트릭"을 포함하지 마십시오 (고객은 몇 초 동안 기다릴 수는 있지만 전역 오류는 허용하지 않음).

완벽한 솔루션이 없습니다. (내 선호는 프로세스에 대해 쉽게 멀티 스레드가 가능하다는 장점이 있기 때문에 작은 그림을 사용하는 것이므로 새 CPU로 많은 작업을 할 수 있습니다). 리소스 할당은 새로운 64 비트 Windows 7 PC에서는 작동하지만 고객의 32 비트 XP 컴퓨터에서는 작동하지 않을 수 있습니다.

관련 문제