读取PPM像素作为RGB整数



因此,我的代码包括读取PPM图像,然后将其存储在数组中,以便将其保存在新的PPM文件中。尽管我认为我的指针有问题,这意味着它实际上并没有读取文件。此外,我的代码在为数组分配内存后结束。非常感谢您的帮助。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define maxheight 1080
#define maxwidth 1920
#define RGB_COMPONENT_COLOUR 255
#define pgmtype "P2"
#define ppmtype "P3"
typedef struct
{
    int red, green, blue;
} PPMPixel;
typedef struct
{
    int x, y;
} PPMImage;
typedef struct 
{
    int rgb_comp_colour;
    char filetype[3];
    int height;
    int width;
} PPMHead;

/*PPMHead head[3];
{
    head[3].filetype;
    head[3].height;
    head[3].width;
}*/
PPMHead head;
PPMHead* head_ptr = &head;
PPMPixel p;
PPMPixel* p_ptr = &p;
PPMPixel *data; //Defines pointer to PPMPixel
int **Array; //Double pointer defines as a pointer pointing to a pointer that is pointing to an integer
PPMPixel **RGBArray; //Double pointer defines as a pointer pointing to a pointer that is pointing to the PPMPixel structure
FILE *fp;
int r, g, b;
void headercheck ()
{
    fscanf(fp, "%s %d %d %d", head.filetype, &head.width, &head.height, &head.rgb_comp_colour);
    printf("%s %d %d %d", head.filetype, head.width, head.height, head.rgb_comp_colour);
    if (head.width > maxwidth || head.height > maxheight)
    {
        printf("tInvalid image size. The maximum value of image is 1920x1080.n");
        printf("tImage size is %d x %dn", head.width, head.height);
    }
    else
    {
        printf("tImage size is validn");
        printf("tImage size is %d x %dn", head.width, head.height);
    }
    if ((strcmp (head.filetype, pgmtype)!=0) && (strcmp (head.filetype, ppmtype)!=0))
    {
        printf("tInvalid filetypen");
    }
    else
    {
        if(strcmp (head.filetype, pgmtype)==0)
        {
            printf("t File is PGM type imagen");
        }
        else
        {
            if(strcmp (head.filetype, ppmtype)==0)
            {
                printf("t File is PPM type imagen");
            }
        }
    }
    if ((head.rgb_comp_colour == RGB_COMPONENT_COLOUR))
    {
        printf("t Image is 8 bitn");
    }
    else
    {
        if (head.rgb_comp_colour > RGB_COMPONENT_COLOUR)
        {
            printf("Maximum bit-depth is 8 bitsn");
        }
        else
        {
            printf("tImage is not 8 bitn");
        }
    }
}
int main(void)
{
    char fname[100];
    printf("Enter file name: ");
    scanf("%s", fname);
    fseek(stdin,0,SEEK_END);
    fp = fopen(fname, "r");
    if (fp == NULL)
    {   
        printf("tError while opening the filen");
    }                        
    else    
    {
        printf("tReading in %sn", fname);
    }
    headercheck();
    if (strcmp (head.filetype, ppmtype)==0)
    {
        RGBArray = (PPMPixel **)malloc(head.height*sizeof(PPMPixel*)); //Points to malloc
            if((RGBArray == NULL))
                {
                    printf("Error allocating memory to the array");
                }
                else
                {
                    printf("Memory allocated to the PPM array sucessfully");
                }
        for (int i=0;i<head.width;i++)
        {
            RGBArray[i] = (PPMPixel *)malloc(head.width*sizeof(PPMPixel));
        }
        
        printf("Error 2");
        //Initialising each element
        for (int j=0;j<head.height;j++)
        {
            for (int i=0;i<head.width;i++)
            {
                fscanf(fp, "%3d %3d %3d ", &p.red, &p.green, &p.blue); //Scans in integers of the address pointer to PPMPixel
                data = &RGBArray[i][j]; //Defines data pointer pointing to address of RGBArray[i][j]
                data->red = p.red; //Access member of PPMPixel structure to equal one of the three RGB channels
                data->green = p.green;
                data->blue = p.blue;
            }
        }
    }
    fclose(fp);
    
    //Save PPM Array Into New PPM File
    FILE *pf;
    int i, j;
    char fname2[100];
    printf("Enter file name: ");
    scanf("%s", fname2);
    fseek(stdin,0,SEEK_END);
    pf = fopen(fname2, "w");
    if (pf == NULL)
    {   
        printf("tError while opening the filen");
    }
    else    
    {
        printf("tWriting in %sn", fname2);
    }
    for(j=0;j<head.height;j++)
    {
        fprintf(pf, "n");
        for(i=0;i<head.width;i++)
        {
            fprintf(pf, "%3d ", RGBArray[i][j].red);
            fprintf(pf, "%3d ", RGBArray[i][j].green);
            fprintf(pf, "%3d ", RGBArray[i][j].blue);
            //fprintf(pf, "%3d ", (RGBArray+j*head.width + i)*r);
            //fprintf(pf, "%3d ", (RGBArray+j*head.width + i)*g);
            //fprintf(pf, "%3d ", (RGBArray+j*head.width + i)*b);
        }
    }
    fclose(pf);
    free(RGBArray);
    RGBArray = NULL;
    for(int i=0;i<head.width;i++)
        {
            free(RGBArray[i]);
            RGBArray[i] = NULL;
        }
    return 0;
}

