如何使用libpng获取图像char阵列?

发布于 2025-02-03 02:35:01 字数 1508 浏览 2 评论 0原文

尽管我已经成功地利用了stb_image/cimg/lodepng开源来获取char数组,但内存的使用情况太大,以至于我无法在低功率嵌入式系统中实现它。

因此,我尝试使用libpng读取PNG类型的图像,并获取一个char数组。

但是,我完全不熟悉libpng ......

有人可以提供帮助吗?


根据一些网站示例程序,我编写以下功能。但是我遇到了细分故障,我认为我在处理变量,RAW_POINTERS和图像时遇到问题。有人可以查看我的代码并给我一些建议吗?

unsigned char* read_png_file(const char *filename) 
{
    FILE *fp = fopen(filename, "rb");
    int bit_depth;
    int color_type;
    png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    png_infop info = png_create_info_struct(png);
    png_init_io(png, fp);
    png_read_info(png, info);

    width = png_get_image_width(png, info);
    height = png_get_image_height(png, info);
    color_type = png_get_color_type(png, info);
    bit_depth = png_get_bit_depth(png, info);

    int numchan = 4;

    // Set up row pointers
    row_pointers = (unsigned char**) malloc(sizeof(unsigned char) * height);
    for (int y=0; y<height; y++)
        row_pointers[y] = (unsigned char*) malloc(sizeof(unsigned char) * width);
    png_read_image(png, row_pointers);

    // Put row pointers data into image
    unsigned char * image = (unsigned char *) malloc (numchan*width*height);
    for (unsigned int i=0;i<height;i++)
        for (unsigned int j=0;j<width;i++)
            *image++ = row_pointers[j][i];
    fclose(fp);

    cout << height << ", " << width << ", " << bit_depth << ", " << numchan << endl;

    return image;
}

Although I have successfully utilized stb_image/CImg/lodepng open source to get a char array, the memory usage is too huge that I can't implement it in a low power embedded system.

Therefore, I try to use libpng to read a png type image, and get a char array.

However, I am completely not familiar with libpng......

Anyone can help?


According to some website sample programs, I write the following function. But I encounter Segmentation Fault, I think that I have problem dealing with the variables, raw_pointers and image. Anyone can review my code and give me some suggestions?

unsigned char* read_png_file(const char *filename) 
{
    FILE *fp = fopen(filename, "rb");
    int bit_depth;
    int color_type;
    png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    png_infop info = png_create_info_struct(png);
    png_init_io(png, fp);
    png_read_info(png, info);

    width = png_get_image_width(png, info);
    height = png_get_image_height(png, info);
    color_type = png_get_color_type(png, info);
    bit_depth = png_get_bit_depth(png, info);

    int numchan = 4;

    // Set up row pointers
    row_pointers = (unsigned char**) malloc(sizeof(unsigned char) * height);
    for (int y=0; y<height; y++)
        row_pointers[y] = (unsigned char*) malloc(sizeof(unsigned char) * width);
    png_read_image(png, row_pointers);

    // Put row pointers data into image
    unsigned char * image = (unsigned char *) malloc (numchan*width*height);
    for (unsigned int i=0;i<height;i++)
        for (unsigned int j=0;j<width;i++)
            *image++ = row_pointers[j][i];
    fclose(fp);

    cout << height << ", " << width << ", " << bit_depth << ", " << numchan << endl;

    return image;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

纵情客 2025-02-10 02:35:01

我成功使用libpng获取了一个char阵列。

但是,内存使用量最大为 915.1kb ,它比stb_image高!!! (使用Valgrind)

啊...有人可以告诉我一些方向以优化内存使用情况吗?

unsigned char* read_png_file(const char *filename) 
{
    FILE *fp = fopen(filename, "rb");
    png_byte bit_depth;
    png_byte color_type;
    png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    png_infop info = png_create_info_struct(png);
    png_init_io(png, fp);
    png_read_info(png, info);

    width = png_get_image_width(png, info);
    height = png_get_image_height(png, info);
    color_type = png_get_color_type(png, info);
    bit_depth = png_get_bit_depth(png, info);

    if(color_type == PNG_COLOR_TYPE_PALETTE)
        png_set_palette_to_rgb(png);
    if(color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
        png_set_expand_gray_1_2_4_to_8(png);
    if(png_get_valid(png, info, PNG_INFO_tRNS))
        png_set_tRNS_to_alpha(png);
    if(color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_PALETTE)
        png_set_filler(png, 0xFF, PNG_FILLER_AFTER);
    if(color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
        png_set_gray_to_rgb(png);

    png_read_update_info(png, info);

    int numchan = 4;

    // Set up row pointer
    png_bytep *row_pointers = (png_bytep*)malloc(sizeof(png_bytep) * height);
    unsigned int i, j;
    for (i = 0; i < height; i++)
        row_pointers[i] = (png_bytep)malloc(png_get_rowbytes(png,info));
    png_read_image(png, row_pointers);

    // Put row pointers data into image
    unsigned char *image = (unsigned char *) malloc (numchan*width*height);
    int count = 0;
    for (i = 0 ; i < height ; i++)
    {
        for (j = 0 ; j < numchan*width ; j++)
        {
            image[count] = row_pointers[i][j];
            count += 1;
        }
    }
    fclose(fp);
    for (i = 0; i < height; i++)
        free(row_pointers[i]) ;
    free(row_pointers) ;

    return image;     
}

I successfully use libpng to get a char array.

However, the memory usage is up to 915.1KB which is higher than stb_image !!! (Use Valgrind)

Ah... Could anyone tell me some directions to optimize the memory usage?

unsigned char* read_png_file(const char *filename) 
{
    FILE *fp = fopen(filename, "rb");
    png_byte bit_depth;
    png_byte color_type;
    png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    png_infop info = png_create_info_struct(png);
    png_init_io(png, fp);
    png_read_info(png, info);

    width = png_get_image_width(png, info);
    height = png_get_image_height(png, info);
    color_type = png_get_color_type(png, info);
    bit_depth = png_get_bit_depth(png, info);

    if(color_type == PNG_COLOR_TYPE_PALETTE)
        png_set_palette_to_rgb(png);
    if(color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
        png_set_expand_gray_1_2_4_to_8(png);
    if(png_get_valid(png, info, PNG_INFO_tRNS))
        png_set_tRNS_to_alpha(png);
    if(color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_PALETTE)
        png_set_filler(png, 0xFF, PNG_FILLER_AFTER);
    if(color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
        png_set_gray_to_rgb(png);

    png_read_update_info(png, info);

    int numchan = 4;

    // Set up row pointer
    png_bytep *row_pointers = (png_bytep*)malloc(sizeof(png_bytep) * height);
    unsigned int i, j;
    for (i = 0; i < height; i++)
        row_pointers[i] = (png_bytep)malloc(png_get_rowbytes(png,info));
    png_read_image(png, row_pointers);

    // Put row pointers data into image
    unsigned char *image = (unsigned char *) malloc (numchan*width*height);
    int count = 0;
    for (i = 0 ; i < height ; i++)
    {
        for (j = 0 ; j < numchan*width ; j++)
        {
            image[count] = row_pointers[i][j];
            count += 1;
        }
    }
    fclose(fp);
    for (i = 0; i < height; i++)
        free(row_pointers[i]) ;
    free(row_pointers) ;

    return image;     
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文