linux图像显示(四)使用libpng处理png图片

linux图像显示

linux图像显示(一)framebuffer操作

linux图像显示(二)bmp图片

linux图像显示(三)使用libjpg处理jpg图片

linux图像显示(四)使用libpng处理png图片

linux图像显示(五)使用freetype处理矢量字体

 

移植libpng

1、下载

由于libpng的的编译需要依赖zlib,所以我们需要下载libpng和zlib

下载地址:ftp://ftp-osl.osuosl.org/pub/libpng/src/

2、移植

将zlib和libpng传到ubuntu中,解压

(1)我们需要先移植zlib

cd到解压出来的zlib目录下

①导出编译器,注意这个编译器必须在你当前环境下能找到,请自行修改

# export CC=arm-linux-gcc

②配置

./configure -shared --prefix=/path

其中path是你自定义的路径,生成的库和头文件将保存到此目录下

③编译并安装

make
make install

这是会在path路径的llib和include目录下发现生成了zlib相关的文件

(2)移植libpng

进入libpng目录下

①导出zlib生成文件所在的目录到环境变量

export LDFLAGS="-L/path/lib"
export CFLAGS="-I/path/include"
export CPPFLAGS="-I/path/include"

②配置

./configure --host=arm-linux --enable-shared --enable-static --prefix=/path

请注意自己修改path路径

③编译并安装

make
make install

3、添加到我们的项目中

先说明一下三个符号 -I -L -l

-I 表示添加头文件路径

-L 表示添加链接库路径

-l 表示添加库

在我们项目的Makefile中添加

-I+头文件的路径
CFLAGS += -I/opt/mlib/include

-L+库的路径
LDFLAGS += -L/opt/mlib/lib
-l+库的名字
LDFLAGS += -lpng -lz

此外还需要将动态链接库.so拷贝到开发板的根文件系统中

①可以拷贝/lib或者/usr/lib这两个系统可以自动查找的地方

②也可以添加添加到自定义的路径,然后导出路径到环境变量中(推荐这种做法)

导出到环境变量:

# export LD_LIBRARY_PATH=/usr/m_lib:$LD_LIBRARY_PATH

查看是否导出成功

echo $LD_LIBRARY_PATH

示例代码

