庫地址
https://github.com/julienr/libpng-android
設置NDK環境變量
將NDK目錄加入PATH變量:
C:\Users\xx\AppData\Local\Android\Sdk\ndk\20.0.5594570\
靜態庫
修改Android.mk文件
#LOCAL_SHARED_LIBRARIES := -lz
LOCAL_EXPORT_LDLIBS := -lz
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/.
#include $(BUILD_SHARED_LIBRARY)
include $(BUILD_STATIC_LIBRARY)
動態庫
修改Android.mk文件
#LOCAL_SHARED_LIBRARIES := -lz
#LOCAL_EXPORT_LDLIBS := -lz
LOCAL_LDLIBS := -lz
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/.
include $(BUILD_SHARED_LIBRARY)
#include $(BUILD_STATIC_LIBRARY)
編譯命令
ndk-build NDK_PROJECT_PATH=./
libpng庫使用
從內存中讀取png圖片數據,解碼爲RGBA格式的raw數據
glPngReader.h
//
// Created by Jinzhu on 2019/9/7.
//
#ifndef OPENGLES_GLPNGREADER_H
#define OPENGLES_GLPNGREADER_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdlib.h>
#include <stdio.h>
#include <setjmp.h>
#include <string.h>
struct glPngReader {
uint8_t *m_raw_data;
size_t m_raw_size;
size_t m_raw_offset;
int m_width;
int m_height;
int m_color_type;
int m_pixel_depth;
int m_status;
uint8_t *m_pixel_data;
};
void glPngReader_Create(struct glPngReader *pngReader, uint8_t *raw_data, size_t raw_size);
void glPngReader_Destory(struct glPngReader *pngReader);
uint8_t *glPngReader_GetPixelData(struct glPngReader *pngReader);
int glPngReader_GetWidth(struct glPngReader *pngReader);
int glPngReader_GetHeight(struct glPngReader *pngReader);
#ifdef __cplusplus
};
#endif
#endif //OPENGLES_GLPNGREADER_H
glPngReader.c
//
// Created by Jinzhu on 2019/9/7.
//
#include <android/log.h>
#ifdef __cplusplus
extern "C" {
#endif
#include "glPngReader.h"
#include <pnglibconf.h>
#include <png.h>
#include <pngstruct.h>
#include <pngconf.h>
#include <pnginfo.h>
#define LOG_TAG "PNGREADER-LIB"
#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
void glPngReader_ReadCallback(png_structp png_ptr, png_bytep data, png_size_t length) {
struct glPngReader *pThis = (struct glPngReader *) png_get_io_ptr(png_ptr);
if (pThis != NULL) {
if (pThis->m_raw_offset + length <= pThis->m_raw_size) {
memcpy(data, pThis->m_raw_data + pThis->m_raw_offset, length);
pThis->m_raw_offset += length;
} else {
ALOGE("the length is illegal.");
}
}
}
void glPngReader_ReadImage(struct glPngReader *pngReader) {
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (png_ptr == NULL) {
ALOGE("load libpng error,png_ptr = NULL.");
pngReader->m_status = 0;
return;
}
png_infop info_ptr = png_create_info_struct(png_ptr);
if (info_ptr == NULL) {
png_destroy_read_struct(&png_ptr, NULL, NULL);
ALOGE("load libpng error,info_ptr = NULL.");
pngReader->m_status = 0;
return;
}
if (setjmp(png_jmpbuf(png_ptr))) {
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
ALOGE("libpng process error.");
pngReader->m_status = 0;
return;
}
png_set_read_fn(png_ptr, pngReader, glPngReader_ReadCallback);
png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_EXPAND, NULL);
pngReader->m_width = info_ptr->width;
pngReader->m_height = info_ptr->height;
pngReader->m_color_type = info_ptr->color_type;
pngReader->m_pixel_depth = info_ptr->pixel_depth;
if ((pngReader->m_color_type != PNG_COLOR_TYPE_RGB &&
pngReader->m_color_type != PNG_COLOR_TYPE_RGB_ALPHA)
&& pngReader->m_pixel_depth == 8) {
ALOGE("image format error.");
pngReader->m_status = 0;
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
return;
}
if (pngReader->m_pixel_data != NULL) {
free(pngReader->m_pixel_data);
pngReader->m_pixel_data = NULL;
}
pngReader->m_pixel_data = (uint8_t *) malloc(pngReader->m_width * pngReader->m_height * 4);
png_bytep *row_pointers = png_get_rows(png_ptr, info_ptr);
if (pngReader->m_color_type == PNG_COLOR_TYPE_RGB) {
int pos = 0;
for (int row = 0; row < pngReader->m_height; ++row) {
for (int col = 0; col < (3 * pngReader->m_width); col += 3) {
pngReader->m_pixel_data[pos++] = row_pointers[row][col + 0];//RED
pngReader->m_pixel_data[pos++] = row_pointers[row][col + 1];//GREEN
pngReader->m_pixel_data[pos++] = row_pointers[row][col + 2];//BLUE
pngReader->m_pixel_data[pos++] = 255;//ALPHA
}
}
pngReader->m_status = 1;
} else if (pngReader->m_color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
int pos = 0;
for (int row = 0; row < pngReader->m_height; ++row) {
for (int col = 0; col < (4 * pngReader->m_width); col += 4) {
pngReader->m_pixel_data[pos++] = row_pointers[row][col + 0];//RED
pngReader->m_pixel_data[pos++] = row_pointers[row][col + 1];//GREEN
pngReader->m_pixel_data[pos++] = row_pointers[row][col + 2];//BLUE
pngReader->m_pixel_data[pos++] = row_pointers[row][col + 3];//ALPHA
}
}
pngReader->m_status = 1;
} else {
pngReader->m_status = 0;
}
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
}
void glPngReader_Create(struct glPngReader *pngReader, uint8_t *raw_data, size_t raw_size) {
pngReader->m_raw_data = raw_data;
pngReader->m_raw_size = raw_size;
pngReader->m_raw_offset = 0;
pngReader->m_width = 0;
pngReader->m_height = 0;
pngReader->m_color_type = PNG_TRANSFORM_STRIP_ALPHA;
pngReader->m_pixel_depth = 8;
pngReader->m_status = 0;
pngReader->m_pixel_data = NULL;
glPngReader_ReadImage(pngReader);
}
void glPngReader_Destory(struct glPngReader *pngReader) {
if (pngReader->m_pixel_data != NULL) {
free(pngReader->m_pixel_data);
pngReader->m_pixel_data = NULL;
}
}
uint8_t *glPngReader_GetPixelData(struct glPngReader *pngReader) { return pngReader->m_pixel_data; }
int glPngReader_GetWidth(struct glPngReader *pngReader) { return pngReader->m_width; }
int glPngReader_GetHeight(struct glPngReader *pngReader) { return pngReader->m_height; }
#ifdef __cplusplus
};
#endif