2014-01-06 2 views
1

Я кодирую в C, и мне нужно работать с png-изображениями, поэтому я работаю с библиотекой libpng. В моем проекте я использую эту структуру:Синтаксис не ясен о указателях и матрице

png_bytep *row_pointers; /* <-- to declare the pointer that will contain the image 
          and this to initialize the pointer to contain the image. */ 

row_pointers = (png_bytep*)malloc(sizeof(png_bytep) * height); 
for(int y = 0; y < height; y++) { 
    row_pointers[y] = (png_byte*)malloc(png_get_rowbytes(png,info)); 
} 

Моя проблема заключается: после того, как этот кусок кода мой образ copyed в row_pointers и я хочу, чтобы скопировать его в png_byte map[x][y], так что я могу работать Исли пиксель для пикселя. Кто-нибудь может мне помочь? Thanks

+0

Вы уверены, что 'row_pointers' не является двойной стрелкой? – haccks

+0

нет, я нет. Я скопировал эту часть кода, и это причина моих дублетов. PS: Если это двойной указатель, как я мог его скопировать в другую более простую структуру? –

+0

@haccks 'png_bytep'' 'в конце указывает, что это байт-понитер. Так что это правильно. Он должен удалить свой бросок на каждом malloc. Он не нужен в C. – RedX

ответ

0

Ok. Это указатель на указатель!

png_bytep = указатель на png_byte

Если устранить png_bytep и использовать только png_byte код будет выглядеть следующим образом.

int height = 10; 
int width = 20; 

png_byte **row_pointers; 
row_pointers = (png_byte**)malloc(sizeof(png_byte*) * height); <-- This is basically your number of rows.. ie height of your matrix. 
for(int y = 0; y < height; y++) 
{ 
    row_pointers[y] = (png_byte*)malloc(sizeof(png_byte)*width); <-- This is representing number of elements in each row.. so width. 

} 

Предполагая, что ваша структура имеет два типа x и y. вы должны подавать данные, как указано ниже.

for(int i=0;i< height;i++) 
{ 
    for (int j=0;j<width;j++) 
    { 
     row_pointers[i][j].x = i*j; 
     row_pointers[i][j].y = i*j; 
    } 
} 

Предполагая, что ваша карта также имеет аналогичную структуру. Это, как вы скопировать данные ..

for(int i=0;i< height;i++) 
{ 
    for (int j=0;j<width;j++) 
    { 
     map[i][j].x = row_pointers[i][j].x; 
     map[i][j].y = row_pointers[i][j].y; 
    } 
} 
+0

Это, скорее всего, комментарий, а затем ответ ... – RedX

+0

да .. редактирование моего ответа для этого ... –

+0

Этот код ничего не делает. Это то же самое, что и исходный код. Только имя typedef было заменено их оригинальными типами ... – RedX

0

Посмотрите pnm2png.c в CONTRIB/pngminus каталог Libpng в.

В этом коде «png_pixels» представляет собой простой массив, который содержит все пиксели, а row_pointers представляет собой массив указателей, которые указывают на начало каждой строки в пределах png_pixels:

/* row_bytes is the width x number of channels x (bit-depth/8) */ 
    row_bytes = width * channels * ((bit_depth <= 8) ? 1 : 2); 

    png_pixels = (png_byte *) malloc (row_bytes * height * sizeof (png_byte)) 

/* set the individual row_pointers to point at the correct offsets */ 
    for (i = 0; i < (height); i++) 
    row_pointers[i] = png_pixels + i * row_bytes; 

/* now we can go ahead and just read the whole image */ 
    png_read_image (png_ptr, row_pointers); 

После png_read_image завершается, вы можете легко работать с вашими пикселями в массиве png_pixels.

Обратите внимание, что существует только один «malloc», который выделяет png_pixels. Вместо того, чтобы делать отдельный «malloc» для каждой строки, этот код вычисляет значения row_pointers.

+0

кажется хороший отзыв, спасибо. Я постараюсь использовать его тоже. Но в каналах у меня уже есть номер этого или я должен установить эту переменную? –

+0

Каналы могут быть 1, 2, 3 или 4, в зависимости от типа цвета PNG. Вы можете получить количество каналов с помощью «png_get_channels (png, png_info);». Кроме того, если возможно, что вы можете читать 16-битные образцы, вам нужно учитывать это. См. Пример libpng/contrib/pngminus, о котором я упоминал ранее. –

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