2012-02-14 7 views
1

C/C++에서 PPM 파일을 저장하는 데 도움이 필요합니다. 세 가지 기본 색상 채널에서 PPM 이미지를 저장하고 싶습니다. 채널은 void * 포인터 (pRed, pGreen 및 pBlue)로 표시됩니다. 그 값들은 고정되어 있으므로 변경할 수는 없습니다.부호없는 char * 및 부호없는 short * 포인터 (RGB) (C++)에서 PPM 파일 만들기/저장

무효 포인터가 해석하는 방법을 결정하는 또 하나 개의 변수가있다 : 이 변수는 다음과 같습니다

BPP = 1 올바른 유형은 * 서명 숯불이다가. 버퍼 요소는 unsigned char 유형입니다.

bpp = 2 올바른 유형은 부호없는 short *입니다. 버퍼 요소는 unsigned short 유형입니다.

이제이 3 가지 색상 채널에서 ppm 파일을 저장합니다. BPP 변수에 대한

선언은 다음과 같습니다

//bpp=1: 
unsigned char* dRed = (unsigned char*)pImg->pRed; 
unsigned char* dGreen = (unsigned char*)pImg->pGreen; 
unsigned char* dBlue = (unsigned char*)pImg->pBlue; 
unsigned char* dBw = (unsigned char*)pImg->pBw; 

//bpp=2: 
unsigned short* dRed = (unsigned short*)pImg->pRed; 
unsigned short* dGreen = (unsigned short*)pImg->pGreen; 
unsigned short* dBlue = (unsigned short*)pImg->pBlue; 
unsigned short* dBw = (unsigned short*)pImg->pBw; 

ppm 단위 파일을 작성하는 내 코드 : 내가 바로 "구조"의를 얻을 수 있기 때문에

다음
ofstream output(fname, ios::binary|ios::out); 

output << "P3"<< endl <<"# foreground "<<endl; 
output << itoa(width, fname, 10); 
output << " "; 
output << itoa(height, fname, 10); 
output << endl; 
output << itoa(255, fname, 10) << endl; 
...  
for(int i=0; i<(height*width); i++){ 
    if(bytesPerP==1){ 
    output << (unsigned char)((char*)dRed) << " "; 
    output << (unsigned char)((char*)dGreen) << " "; 
    output << (unsigned char)((char*)dBlue) << " "; 
    dRed = dRed + (i * bytesPerP); 
    dGreen = dGreen + (i * bytesPerP); 
    dBlue = dBlue + (i * bytesPerP); 
}else if(bytesPerP==2){ 
    output << ((unsigned short)((char*)dRed))%256 << " "; 
    output << (unsigned short)((char*)dGreen)%256 << " "; 
    output << (unsigned short)((char*)dBlue)%256 << " "; 

    dRed = dRed + (i * bytesPerP); 
    dGreen = dGreen + (i * bytesPerP); 
    dBlue = dBlue + (i * bytesPerP); 
} 

가 어디 오류입니다 기록 된 이미지,하지만 색상이 완전히 이상한 (psychodelic 스타일) :) 나는 인터넷에서 검색하고 많은 것들을 테스트했지만, 그들 중 누구도 일하지 못했습니다. 누군가가 올바른 방향으로 나를 가리킬 수 있을까요?

+0

이상 없을 것 새로운 스타일 캐스팅 구문을 사용하려고 할 수 있습니다. – shuttle87

+0

문제는 포인터 값을 'unsigned char'또는 'unsigned short'로 캐스팅하는 것입니다 ... 그 포인터를 역 참조하고 캐스트하지 않으려합니다. – Jason

답변

1

문제는 이미지 버퍼에서 바이트를 출력하는 방법입니다. 실제 포인터 값을 출력하지 않고 실제 데이터 정보를 얻기 위해 포인터를 역 참조 할 필요가 있습니다. 예를 들어

이 :

output << (unsigned char)((char*)dRed) << " "; 

unsigned char에 4 또는 8 바이트 포인터 값 dRed 캐스트를 출력 ... 당신은 포인터 dRed어떤 일 것,를 가리키는 것으로 값을 원하는 이런 일 :

output << *dRed << " "; 

둘째, 각 컬러 채널에 대한 데이터가 별개의 연속 선형 어레이에 저장되어있는 경우 (즉, 적색 화소에만 적색 점, 녹색 점 t 오직 녹색 - 픽셀, 적색 - 픽셀, 녹색 - 픽셀, 그리고 파란색 - 픽셀 인 버퍼)와 비교할 때 채널당 16 비트의 경우 값을 정확하게 증가시키지 않습니다. 버퍼는 선형 배열 인 경우에, 당신은 단순히 다음 작업을 수행 할 수 있습니다 : 여분의 공백이 픽셀 값 샘플은 공백 문자로 둘러싸인해야 PPM 표준을 준수하는 것입니다

output << " " << dRed[i] << " " << dGreen[i] << " " << dBlue[i] << endl; 

. 이것은 C++ 프로젝트는 경우

마지막으로 출력하고있는 "일반"PPM 형식으로, 어떤 행은 70 개 당신은 확실히 그 한도를 초과거야 ... 자 ...

+0

이 게시물은 도움이되었지만 추가 오류가 발생했습니다. 나는 ppm에 최대 색 값을 쓰지 않았다. 그 때문에 색상이 잘못되었습니다 (색상 값이 255보다 큽니다). 다시 감사합니다 –