做ios开发,加载图片是常有的事情,但是图片加载失败是非常头疼的事情。
ios开发中常用的图片一般为png格式。
在一篇文章中看到不同格式的图片具有不同的文件头,这样就给开发者带来一个好的方法,加载图片的时候,首先判断下载的图片是否为我们所需要的图片格式,然后在进行保存。(文章:http://blog.csdn.net/include1224/article/details/5195470)
PNG
- 文件头标识 (8 bytes)
另一篇http://blog.csdn.net/yshen_dublin/article/details/4942871
libpng的数据结构
libpng的使用
0、判断是否为libpng数据
1、初始化libpng
1:
7: png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
8: png_voidp user_error_ptr, user_error_fn, user_warning_fn);
1: png_structp png_ptr = png_create_read_struct_2
2: (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
3: user_error_fn, user_warning_fn, (png_voidp)
4: user_mem_ptr, user_malloc_fn, user_free_fn)
2、创建图像信息——png_infop变量
1:
2: info_ptr = png_create_info_struct(png_ptr);
3: if (info_ptr == NULL)
4: {
5: png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
6: return (ERROR);
7: }
3、设置错误返回点
1:
5: if (setjmp(png_jmpbuf(png_ptr)))
6: {
7:
8: png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
9:
10: return (ERROR);
11: }
4、设置libpng的数据源
1:
2: def streams
3:
4: png_init_io(png_ptr, fp);
1:
4: png_set_read_fn(png_ptr, (void *)user_io_ptr, user_read_fn);
5:
5、png图像处理
高层处理
PNG_TRANSFORM_IDENTITY
PNG_TRANSFORM_STRIP_ALPHA
PNG_TRANSFORM_PACKING
PNG_TRANSFORM_PACKSWAP
PNG_TRANSFORM_EXPAND
PNG_TRANSFORM_INVERT_MONO
PNG_TRANSFORM_SHIFT
PNG_TRANSFORM_BGR
PNG_TRANSFORM_SWAP_ALPHA
PNG_TRANSFORM_INVERT_ALPHA
PNG_TRANSFORM_SWAP_ENDIAN
PNG_TRANSFORM_GRAY_TO_RGB
1:
9: png_read_png(png_ptr, info_ptr, png_transforms, png_voidp_NULL);
a)调用png_read_info函数获得图片信息。
b)根据png_transforms所指示的,调用png_set_transform设置输出格式转换的函数。
c)调用png_read_image来解码整个图片的数据到内存。
d)调用png_read_end结束图片解码。
1: row_pointers = png_get_rows(png_ptr, info_ptr);
底层处理
a)读取输入png数据的图片信息:
1:
4: png_read_info(png_ptr, info_ptr);
b)查询图像信息
1: png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
2: &interlace_type, int_p_NULL, int_p_NULL);
c)设置png输出参数(转换参数)
1: // expand images of all color-type and bit-depth to 3x8 bit RGB images
2: // let the library process things like alpha, transparency, background
3: if (bit_depth == 16)
4: png_set_strip_16(png_ptr);
5: if (color_type == PNG_COLOR_TYPE_PALETTE)
6: png_set_expand(png_ptr);
7: if (bit_depth<8)
8: png_set_expand(png_ptr);
9: if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
10: png_set_expand(png_ptr);
11: if (color_type == PNG_COLOR_TYPE_GRAY ||
12: color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
13: png_set_gray_to_rgb(png_ptr);
1: png_set_read_user_transform_fn(png_ptr,
2: read_transform_fn);
1: png_set_user_transform_info(png_ptr, user_ptr,
2: user_depth, user_channels);
1: voidp read_user_transform_ptr =
2: png_get_user_transform_ptr(png_ptr);
d)更新png数据的详细信息
1: png_read_update_info(png_ptr, info_ptr);
e)读取png数据
1: png_read_image(png_ptr, row_pointers);
1: for (y = 0; y < height; y++)
2: {
3: png_read_rows(png_ptr, &row_pointers[y], png_bytepp_NULL, 1);
4: }
f)结束读取数据
通过png_read_end结束读取png数据,代码如下:
1:
2: png_read_end(png_ptr, info_ptr);
6、释放libpng的内存
1:
2: png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
总结:
http://my.unix-center.net/~Simon_fu/?p=1030