gpt4 book ai didi

c++ - 阅读 PPM 图像问题

转载 作者:行者123 更新时间:2023-11-30 18:14:18 25 4
gpt4 key购买 nike

我在让我的算法成功读取 PPM 图像时遇到了很多麻烦......它对某些图像工作完美,但对其他图像则严重失败,导致半灰色(RGB 205、205、205)图像。

我已经尝试了我能找到的一切并研究了几个小时。我已经被困了一个星期了...

希望大家能帮忙。

    Image* pnm_read(char* filePath)
{
FILE* file;
char token[20];
int imageWidth, imageHeight, maximumColorValue;
Image* image;

/* Abre arquivo PNM. */
file = fopen(filePath, "r");
if (file == NULL)
{
fprintf(stderr, "Não foi possível localizar o arquivo de imagem %s.\n", filePath);
return 0;
}

/* Lê Magic Number do cabecalho e vê se é P6*/
pnm_get_token(file, token, sizeof token);
if (strcmp(token, "P6"))
{
fprintf(stderr, "%s não é um arquivo PPM válido.\n", filePath);
fclose(file);
return 0;
}

//Lê widht, height e valor máximo rgb
if (sscanf(pnm_get_token(file, token, sizeof token), "%d", &imageWidth) != 1 ||
sscanf(pnm_get_token(file, token, sizeof token), "%d", &imageHeight) != 1 ||
sscanf(pnm_get_token(file, token, sizeof token), "%d", &maximumColorValue) != 1)
{
fprintf(stderr, "%s não é um arquivo PNM válido.\n", filePath);
fclose(file);
return 0;
}

//Se não for RGB com componentes de 8 bits (0-255) dá erro
if (maximumColorValue != 255)
{
fprintf(stderr, "%s does not have 8-bit components: maximumColorValue=%d\n", filePath, maximumColorValue);
fclose(file);
return 0;
}

image = new Image(imageWidth, imageHeight);
unsigned char* pixelComponents = new unsigned char[imageWidth * imageHeight * 3];
fread(pixelComponents, sizeof(unsigned char), imageWidth * imageHeight * 3, file);
fclose(file);

int r, g, b, pixel;

for(int i = 3; i <= imageWidth * imageHeight * 3; i += 3)
{
r = pixelComponents[i-3] & 0xff;
g = pixelComponents[i-2] & 0xff;
b = pixelComponents[i-1] & 0xff;

/*fread(&r, sizeof(char), sizeof(char), file);
fread(&g, sizeof(char), sizeof(char), file);
fread(&b, sizeof(char), sizeof(char), file);

r = r & 0xff;
g = g & 0xff;
b = b & 0xff;*/

pixel = (255 << 24) | (r << 16) | (g << 8) | b;

// Atribuindo os pixels e virando imagem de cabeca para baixo
image->pixels[ (imageWidth * imageHeight) - (i/3) - 1] = pixel;
}

printf("Lido arquivo PNM (%s): %dx%d pixels.\n", filePath, image->width, image->height);

return image;
}

最佳答案

我已经修改了您的代码以使用结构来帮助理解和调试。我还删除了难以调试的片段,例如“(imageWidth * imageHeight) - (i/3) - 1”,并引入了一些临时变量来提供帮助。

一些注意事项:您的图像像素似乎包含 Alpha channel ,因此我在 RGBA 像素类型中添加了一个。编译指示还假定与 gcc 一致。我认为这是可以接受的,因为没有提到编译器。最后,这个例子更注重可读性而不是效率。有“更好”的方法来处理 RGB 和 RGBA 像素类型,但希望这能让您朝着正确的方向开始。

typedef unsigned char u8;   // define a more concise data type

// Save current packing to ensure the pixel struct is 3 bytes in size
#pragma pack(push)

// Pack on 1-byte boundaries
#pragma pack(1)


typedef struct
{
u8 red;
u8 green;
u8 blue;
u8 alpha;
} RgbaPixel;

typedef struct
{
u8 red;
u8 green;
u8 blue;
} RgbPixel;

// Restore previous packing
#pragma pack(pop)

Image* pnm_read(char* filePath)
{


FILE* file = NULL;
char token[20] = "";
int imageWidth = 0;
int imageHeight = 0;
int maximumColorValue = 0;
int numPixels = 0;
int numRead = 0;
Image* image = NULL;

/* Abre arquivo PNM. */
file = fopen(filePath, "r");
if (file == NULL)
{
fprintf(stderr, "Não foi possível localizar o arquivo de imagem %s.\n", filePath);
return 0;
}

/* Lê Magic Number do cabecalho e vê se é P6*/
pnm_get_token(file, token, sizeof token);
if (strcmp(token, "P6"))
{
fprintf(stderr, "%s não é um arquivo PPM válido.\n", filePath);
fclose(file);
return 0;
}

//Lê widht, height e valor máximo rgb
if (sscanf(pnm_get_token(file, token, sizeof token), "%d", &imageWidth) != 1 ||
sscanf(pnm_get_token(file, token, sizeof token), "%d", &imageHeight) != 1 ||
sscanf(pnm_get_token(file, token, sizeof token), "%d", &maximumColorValue) != 1)
{
fprintf(stderr, "%s não é um arquivo PNM válido.\n", filePath);
fclose(file);
return 0;
}

//Se não for RGB com componentes de 8 bits (0-255) dá erro
if (maximumColorValue != 255)
{
fprintf(stderr, "%s does not have 8-bit components: maximumColorValue=%d\n", filePath, maximumColorValue);
fclose(file);
return 0;
}

image = new Image(imageWidth, imageHeight);

numPixels = imageWidth * imageHeight;
RgbPixel* pixelComponents = new RgbPixel [numPixels];
numRead = fread(pixelComponents, sizeof(RgbPixel), numPixels, file);
fclose(file);

if (numRead != numPixels)
{
// Problem!

return 0;
}

RgbaPixel pixel = {0};

for (int i = 0; i < numPixels; i++)
{
pixel.alpha = 255;
pixel.red = pixelComponents[i].red;
pixel.green = pixelComponents[i].green;
pixel.blue = pixelComponents[i].blue;

// Atribuindo os pixels e virando imagem de cabeca para baixo
image->pixels[i] = pixel;
}

printf("Lido arquivo PNM (%s): %dx%d pixels.\n", filePath, image->width, image->height);

return image;
}

关于c++ - 阅读 PPM 图像问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16226878/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com