2013-10-31 1 views
7

비트 맵 저장시 GDI + 일반 오류는 분명히 SO와 웹에 대한 내 연구에 따르면 일반적인 문제입니다. 단순화 된 스 니펫을 보면 다음과 같습니다.GDI + LockBits를 사용하여 메모리에서 생성 된 일반 오류 저장

byte[] bytes = new byte[2048 * 2048 * 2]; 

for (int i = 0; i < bytes.Length; i++) 
{ 
    // set random or constant pixel data, whatever you want 
} 

Bitmap bmp = new Bitmap(2048, 2048, PixelFormat.Format16bppGrayScale); 
BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, 2048, 2048), ImageLockMode.ReadWrite, bmp.PixelFormat); 
System.Runtime.InteropServices.Marshal.Copy(bytes, 0, bmpData.Scan0, 8388608); 
bmp.UnlockBits(bmpData); 
bmp.Save(@"name.bmp"); 

결과로 0x80004005 일반 오류가 발생합니다. 이것에 대한 일반적인 이유는 구성 요소에 자물쇠라고하지만, 난 아무것도 볼 수 없어. 난 그냥 장님인가요? 저장하고있는 경로가 존재합니다. 물론 비어있는 bmp 파일 만 생성됩니다 (0B).

배경 : C++/CLI 래퍼를 사용하여 .NET으로 전송하는 카메라 드라이버에서 픽셀 데이터를 가져오고 있으므로 위의 Bitmap 객체는 함수 호출에서 반환됩니다. 그러나이 작은 예제가 이미 실패했기 때문에 어댑터에 문제가 없다고 생각합니다.

모든 의견을 보내 주시면 감사하겠습니다.

+0

16 비트 그레이 스케일은 유효한 bmp 형식이 아닐 수도 있습니다. –

+0

솔직히 생각하지 않았습니다. 인덱싱 된 8bpp로 전환하면 오류없이 파일이 생성됩니다. 궁극적 인 목표는 그레이 스케일 16bpp 이미지를 PNG로 저장하는 것입니다.하지만 위 코드를'bmp.Save (@ "name.bmp", ImageFormat.Png);로 대체하는 것은 효과가 없습니다. – simd

+0

저장시 ImageFormat.Bmp를 지정해 보셨습니까? 이 답변보기 : http://social.msdn.microsoft.com/Forums/vstudio/en-US/10252c05-c4b6-49dc-b2a3-4c1396e2c3ab/action?threadDisplayName=writing-a-16bit-grayscale-image – Ben

답변

15
Bitmap bmp = new Bitmap(2048, 2048, PixelFormat.Format16bppGrayScale); 

GDI + 예외는 다소 가난하므로 두 가지 실수를 진단 할 필요가 거의 없습니다. 작은 하나는 Save() 호출이며 저장하려는 ImageFormat은 지정하지 않습니다. 기본값은 원하는대로 BMP가 아닌 PNG입니다.

하지만 핵심 요소는 PixelFormat.Format16bppGrayScale입니다. .NET이 등장하기 오래 전에 GDI +가 설계되었을 때 모든 사람들은 여전히 ​​LCD 모니터 대신 CRT를 사용하고있었습니다. CRT는 색 영역을 표시하는 데 상당히 뛰어났습니다. 좋았지 만 주류 CRT는 없었으며 65536 개의 회색 색상을 표시 할 수있었습니다. 비디오 어댑터의 DAC는 디지털 픽셀 값을 CRT의 아날로그 신호로 변환하는 칩으로 대부분 제한됩니다. 100MHz 이상의 16 비트 정확도로 변환 할 수있는 DAC는 아직 기술적으로 실현 가능하지 않았습니다. Microsoft는 언젠가 가능하도록 디스플레이 기술을 도박했습니다. 언젠가는 Format16bppGrayScale을 언젠가 일 수있는 픽셀 형식으로 지정했습니다.

그런 일은 없었습니다. 오히려 반대의 LCD는 색 분해능이 현저히 떨어집니다. 일반적인 LCD 패널은 픽셀 형식에서 사용할 수있는 8 비트가 아닌 6 비트 색상 만 해결할 수 있습니다. 16 비트 컬러 해상도를 얻으려면 기술적 인 획기적인 기술이 필요합니다.

따라서 픽셀 형식이 유용하지 않으므로 GDI +에는 실제로 16bpp 회색조 이미지 형식을 쓸 수있는 이미지 인코더가 없습니다. Kaboom이 당신이 선택한 ImageFormat에 상관없이 디스크에 저장하려고 할 때.

16bpp 회색조가 실제로 사용되는 경우 방사선 촬영에서 해당 픽셀 형식을 사용합니다. 매우 비싼 디스플레이로 실제로 유용합니다. 그러나 그러한 장비는 변함없는 맞춤형 이미지 포맷을 사용하여 DICOM이 일반적인 선택입니다. GDI +에는 코덱이 없습니다.

고객이 원하는 이미지 형식을 지원하는 라이브러리를 구입해야합니다. 리드 도구는 해당 제품 분야에서 천 파운드 고릴라입니다.

+0

자세한 설명을 해주셔서 감사합니다. 설명이있는 배경을 얻으 려합니다. 여기에서의 포인트는 이미지가 디스플레이에 사용되는 것이 아니라 소프트웨어로 분석하는 것입니다. 이미지는 시간 경과 현미경으로 얻었으며 16 비트는 8 비트보다 훨씬 더 많은 옵션을 제공합니다. 그래서 여분의 lib와 함께 가야한다면 WIC가 여기에서 작동할까요 (이미 카메라 어댑터에서 연결되어 있습니다). 아니면 libpng로 돌아 가야합니까? – simd

+3

이 경우 지원되는 이미지 형식으로 커밋되지 않았습니다. 현명한 일은 여기에 데이터를 저장하는 것입니다. BinaryWriter가 할 수 없었던 것은 없습니다. –

+1

16 비트 비트 맵은 범위 데이터 (예 : Kinect에서 생성 한 것과 같은)에도 유용합니다. – Eponymous

관련 문제