GDI+를 사용하여 인덱스 형식의 그림을 메모리로 가져오기


원본 이미지는 인덱스PixelFormat8bpIndexed 형식으로 15M 크기이지만 일반 이미지를 가져오는 방법에 따라 메모리로 가져오는 경우 60M을 차지합니다. 분석은 다음과 같습니다.
 
일반 그림을 가져오는 방법은 다음과 같습니다.
		Bitmap *pImage=Bitmap::FromFile(sourceFile); //         ,        File *fp   

		Bitmap *pBmp=new Bitmap(pImage->GetWidth(),pImage->GetHeight());

		Graphics *pG=new Graphics(pBmp);

		pG->DrawImage(pImage,0,0,pImage->GetWidth(),pImage->GetHeight());  //           

여기서,
Bitmap(          INT width,
    INT height,
    PixelFormat format
);

 
The default value is Pixel Format32bpARGB는 기본적으로 픽셀 32bit이기 때문에 픽셀 형식이 Pixel Format8bpIndexed일 때 원래 그림은 15M이고 메모리를 가져오면 60M을 차지한다.
 
-----------------------------------------------------------------------------------------------------
시험1:PixelFormat8bpIndexed 형식의 비트맵을 만들고 그 위에 그리기
		Bitmap *pImage=Bitmap::FromFile(sourceFile); //         ,        File *fp   

		Bitmap *pBmp=new Bitmap(pImage->GetWidth(),pImage->GetHeight(),PixelFormat8bppIndexed); //  PixelFormat8bppIndexed     ,       

		Graphics *pG=new Graphics(pBmp);//           ,    Graphics  

		pG->DrawImage(pImage,0,0,pImage->GetWidth(),pImage->GetHeight());  //           


결과: MFC는 오류를 보고하지 않았지만 그림을 그림에 그릴 수 없었고 모니터에 표시된 비트맵 그림은 검은색이었다
 
나중에 팔레트를 설치하지 않아서 그런지 팔레트를 추가했어요.
 
		Bitmap *pImage=Bitmap::FromFile(sourceFile); //         ,        File *fp   
		Bitmap *pBmp=new Bitmap(pImage->GetWidth(),pImage->GetHeight(),PixelFormat8bppIndexed); //  PixelFormat8bppIndexed     ,       
		Graphics *pG=new Graphics(pBmp);//           ,    Graphics  
		pG->DrawImage(pImage,0,0,pImage->GetWidth(),pImage->GetHeight());  //           



		ColorPalette *pal=(ColorPalette*)malloc(sizeof(ColorPalette)+256*sizeof(ARGB));
		pal->Count=256;
		pal->Flags=0;

		for (int m=0;m<256;m++)
		{
			pal->Entries[m]=Color::MakeARGB(255,m,m,m);
		}
		pBmp->SetPalette(pal);

시험 결과는 여전히 위와 같다. 그림을 그림에 그리지 않았고 비트맵의 픽셀은 모두 0이며 검은색 구역을 나타냈다
도대체 무슨 이유일까?많은 자료를 찾아보니 원래: 그림 픽셀 형식이 색인일 때Graphics 대상을 만들 수 없음(전기 블로그 참조http://blog.csdn.net/shuilan0066/article/details/6830183)
 
 
파일럿 2: Bitmap *Clone(const Rect &rect, Pixel Format format)을 사용하여 지정된 픽셀 형식의 그림으로 복사
 
 
  if (m_pMemBmp)
    {		
		delete m_pMemBmp;
		m_pMemBmp=NULL;
    }

	
    m_pMemBmp=new Bitmap(m_ImgW,m_ImgH,PixelFormat8bppIndexed);
	Rect rect(0,0,m_ImgW,m_ImgH);
	m_pMemBmp=m_pImage->Clone(rect,m_pImage->GetPixelFormat());

이렇게,mpMemBmp는PixelFormat8bppIndexed 포맷의 그림입니다. 그러나 이 프로그램을 여러 번 실행하면 메모리가 계속 증가하는 것을 발견할 수 있습니다. 그러나 다음에 실행할 때 저는 이미 deletempMemBmp;개척된 메모리를 삭제했는데 왜 늘릴까요?
몇 차례 분석한 결과, 원래 오류는 Clone () 함수에 나타났는데, 이 함수는 자동으로 메모리 더미에 크기가 rect이고, 픽셀 형식은 m 이다pImage->GetPixelFormat()의 메모리 영역이므로 new Bitmap(m ImgW, m ImgH,PixelFormat8bppIndexed)을 미리 열 필요가 없습니다.그렇지 않으면 자신이 개척한 메모리가 방출되지 않기 때문에 메모리가 끊임없이 증가할 것이다.
올바른 작업은 다음과 같습니다.
  if (m_pMemBmp)
    {		
		delete m_pMemBmp;
		m_pMemBmp=NULL;
    }
	
	Rect rect(0,0,m_pImage->GetWidth(),m_pImage->GetHeight());
	m_pMemBmp=m_pImage->Clone(rect,m_pImage->GetPixelFormat());

이렇게 하면 원 그림은 어떤 격식이고, 메모리 속의 그림은 어떤 격식이다.15M의 그림을 메모리에 불러오면 60M의 공간을 차지하지 않습니다.
그러나 파일 포인터에서 직접 clone()로 만들어진 비트맵은 new Bitmap()에서 생성된 비트맵보다 읽기와 쓰기 속도가 빠르지 않은데 무슨 이유인지 읽기와 쓰기 속도를 만족시키지 못할 경우 변환해야 한다.추가 정보 참조:http://blog.csdn.net/shuilan0066/article/details/6833711
물론 메모리가 허락된다면 일반적인 메모리 가져오는 방법에 따라 할 수 있다. 단지 다중 점포 메모리일 뿐이지, Graphics를 사용하여 이 메모리에 그림을 그릴 수 있기 때문이다.
      
 
 
 
 
 
 
 
 
 

좋은 웹페이지 즐겨찾기