2013-03-08 4 views
0

픽셀 데이터에 직접 액세스하여 Bitmap 개체를 만들어야합니다.Marshal.AllocHGlobal으로 할당 된 메모리가 손상 되었습니까?

LockBits은 내 요구에 비해 속도가 너무 느립니다. 빠르게 (때로는 큰) 비트 맵을 재현하기에는 좋지 않습니다.

그래서 맞춤 FastBitmap 개체가 있습니다. Bitmap 개체에 대한 참조와 비트 맵의 ​​비트를 가리키는 IntPtr이 있습니다.

생성자는 다음과 같다 :

public FastBitmap(int width, int height) 
{ 
    unsafe 
    { 
     int pixelSize = Image.GetPixelFormatSize(PixelFormat.Format32bppArgb)/8; 
     _stride = width * pixelSize; 

     int byteCount = _stride * height; 

     _bits = Marshal.AllocHGlobal(byteCount); 

     // Fill image with red for testing 
     for (int i = 0; i < byteCount; i += 4) 
     { 
      byte* pixel = ((byte *)_bits) + i; 
      pixel[0] = 0; 
      pixel[1] = 0; 
      pixel[2] = 255; 
      pixel[3] = 255; 

     } 

     _bitmapObject = new Bitmap(width, height, _stride, PixelFormat.Format32bppArgb, _bits); // All bits in this bitmap are now directly modifiable without LockBits. 

    } 
} 

할당 된 메모리는 deconstructor 의해 호출되는 함수에 정리 해제된다.

오래 사용할 수 있지만 작동하지 않습니다. 어떻게 든 비트를 더 이상 수정하지 않으면 할당 된 메모리가 손상되어 비트 맵이 손상됩니다. 때로는 비트 맵의 ​​큰 부분이 무작위 픽셀로 바뀌고 다른 하나는 무작위로 완전히 Graphics.DrawImage 중 하나를 표시하려고 할 때 전체 프로그램이 충돌합니다.

+0

garbagecollector가 Bitmap 개체 주위를 돌고있을 가능성이 있습니다. 어쩌면 당신은 [핀] (http://stackoverflow.com/questions/2490912/what-are-pinned-objects) 그것 – rene

+0

당신이 어떻게 작동 할 수 자세히 설명해 주시겠습니까? 이 방법을 구현하는 방법에 대해 혼란스러워하고 개체를 고정하면 관리되지 않는 메모리가 손상되는 것을 막을 수 있는지 확실하지 않습니까? – user1092719

답변

1

FastBitmap을 사용한 후에 Bitmap.Clone을 사용하여 _bitmapObject을 복사했기 때문에 메모리가 손상된 이유가있었습니다.

Bitmap.Clone은 호출 할 때 픽셀 데이터의 새 사본을 만들지 않으며, 또는 적어도 자신이 할당 한 데이터로 Bitmap을 생성하는 경우입니다.

대신 복제 작업 후에 픽셀 데이터 메모리가 해제되어 메모리가 다른 것들에 사용될 때 복제 된 비트 맵이 손상 될 수 있기 때문에 복제는 똑같은 픽셀 데이터를 사용하는 것처럼 보입니다. 하고, 다른 곳에서 픽셀 데이터를 복사 않는

Bitmap clone = new Bitmap(bitmapToClone);

괜찮 기존의 메모리를 해제 :

내가 Bitmap.Clone에 대한 대안으로 발견 한 첫 번째와 현재의 솔루션을 사용하는 것입니다.

완벽하게 복제 된 복제본을 만드는 방법이 더 좋을 수도 더 빠를 수도 있지만 지금은 간단한 해결책입니다.

관련 문제