2013-03-08 10 views
1

Bitmap.LockBits을 사용하여 가져온 BitmapData 개체를 사용하여 픽셀 데이터를 빠르게 읽고 쓰고 있습니다. 기능은 클래스에 캡슐화됩니다. BitmapData 개체의 Scan0Stride에 대한 참조를 저장할 수 있습니까? 아니면 픽셀에 액세스해야 할 때마다 읽어야합니까? 내 사용량을 기반으로 같은 클래스 개체는 시간 동안 활성화 될 수 있으며이 기간 동안 Scan0/Stride이 변경됩니까? 또는 부동산 액세스를 줄이기 위해 수업에 학생들에게 심판을 저장할 수 있습니까? 마다 (약간 느림)일정 기간 동안 BitmapData의 Scan0 또는 Stride가 변경 될 수 있습니까?

public BitmapData Data; 

byte* pixByte = (byte*)BmpData.Scan0 + (Y * BmpData.Stride) + (X * 3); // access pixel of 24bpp image 

저장 심판 (이 가능한가?)

통로 (따라서 Scan0) BitmapData에 대한 참조만을 유효한 동안이

public BitmapData Data; 
public IntPtr Scan0; 
public int Stride; 

byte* pixByte = (byte*)Scan0 + (Y * Stride) + (X * 3); // access pixel of 24bpp image 

답변

2

아니요, 아니요, 비트 맵의 ​​픽셀 데이터는 관리되지 않는 메모리에 저장됩니다. 이것이 BitmapData.Scan0의 형식이 IntPtr 인 이유입니다. 관리되지 않는 포인터는 값을 변경하지 않으므로 관리되지 않는 힙 관리자에 대해 압축 가비지 수집기와 동일한 기능이 없습니다.

그러나 비트 맵이 잠겨있는 동안에 만 유효합니다. 일반적으로 Bitmap.UnlockBits()를 빠르게 호출하는 것이 중요합니다. 잠금이 적용되는 동안 비트 맵 객체를 사용할 수 없습니다. 비트 맵을 페인팅하는 것과 같은 작업을 시도하면 비트 맵이 잠기는 동안 예외가 발생하여 실패합니다. 나중에 사용하기 위해 Scan0 포인터를 저장하는 것은 거의 항상 잘못된 작업입니다.

+0

당신은 모든 것에 대해 매우 잘 알고 있기 때문에 .NET에 대한 답을 철저히 수락합니다. 네가 가장 잘 알 것 같아. 좋은 답변을 주신 Hans에게 감사드립니다. –

0

인 당신은 Bitmap.Lockbits을 열었습니다. 일단 UnlockBits으로 전화하면 포인터는 더 이상 유효하지 않습니다.

효과적으로 해당 값을 캐시 할 수 없지만 비트 맵의 ​​색상 깊이와 크기가 변경되지 않는다는 것을 알고 있으면 픽셀 위치에 액세스하기위한 많은 계산을 제거하는 검색 테이블을 사전 계산할 수 있습니다 Stride (행의 너비)와 픽셀의 크기 (24bpp 색상 깊이의 경우 3 바이트). 기본적으로 정적 일 것입니다.