void png_read(char *file_path)
{
    png_structp png_ptr;
    png_infop info_ptr;
    int color_type = 0; 
    int image_size = 0;
    int image_width, image_height;
	
    FILE *p_fp;

    if ((p_fp = fopen(file_path, "rb")) == NULL)
    {
        fprintf(stderr, "%s open fail!!!\n", file_path);
        return -1;
    }

    /* 创建一个png_structp结构体,如果不想自定义错误处理,后3个参数可以传NULL */
    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);	
    if (png_ptr == NULL)
    {
        fclose(p_fp);
        return -1;
    }

	/* 创建一个info_ptr,必须的 */	
    info_ptr = png_create_info_struct(png_ptr);
    
    if (info_ptr == NULL)
    {
        fclose(p_fp);
        png_destroy_read_struct(&png_ptr, NULL, NULL);
        return -1;
    }

    /* 如果上面png_create_read_struct没有自定义错误处理,这里是必须的 */
    if (setjmp(png_jmpbuf(png_ptr)))
    {
        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
        fclose(p_fp);

        return -1;
    }

    /* 初始化文件IO */
	png_init_io(png_ptr, p_fp);

    /* 
     * 函数功能:读取png图片信息 
     * 说明:可以参数3来改变不同的读取方式,这里只读取RGB,抛弃了ALPHA
     */
    png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_EXPAND | PNG_TRANSFORM_STRIP_ALPHA, NULL);

	if ((png_ptr != NULL) && (info_ptr != NULL))
	{
		/* 获取图像的宽高 */
		image_width = png_get_image_width(png_ptr, info_ptr);       
		image_height = png_get_image_height(png_ptr, info_ptr); 
		printf("width:%d,height:%d\n", image_width, image_height);

        /* 获取图像颜色类型 */
	    color_type = png_get_color_type(png_ptr, info_ptr); 
        printf("color type:%d\n", color_type);

    }

    /* 获取所有的图像数据 */
    png_bytep *row_pointers; /* 指针数组,数组中的每一个指针都指向一行图像数据 */
    row_pointers = png_get_rows(png_ptr, info_ptr);
 
    int i, j;
    int pos = 0;

	/* RGB格式 */
    if(PNG_COLOR_TYPE_RGB == color_type)
    {
        /* 图像数据的大小 */
        image_size = image_width * image_height * 3;   
        p_image_buf = malloc(image_size);

        for(i = 0; i < image_height; i++)
        {
            for(j = 0; j < (image_width * 3); j += 3)
            {
                *(p_image + pos++) = row_pointers[i][j + 0];
                *(p_image + pos++) = row_pointers[i][j + 1];
                *(p_image + pos++) = row_pointers[i][j + 2];
               
            }
        }

    }   

    /* 清理图像,释放内存 */
    png_destroy_read_struct(&png_ptr, &info_ptr, 0);
    
    fclose(p_fp);    
    
    return 0;
}

 

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
是的,Linux可以使用libemf库将EMF文件转换为PNG图片。libemf是一个开源的库,用于解析Windows Metafile Format (WMF) 和 Enhanced Metafile Format (EMF) 文件,并将其转换为其他图像格式。其中,EMF是WMF的升级版本,提供更多的功能和更高的分辨率。 libemf提供了一个名为`GetEnhMetaFile()`的函数,用于获取EMF文件的句柄。你可以使用该函数来读取EMF文件,然后将其转换为PNG格式。 下面是一个简单的示例代码,用于将EMF文件转换为PNG格式: ```c++ #include <stdio.h> #include <emf.h> #include <png.h> int main(int argc, char *argv[]) { const char *input_file = "input.emf"; const char *output_file = "output.png"; int width, height; HDC hdc; HENHMETAFILE hEmf; png_bytep row_pointer; png_structp png_ptr; png_infop info_ptr; FILE *fp; png_byte color_type = PNG_COLOR_TYPE_RGBA; png_byte bit_depth = 8; png_bytep *row_pointers = NULL; // 打开 EMF 文件 fp = fopen(input_file, "rb"); if (!fp) { printf("Error: Cannot open input file %s\n", input_file); return -1; } // 读取 EMF 文件 hEmf = GetEnhMetaFile(input_file); if (!hEmf) { printf("Error: Cannot read EMF file %s\n", input_file); fclose(fp); return -1; } // 获取 EMF 文件的宽度和高度 hdc = CreateEnhMetaFile(NULL, NULL, NULL, NULL); PlayEnhMetaFile(hdc, hEmf, NULL); width = GetDeviceCaps(hdc, HORZRES); height = GetDeviceCaps(hdc, VERTRES); DeleteEnhMetaFile(hEmf); DeleteDC(hdc); // 创建 PNG 文件 fp = fopen(output_file, "wb"); if (!fp) { printf("Error: Cannot create output file %s\n", output_file); return -1; } // 初始化 PNG 结构体 png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) { printf("Error: Cannot create PNG write structure\n"); fclose(fp); return -1; } // 初始化 PNG 信息结构体 info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { printf("Error: Cannot create PNG info structure\n"); png_destroy_write_struct(&png_ptr, NULL); fclose(fp); return -1; } // 设置错误处理函数 if (setjmp(png_jmpbuf(png_ptr))) { printf("Error: Error during PNG write\n"); png_destroy_write_struct(&png_ptr, &info_ptr); fclose(fp); return -1; } // 设置 PNG 文件头信息 png_set_IHDR( png_ptr, info_ptr, width, height, bit_depth, color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); // 写入 PNG 文件头信息 png_init_io(png_ptr, fp); png_write_info(png_ptr, info_ptr); // 创建每行数据的缓冲区 row_pointers = (png_bytep *) malloc(sizeof(png_bytep) * height); for (int i = 0; i < height; i++) { row_pointers[i] = (png_byte *) malloc(png_get_rowbytes(png_ptr, info_ptr)); } // 创建 DC 并将 EMF 文件绘制到 DC 上 hdc = CreateCompatibleDC(NULL); hEmf = GetEnhMetaFile(input_file); SelectObject(hdc, CreateEnhMetaFile(NULL, NULL, NULL, NULL)); PlayEnhMetaFile(hdc, hEmf, NULL); // 逐行读取数据并写入 PNG 文件 for (int y = 0; y < height; y++) { row_pointer = row_pointers[y]; for (int x = 0; x < width; x++) { COLORREF color = GetPixel(hdc, x, y); row_pointer[x * 4] = GetRValue(color); // Red row_pointer[x * 4 + 1] = GetGValue(color); // Green row_pointer[x * 4 + 2] = GetBValue(color); // Blue row_pointer[x * 4 + 3] = 255; // Alpha } } png_write_image(png_ptr, row_pointers); // 写入 PNG 文件尾信息 png_write_end(png_ptr, NULL); // 清理资源 for (int i = 0; i < height; i++) { free(row_pointers[i]); } free(row_pointers); png_destroy_write_struct(&png_ptr, &info_ptr); DeleteEnhMetaFile(hEmf); DeleteDC(hdc); fclose(fp); printf("Conversion completed successfully\n"); return 0; } ``` 这个示例程序使用libemf库和libpng库将EMF文件转换为PNG格式,其中使用`GetEnhMetaFile()`函数读取EMF文件,使用`CreateCompatibleDC()`函数创建设备上下文,使用`GetPixel()`函数获取每个像素的颜色值,并使用libpng库将像素数据写入PNG文件。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值