2010-04-07 2 views
4

일부 데이터의 매우 큰 그래픽 표현을 표시하려고합니다. 이미지의 영구 저장을위한 비트 맵을 사용하고 e.Graphics.DrawImage(myBitmap, new Point(0,0))은 내 양식의 PictureBox 컨트롤의 onPaint에 사용하고 있습니다. 나는 내 이미지의 높이 또는 너비가 2^15보다 큰 경우 Parameter not Valid 예외가 발생하지만이 제한에 대한 공식 문서를 찾지 못했다는 사실을 다른 사이트에서 언급 한 것으로 알고 있습니다.(C#) graphics.drawImage의 크기 제한이 있습니까? 어떻게 처리할까요?

이 2^15 이미지 크기 제한은 공식 Graphics.DrawImage의 한정적 부분입니까? 내 이미지 전체를 양식으로 렌더링하는 간단한 해결 방법이 있습니까?

가 (예,의 PictureBox는 이미지, 또는 더 큰과 같은 크기로 설정됩니다. 사이드 질문하지만,해야 그냥 폼 자체 대신 그림 상자의 OnPaint를를 사용?)

답변

5

여기에 몇 가지 문제가 있습니다. 첫째, 일반 스크린에 적합한 크기로 축소하지 않으면 서 이처럼 큰 이미지를 표시하는 것이 근본적으로 가능하지 않습니다 (거대하고 거대한 모니터 또는 다중 모니터 설정이없는 경우).

당신은 Graphics.DrawImage을 사용하여이 크기 감소를 수행하지만,이 의미에서도 고품질의 InterpolationMode으로, 보간 만 대부분 몇 이웃 픽셀 (A)에서 이루어집니다 마음에 유지할 수는 최대 금액에 제한 당신 심각한 정보 손실없이 이미지를 줄일 수 있습니다 (보통 25 % 이하).

두 번째로 .Net의 Bitmap 개체는 단순한 픽셀 배열보다 훨씬 복잡합니다. 비트 맵은 가끔씩 최대 프로그램 크기를 제한하는 비디오 RAM에서 생성됩니다 (컴팩트 프레임 워크에서는 비트 맵 생성자 중 하나가 비디오 RAM에 픽셀 데이터를 만듭니다. 일반적으로 .NET 프로세스에서 32MB를 사용할 수 있음). 결과적으로 Bitmap에 대한 최대 크기는 문서화되어 있지 않습니다. 이것은 프로그래머가 너무 어려운 경우 던져 예외를 발견 할 수있는 내부 구현 세부 사항입니다 (이미 존재하는 비트 맵의 ​​영향을 받음). . 따라서 임의의 큰 데이터 세트를 저장하기 위해 Bitmap을 사용하면 효과가 없습니다.

가장 좋은 접근법은 데이터를 OutOfMemoryException을 던지지 않고 임의로 커질 수있는 일반 2 차원 배열 (아마도 int[,] 유형)로 저장하는 것입니다 (컴퓨터를 스왑 파일로 만들지 않고도).) 다음이 배열에서 실제 (실제 크기) Bitmap으로 복사하는 사용자 지정 메서드를 작성합니다. 이 Bitmap에서 PictureBox으로 복사하거나 (이보다는 더 간단하게 그림 상자의 Image 속성으로이 값을 Bitmap으로 설정하십시오. 가능한 경우 Paint 방법을 사용하지 않는 것이 가장 좋습니다).

2

당신은 것입니다 이 제한에 도달하기 오래 전에 문제가 발생합니다. 약 10000x10000 픽셀 정도면 거의 모든 비트 맵 메모리를 사용하게됩니다. 내부 gdi + 비트 맵이 32bppargb가 될 것이라고 생각해보십시오. 계산시 픽셀 당 4 바이트 x 100000000 = 4GB가 필요합니다.

이미지를 타일로 나누거나 드로잉하는 경우 수동으로 페이징 솔루션을 구현해야합니다.

+0

수학이 약간 벗어 났을 것으로 생각됩니다. 2^15 (높이) * 2^15 (너비) * 2^2 (픽셀 당 * 바이트) = 2^32, 정확하게 4GB입니다.이것은 32 비트 시스템에 대한 메모리 제한이므로 비트 맵의 ​​예상 최대 크기를 나타내는 것으로 보입니다. –

+1

실제로 10 배로 벗어납니다. 감사. 나는 훨씬 작은 bmps가 gdi +와 C#을 무릎에 가지고 오는 것을 보았다. –

1

저는 C#을 사용하여 25200 x 15000 픽셀까지 비트 맵을 만들고 64 비트 응용 프로그램에서 Windows 폼을 빌드 할 수있었습니다. 아직 실험 중이지만 비트 맵 크기 제한에 대한 것 같습니다.