从unsigned char *和unsigned short *指针(RGB)创建/保存PPM文件(C ++)

时间:2012-02-14 18:33:43

标签: c++ image ppm

我需要帮助在C / C ++中保存PPM文件。我想从三个基本颜色通道中保存PPM图像。通道表示为void *指针(pRed,pGreen和pBlue)。这些值是固定的,所以我无法改变它们。

还有一个变量来决定如何解释void指针: 这个变量是:

bpp = 1正确的类型是unsigned char *。缓冲区元素的类型为unsigned char

bpp = 2正确的类型是无符号短*。缓冲区元素的类型为unsigned short。

现在我将从这三个颜色通道中保存一个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;

我写代码文件的代码:

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);
}

这是错误的任何地方,因为我得到了正确的&#34;结构&#34;记录的图像,但颜色是完全奇怪的(psychodelic样式):) 我在互联网上搜索并测试了很多东西,但没有一个能够工作。有人能指出我正确的方向吗?

1 个答案:

答案 0 :(得分:1)

问题是如何从图像缓冲区输出字节...你需要取消引用指针来获取实际的数据信息,而不是输出实际的指针值本身。

例如,这个:

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

将4或8字节指针值dRed输出到unsigned char ...您希望指针dRed 指向的值,这将是这样做的:

output << *dRed << " ";

其次,如果每个颜色通道的数据存储在单独的连续线性阵列中(即,红色指向仅红色像素,绿色指向仅绿色像素,而对于缓冲区,其中它是红色像素,然后是绿色像素,然后是蓝色像素),那么你不会在每个16位的通道情况下正确递增值。如果缓冲区是线性阵列,您只需执行以下操作:

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

其中额外的空格要符合PPM标准,其中像素值样本应该用空格字符包围。

最后,在你输出的“普通”PPM格式中,没有行应该超过70个字符......你肯定会超过这个限制......