LINUX.ORG.RU

Пробую рисовать в PNG: ошибка со слоями?


0

1
#include <stdio.h>
#include <png.h>
#include <stdlib.h>
// См. http://zarb.org/~gc/html/libpng.html (A simple libpng example program)

int main(int argc, char **argv) {
  if (argc < 2) {
    printf("pngwrite [filename.png]\n");
    return -1;
  }
  const char *filename = argv[1];
  FILE *f = fopen(filename, "wb");
  int w = 1000;
  int h = 1000;
  int bpp = 16;

  png_structp hw; // Handle for writing
  png_infop info;
  hw = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  info = png_create_info_struct(hw);
  
  setjmp(png_jmpbuf(hw));
  png_init_io(hw, f);

  setjmp(png_jmpbuf(hw));
  png_set_IHDR(hw, info,
    w, h, bpp, PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE,
    PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
  png_write_info(hw, info); // write header

  png_bytep *rows;
  rows = (png_bytep*)malloc(sizeof(png_bytep)*h);
  for (int y = 0; y < h; y++)
    rows[y] = (png_byte*)malloc(4*w);
    //rows[y] = (png_byte*)malloc(png_get_rowbytes(hw,info));

  for (int y = 0; y < h; y++)
    for (int x = 0; x < w; x++) {
      rows[y][x*4+0] = 255;
      rows[y][x*4+1] = 0;
      rows[y][x*4+2] = 255;
      rows[y][x*4+3] = 0;
    }

  setjmp(png_jmpbuf(hw));
  png_write_image(hw, rows); // bytes write

  setjmp(png_jmpbuf(hw));
  png_write_end(hw, NULL); // end write

  for (int y = 0; y < h; y++) free(rows[y]);
  free(rows);

  fclose(f);
  return 0;
}

Выдается такой файл: http://php.kirovnet.ru/images/pngwrite-sample-error-shot.png

Как видно - черная полоса посередине картинки из белых пикселей.
Вроде, картинка должна получиться фиолетовой.
Почему так? Может быть, я неправильно задаю параметр bpp?

Допустимые значения для bpp беру отсюда: http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html

★★★★★

Разобрался самостоятельно:
Эти строки эквивалентны:
rows[y] = (png_byte*)malloc(4*w);
//rows[y] = (png_byte*)malloc(png_get_rowbytes(hw,info));

Вместо
int bpp = 16;
надо написать
int bpp = 8;
(глубина в битах для одного слоя);

Всё работает, PNG формируется.

pacify ★★★★★
() автор топика
Ответ на: комментарий от pacify

И ведь точно, по документации,

  6       8,16        _Each pixel_ is an R,G,B triple, followed by an alpha sample.
(подчеркнуто)

pacify ★★★★★
() автор топика
Ответ на: комментарий от pacify

> Нарисовал миллион простых чисел по-спирали:

Чем обусловлено такое распределение? Какие координаты по x,y?

anonymous
()
Ответ на: комментарий от anonymous

Какие координаты по x,y?

    int x,y;
    double r,phi;
    phi = d/200.0;
    r = 3.0*sqrt(phi); // спираль
    x = (int)(floor(w/2+r*cos(phi)));
    y = (int)(floor(w/2+r*sin(phi)));
    if ((x >= 0) && (x <= w-1) &&
        (y >= 0) && (y <= h-1)) {
      p[y*w+x]++;
    }
    ...
  for (int y = 0; y < h; y++) {
    for (int x = 0; x < w; x++) {
      unsigned int k = 32;
      rows[y][x*4+0] = (p[y*w+x]*k<256?p[y*w+x]*k:255);
      rows[y][x*4+1] = (p[y*w+x]*k<256?p[y*w+x]*k:255);
      rows[y][x*4+2] = (p[y*w+x]*k<256?p[y*w+x]*k:255);
      rows[y][x*4+3] = 255;
    }
  }

«Дуги» в виде ветвей спирали, видимо, обусловлены делением чисел на 2, 3, и т.д. Точнее не анализировал.

pacify ★★★★★
() автор топика
Ответ на: комментарий от pacify

Дай большее разрешение плз. Хочу увидеть числа.

drull ★☆☆☆
()
Ответ на: комментарий от Eddy_Em

> Я-то думал, действительно числа записаны...

Числа можно записать через Cairo (у них в исходниках много примеров).
Затем - отмасштабировать изображение.

pacify ★★★★★
() автор топика
Ответ на: комментарий от Eddy_Em

Была еще идея - отображать цветом не плотность простых чисел, а количество его простых делителей.

pacify ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.