3921
2015-06-10 10:53:45
0
저도 예전에 기가단위 항공 영상 열때 고민 했던 문제네요 ㅎㅎㅎㅎ
비트맵을 잘게 쪼개서 관리 하게 되면 아웃오브 메모리는 안나와요. 다만 사용 하는 pc 의 메모리 여유량에 따라 틀려지지만.. 저같은 경우 2기가짜리 항공영상도 다 잘라서 메모리에 올려봤어요. 하지만 컴퓨터 특성도 타고 메모리는 엄청나게 잡아 먹어서 별로 추천하지 않습니다.
제가 쓰던 방식은 로딩이 조금 생기더라도 우선 파일은 하드에 두고 내가 보여주는 view 해주는 영역만 파일에 직접 접근해서 그때 그때 가져오는거죠.
전체 화면일때는 화면에 보여주는 가로세로 사이즈 대비 해서 샘플링한 데이터로 가져와서 최대한 데이터를 타이트하게 줄이는 방식입니다.
그러기 위해서는 해당 이미지 파일의 물리적인 형태를 알아야 한다는거죠.
파일 헤더는 몇 비트 부터 몇비트까지 실제 데이터는 몇비트부터 몇비트까지 등의 정보와 헤더를 읽어서 데이터가 가르키는 위치에 가서
영상을 가져와야 하는데.
데이터는 쭉 일렬로 있으니 가로 사이즈 단위로 끊어서 위치를 알아야 한다는 개념도 필요 하고요.
byte[,] bits = GetScanRange(heder, (long)y, (long)tempx1, (long)tempx);
이런식으로 줄단위로 영상을 읽어서 원하는 데이터만 가공해서 쓰는 형식도 좋고요..
이게 벌써 만든지 6년 전에 만든거라 메모리에 대한 개념이 희박할때라 좀 효율적이지 않았죠.
암튼
1. 파일 헤더 분석
2. 파일에 직접 접근해서 데이터를 byte 단위로 빼온다
3. 그 데이터를 bitmap 으로 만든다.
4. 그 비트맵 을 화면에 보여준다.
식으로 가면 됩니다.
아 저위에 GetScanRange 이건 미리 읽어놓은 헤더 데이터로 특정 위치부터 특정 위치까지 쭉 한방에 데이터를 긁어 오게 하는 함수를 만들어 놓은거에요.
byte[,] ScanLine = new byte[nEnd - nStart, tifHead.Depth / 8];
데이터 가져올 변수 하나 만들어서
file.Seek(DataStart, SeekOrigin.Begin);
파일 위치에 가서
ScanLine[i, (int)ColorRGBA.B] = (byte)file.ReadByte();
ScanLine[i, (int)ColorRGBA.G] = (byte)file.ReadByte();
ScanLine[i, (int)ColorRGBA.R] = (byte)file.ReadByte();
ScanLine[i, (int)ColorRGBA.A] = (byte)file.ReadByte();
각각 컬러별로 데이터 가져오는거죠.
뭐 이런식으로요..