2014-11-29 2 views
0

Итак, у меня есть код, который будет считываться в заголовке из изображения ppm, выделять память для размера изображения и успешно печатать пробелы (случайное число, повторяемое в терминале) для каждого пикселя. Все, что мне нужно знать, это то, как я должен читать красные зеленые и синие значения (3 отдельных значения от 0 до 255) для каждого пикселя. Я не знаю, как получить доступ к этим данным в каждом пикселе. Вот мой код до сих пор:Получение значений 0-255 из пикселя в файле ppm C

#include <stdio.h> 
#include <stdlib.h> 

int subscript(int row,int column,int numberColumns); 
int sub(int rd, int gr, int bl); 
//table of contents for the subscript 
int main(void){ 
     char header[5]; 
     scanf("%s",header); 
     printf("%s",header); 
     printf("\n"); 
     int width, height, depth; 
     scanf("%d %d %d\n", &width, &height, &depth); 
     printf("%d %d %d\n", width, height, depth); 
     int red = 0; 
     int green = 0; 
     int blue = 0; 
     int sm; 
     int r = 0; 
     int c = 0; 
     //allocate memory for bit to be used throughout main 
     unsigned char *bit = malloc(width*height); 
     int *rgb = malloc(3*depth); 
     //loops to read in table and print it 
     while(r < height){ 
       while(c < width) 
         { 
         int col; 
         scanf("%d",&col); 
         //brings in allocated memory and values 
         bit[subscript(r,c,width)] = col; 
         int clr; 
         rgb[sub(red,green,blue)] = clr; 
         int color = clr + col; 
         printf(" %d",clr); 
         c=c+1; 
         } 
       printf("\n"); 
       r = r + 1; 
       c = 0; 
       } 


     free(bit); 

} 
int subscript(int row,int column, int numberColumns) 
     { 
     return row * numberColumns + column; 
     //retuns items for subscript 
} 

int sub(int rd, int gr, int bl) 
     { 
     return rd+gr+bl; 
} 

ответ

0

PPM files магазин цветов как троек байт (один байт каждый для R, G и B в таком порядке), если максимальное поле значение цвета в заголовке меньше, чем 256 и тройки двух байтов, если это 256 или больше (так что два байта для каждого из r, g и b, снова в этом порядке).

В двух байтах на каждый канал байты - это MSB first (big-endian).


scanf("%c", &byte_var); зачитает вам один символ (байт) в byte_var, который должен быть соответствующим типом. Затем вы можете обработать его соответствующим образом. scanf("%hhu", &byte_var); будет читать символ без знака, если вы используете C99 - если вы используете C89, вы должны посмотреть getchar.

Теперь scanf возвращает количество успешно преобразованных аргументов или EOF, поэтому вы должны проверить результат как для неправильного ввода, так и для конца ввода. Например:

int n; 
char c; 

while ((n = scanf("%c", &c)) != EOF && 1 == n) { 
    // do something 
} 

Пример использования этого может быть:

// Read width, height, work out how many bytes you need per pixel. 
... 

// Now read some pixels 
// Here I assume one byte per pixel; this would be a good situation 
// to use a function for reading different channel widths 

w = 0, h = 0; 
while ((n = scanf("%hhu%hhu%hhu", &r, &g, &b)) != EOF && 3 == n 
     && w < width && h < height) { 
    // now do something with r, g, b 
    // e.g. store them in an appropriate pixels array at pixels[w][h] 
    ... 

    ++w; 
    if (w == width) { 
    w = 0, ++h; 
    } 
} 

Я также вижу, что вы читаете из stdin, который я нахожу немного необычно, так как название означает, что вы работаете с файл. Вы можете открыть файл с fopen (не забудьте проверить результат), используйте fscanf, чтобы прочитать его, и используйте fclose, чтобы закрыть его потом.

Однако я предлагаю прочитать весь файл в памяти и обработать его там, потому что чтение файла по несколько байтов за раз медленнее.


Наконец, я отмечаю, что вы только распределение width * height байт для bit когда вам нужно bytes_per_channel * num_channels * width * height, не проверяя ли ваш malloc неудачу, не освобождая rgb. Вы должны это исправить.

+0

это для проекта, и одним из требований является синтаксический анализ ввода/вывода файла из командной строки, поэтому я не думаю, что мне разрешено использовать fopen в этой ситуации. Я видел в нескольких других сообщениях, что чтение всего файла в память происходит намного быстрее, но я должен прочитать его по частям, поэтому я не выхожу за пределы материала, который мы рассмотрели в классе (неудачная избыточность здесь). Как я могу включить этот scanf, который вы упомянули во вложенном цикле строк/столбцов? Я также исправлю упомянутые вами проблемы с malloc. –

+0

«из командной строки» может означать, что имя файла должно быть передано в качестве аргумента вашей программе или что оно должно быть передано через stdin. Сделайте все, что вам нужно для выполнения задания. Я добавлю пример re. петля и т. д. –

+0

@ihavethedumb Добавлен пример. –

Смежные вопросы