您主要混合了widthheight,但还有其他问题。

  • width是列数
  • height是行数

内存顺序中的C二维数组为Row Major
用于在存储器中存储图像的约定是";按行">
索引为RGBArray[col][row](在您的代码中应该为RGBArray[j][i](。

插图:

 RGBArray[0][0]               RGBArray[0][14]
               |             |
               V             V
               <--- width --->
RGBArray[0] -> ############### ^
RGBArray[1] -> ############### |
RGBArray[2] -> ############### height
RGBArray[3] -> ############### |
RGBArray[4] -> ############### V

我使用以下PPM文本文件进行测试(in.ppm(:

P3
# ppm comment
4 3
255
  1   2   3    11  12  13   21  22  23    31  32  33
101 102 103   111 112 113  121 122 123   131 132 133
201 202 203   211 212 213  221 222 223   231 232 233

更正代码(请阅读注释(:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define maxheight 1080
#define maxwidth 1920
#define RGB_COMPONENT_COLOUR 255
#define pgmtype "P2"
#define ppmtype "P3"
typedef struct
{
    int red, green, blue;
} PPMPixel;
typedef struct
{
    int x, y;
} PPMImage;
typedef struct
{
    int rgb_comp_colour;
    char filetype[3];
    int height;
    int width;
} PPMHead;

PPMHead head;
PPMHead* head_ptr = &head;
PPMPixel p;
PPMPixel* p_ptr = &p;
PPMPixel *data; //Defines pointer to PPMPixel
int **Array; //Double pointer defines as a pointer pointing to a pointer that is pointing to an integer
PPMPixel **RGBArray; //Double pointer defines as a pointer pointing to a pointer that is pointing to the PPMPixel structure
FILE *fp;
int r, g, b;
void headercheck()
{
    char tmp[201]; //Temporary string.
    fscanf(fp, "%2s", head.filetype); //%2s ensures that no more than two characters are read.
    fscanf(fp, "%200s", tmp);
    if (tmp[0] == '#')
    {
        //The second line may be a comment starting with '#'
        fgets(tmp, 200, fp);    //Skip the comment.
        fscanf(fp, "%d", &head.width);
    }
    else
    {
        //If not a comment, read width from tmp.
        sscanf(tmp, "%d", &head.width);
    }
    //fscanf(fp, "%s %d %d %d", head.filetype, &head.width, &head.height, &head.rgb_comp_colour);
    fscanf(fp, "%d %d", &head.height, &head.rgb_comp_colour);
    printf("%s %d %d %d", head.filetype, head.width, head.height, head.rgb_comp_colour);
    if (head.width > maxwidth || head.height > maxheight)
    {
        printf("tInvalid image size. The maximum value of image is 1920x1080.n");
        printf("tImage size is %d x %dn", head.width, head.height);
    }
    else
    {
        printf("tImage size is validn");
        printf("tImage size is %d x %dn", head.width, head.height);
    }
    if ((strcmp(head.filetype, pgmtype) != 0) && (strcmp(head.filetype, ppmtype) != 0))
    {
        printf("tInvalid filetypen");
    }
    else
    {
        if (strcmp(head.filetype, pgmtype) == 0)
        {
            printf("t File is PGM type imagen");
        }
        else
        {
            if (strcmp(head.filetype, ppmtype) == 0)
            {
                printf("t File is PPM type imagen");
            }
        }
    }
    if ((head.rgb_comp_colour == RGB_COMPONENT_COLOUR))
    {
        printf("t Image is 8 bitn");
    }
    else
    {
        if (head.rgb_comp_colour > RGB_COMPONENT_COLOUR)
        {
            printf("Maximum bit-depth is 8 bitsn");
        }
        else
        {
            printf("tImage is not 8 bitn");
        }
    }
}
int main(void)
{
    const char *fname = "in.ppm";
    //char fname[100];
    //printf("Enter file name: ");
    //scanf("%s", fname);
    //fseek(stdin, 0, SEEK_END);
    fp = fopen(fname, "r");
    if (fp == NULL)
    {
        printf("tError while opening the filen");
    }
    else
    {
        printf("tReading in %sn", fname);
    }
    headercheck();
    if (strcmp(head.filetype, ppmtype) == 0)
    {
        RGBArray = (PPMPixel **)malloc(head.height * sizeof(PPMPixel*)); //Points to malloc
        if ((RGBArray == NULL))
        {
            printf("Error allocating memory to the arrayn");
        }
        else
        {
            printf("Memory allocated to the PPM array successfullyn");
        }
        //for (int i = 0; i < head.width; i++)
        for (int i = 0; i < head.height; i++)   //Iterate height rows
        {
            RGBArray[i] = (PPMPixel *)malloc(head.width * sizeof(PPMPixel));
            if ((RGBArray[i] == NULL))
            {
                printf("Error allocating memory to the arrayn");
            }
        }
        //printf("Error 2");
        //Initializing each element
        for (int j = 0; j < head.height; j++)
        {
            for (int i = 0; i < head.width; i++)
            {
                fscanf(fp, "%3d %3d %3d ", &p.red, &p.green, &p.blue); //Scans in integers of the address pointer to PPMPixel
                //data = &RGBArray[i][j]; //Defines data pointer pointing to address of RGBArray[i][j]
                data = &RGBArray[j][i]; //The row index comes first - (use [j][i] instead of [i][j])
                data->red = p.red; //Access member of PPMPixel structure to equal one of the three RGB channels
                data->green = p.green;
                data->blue = p.blue;
            }
        }
    }
    fclose(fp);
    //Save PPM Array Into New PPM File
    FILE *pf;
    int i, j;
    //char fname2[100];
    //printf("Enter file name: ");
    //scanf("%s", fname2);
    //fseek(stdin, 0, SEEK_END);
    const char *fname2 = "out.ppm";
    pf = fopen(fname2, "w");
    if (pf == NULL)
    {
        printf("tError while opening the filen");
    }
    else
    {
        printf("tWriting in %sn", fname2);
    }
    //Write the PPM header
    ////////////////////////////////////////////////////////////////////////////
    fprintf(fp, "%sn", head.filetype);
    fprintf(fp, "%d %dn", head.width, head.height);
    fprintf(fp, "%dn", head.rgb_comp_colour);
    ////////////////////////////////////////////////////////////////////////////
    for (j = 0; j < head.height; j++)
    {
        //fprintf(pf, "n");
        for (i = 0; i < head.width; i++)
        {
            //fprintf(pf, "%3d ", RGBArray[i][j].red);
            //fprintf(pf, "%3d ", RGBArray[i][j].green);
            //fprintf(pf, "%3d ", RGBArray[i][j].blue);
            fprintf(pf, "%3d ", RGBArray[j][i].red);    //row index comes first - use [j][i] instead of [i][j]
            fprintf(pf, "%3d ", RGBArray[j][i].green);
            fprintf(pf, "%3d ", RGBArray[j][i].blue);
        }
        fprintf(pf, "n");
    }
    fclose(pf);
    //free(RGBArray);
    //RGBArray = NULL;
    for (int i = 0; i < head.height; i++)
    {
        free(RGBArray[i]);
        RGBArray[i] = NULL;
    }
    free(RGBArray); //Free RGBArray after free RGBArray[i]
    RGBArray = NULL;
    return 0;
}

输出文件(out.ppm(:

P3
4 3
255
  1   2   3  11  12  13  21  22  23  31  32  33 
101 102 103 111 112 113 121 122 123 131 132 133 
201 202 203 211 212 213 221 222 223 231 232 233 

相关内容

  • 没有找到相关文章

最新更新