首页 > 解决方案 > 如何为 png_write_image 准备 RGB 数组和行指针?

问题描述

我对 C 很陌生,需要一些有关 libpng 的帮助。我有一个用图像的 RGB 值填充的无符号字符数组,需要创建一个 .png 图像。我设法创建了一个大小合适的图像并填充了像素值,但原始图片看起来像这样: 原图 我的代码是这样做的: 新图片

我是否正确,像素值必须存储在无符号字符数组中:红色像素一,绿色像素一,蓝色像素一,红色像素二,绿色像素二,蓝色像素二,......我是否计算下面代码中的行指针正确吗?

构建像素数组(将 Y、Cb、Cr 值转换为 RGB):

int wcnt = 0;

for(int y = 0; y < height; y++){
  for(int x = 0; x < width; x++){

    rgb[wcnt] = round(1.0 * _y[y][x] + 0.0 * _cb[y][x] + 1.402 * _cr[y][x]);        //red
    rgb[wcnt+1] = round(1.0 * _y[y][x] + (-0.34414 * _cb[y][x]) + (-0.71414 * _cr[y][x]));  //green
    rgb[wcnt+2] = round(1.0 * _y[y][x] + 1.772 * _cb[y][x] + 0.0 * _cr[y][x]);  //blue

    wcnt = wcnt +3;
  }
}

编写PNG:

int writepng(char* name, char* dest){   
    char decpng[256];
    FILE *fp = NULL;
    png_structp png_ptr = NULL;
    png_infop info_ptr = NULL;
    png_bytep row_pointers[height];

    sprintf(decpng, "%s%s_dec.png", dest, name);

    //Create File
    fp = fopen(decpng, "wb");
    if (fp == NULL){
      fprintf(stderr, "PNG konnte nicht angelegt werden!\n");
      return EXIT_FAILURE;
    }

    // Information init
    png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if (png_ptr == NULL){
      fprintf(stderr, "Schreibstruktur konnte nicht angelegt werden.\n");
      return EXIT_FAILURE;
    }

    info_ptr = png_create_info_struct(png_ptr);
    if (info_ptr == NULL){
      fprintf(stderr, "Infostruktur konnte nicht angelegt werden.\n");
      return EXIT_FAILURE;
    }

    if (setjmp(png_jmpbuf(png_ptr))){
      fprintf(stderr, "Fehler Initialisierung.\n");
      return EXIT_FAILURE;
    }

    png_init_io(png_ptr, fp);

    if (setjmp(png_jmpbuf(png_ptr))){
      fprintf(stderr, "Fehler beim schreiben des Headers.\n");
      return EXIT_FAILURE;
    }

    png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);

    png_write_info(png_ptr, info_ptr);

    if (setjmp(png_jmpbuf(png_ptr))){
      fprintf(stderr, "Fehler beim schreiben der Daten.\n");
      return EXIT_FAILURE;
    }

    //Fill PNG - here is something wrong

    for(int k = 0; k < height; k++){
      //k = each line, k*width = pixels till first pixel of like k, *3 = RGB values
      row_pointers[k] = (rgb + k * width * 3);
    }

    //png_struct, png_bytep
    png_write_image(png_ptr, row_pointers);

    png_write_end(png_ptr, info_ptr);

    return EXIT_SUCCESS;
}

标签: clibpng

解决方案


推荐阅读