2017-02-22 58 views
0

Мне нужна матрица с каждой строкой, соответствующей пикселю, и каждый столбец является значением R G B из изображения PPM P3.Как вы читаете данные пикселя из изображения PPM (P3) в матрицу в C?

Я попытался создать матрицу с [imageWidth * imageHeight] [3], так как размер заселен, но, похоже, навсегда. Я думаю, что что-то пропустил, может кто-нибудь объяснить, где я поступил неправильно или, возможно, предложить лучший способ сделать это?

int pixels [imageSize] [3]; 

while(fgets(line,70,fd) != NULL){ 
    for (column = 0; column < (imageSize); column++){ 
    for (row = 0; row < 1; row++){ 
     sscanf(line, "%d %d %d", &r, &g, &b); 
     pixels [column] [row] = r; 
     pixels [column] [row + 1] = g; 
     pixels [column] [row + 2] = b; 
    } 
    } 
} 

Линия относится к строке, считываемой функцией fgets.

+0

Вы никогда обновите 'line', так что вы просто просматриваете одни и те же значения снова и снова. – jwodder

+0

Упс, я пропустил мой внешний цикл while, который обновляет строку. –

+0

Это загадка, почему вы размещаете компоненты r, g, b на разных * строках * изображения. Также почему 'for (column = 0; column <(imageSize); column ++) цикл для каждой прочитанной строки, которая будет медленной. Я предлагаю написать блок-схему того, что вы хотите, - даже если это неофициальный псевдокод на бумаге. –

ответ

1

Проблема в вашем обновленном коде устранена: вы пытаетесь прочитать все пиксели изображения с каждые растровая линия. Это не будет работать forever, если только fgets() блокируется бесконечно, но если размеры растра большие и файл организован со многими линиями пикселей, то это может занять очень много времени. В любом случае это неверно, поскольку на каждой итерации самого внешнего цикла, то есть для каждой строки, прочитанной, она перезаписывает все ранее назначенные значения пикселей.

Кроме того, ваша внутренняя петля, хотя и не совсем ошибочная, очень запутанна. Он всегда выполняет ровно одну итерацию; его итерационная переменная row фактически индексирует компоненты пикселей (в отличие от строк растра), а row в любом случае имеет значение 0 на каждой итерации. Было бы лучше просто удалить его.

В целом, вы делаете это намного сложнее, чем должно быть. Формат PPM P3 разработан таким образом, чтобы он мог вводиться через гораздо более простой код. Каждой выборке в действительном PPM-файле P3 гарантируется наличие пробелов до и после. С другой стороны, положение и ширина полей и количество их на линию не фиксированы. Вместе эти характеристики делают этот один из сравнительно редких случаев, когда fscanf() на самом деле является лучшим выбором, чем fgets() + sscanf(). Ограничение длины линии делает последнее очень хорошим, но вам не нужно дополнительное осложнение, которое приносит.

Учитывая, что вы хотите прочитать imageSize пикселей из FILE назначенного fd, с этим FILE изначально позиционируется на первый символ первой строки растра, это будет делать трюк:

for (pixel = 0; pixel < imageSize; pixel++) { 
    int numScanned = fscanf(fd, "%d %d %d", 
      &pixels[pixel][0], 
      &pixels[pixel][1], 
      &pixels[pixel][2]); 
    if (numScanned < 3) { 
     // ... handle file format or I/O error ... 
     break; 
    } 
}