安卓opengles使用ndk方式读取png图片

2024-05-16 00:32

本文主要是介绍安卓opengles使用ndk方式读取png图片,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本博客主要是通过使用libpng来进行加载png图片

1libpng图片配置

(1)在官网下载最新的libpng压缩包和zlib压缩包,然后解压,分别放入如下图所示的png目录和zlib目录
最终存放目录
(2)将jni\png\scripts目录下的pnglibconf.h.prebuilt文件复制到jni\png目录下,并且重命名为pnglibconf.h。
(3)在jni\png目录下新建Android.mk文件,内容如下:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)LOCAL_MODULE    := libpng
LOCAL_SRC_FILES :=\png.c \pngerror.c \pngget.c \pngmem.c \pngpread.c \pngread.c \pngrio.c \pngrtran.c \pngrutil.c \pngset.c \pngtest.c \pngtrans.c \pngwio.c \pngwrite.c \pngwtran.c \pngwutil.cLOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/.include $(BUILD_STATIC_LIBRARY)

(4)在jni\zlib目录下新建Android.mk文件,内容如下:

include $(CLEAR_VARS)
LOCAL_MODULE:= zlib
LOCAL_SRC_FILES:= \
adler32.c \
compress.c \
crc32.c \
deflate.c \
gzclose.c \
gzlib.c \
gzread.c \
gzwrite.c \
infback.c \
inflate.c \
inftrees.c \
inffast.c \
trees.c \
uncompr.c \
zutil.c LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
include $(BUILD_STATIC_LIBRARY)

(4)在jni\目录下新建Android.mk文件,文件目录内容如下:

LOCAL_PATH:=$(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE:=libmygles
LOCAL_SRC_FILES:=opengl.cpp
LOCAL_STATIC_LIBRARIES := libpng
LOCAL_STATIC_LIBRARIES += zlib
LOCAL_C_INCLUDES := $(LOCAL_PATH)/png
LOCAL_C_INCLUDES += $(LOCAL_PATH)/zlibLOCAL_LDLIBS:=-llog -lGLESv2 -landroidinclude $(BUILD_SHARED_LIBRARY)include $(CLEAR_VARS)include $(LOCAL_PATH)/png/Android.mk $(LOCAL_PATH)/zlib/Android.mk

(5)修改jni/png/pngpriv.h文件中


#  ifdef __ARM_NEON__
#     define PNG_ARM_NEON_OPT 2
#  else
#     define PNG_ARM_NEON_OPT 0
#  en

#define PNG_ARM_NEON_OPT 0

不然会报错 png_init_filter_fuction_neon
(6)使用ndk编译主文件,我的文件是jni目录下的opengl.cpp文件,该文件中需要包括#include “png.h”,然后编译成功。
(7)使用如下函数读取并创建纹理,试了网上好多函数都不能用,使用该函数编译后,将png图片拷贝到assets函数下,即可调用
“`

GLuint CreateTextureFromPng(const char *filename)
{
info(“enter into CreateTextureFromPng”);

int bitDepth;
int colorType;
int interlaceype;png_uint_32 width;
png_uint_32 height;
void *pixelData = nullptr;
AAsset *asset = nullptr;
unsigned char head[8];
// off_t size;
asset = AAssetManager_open(sAssetManager, filename, AASSET_MODE_UNKNOWN);
if (asset == nullptr)
{info("load file %s fail", filename);return 0;
}
AAsset_read(asset, head, 8);
if (png_sig_cmp(head, 0, 8))
{info("File %s, is not PNG", filename);return 0;
}info("enter into CreateTextureFromPng1");png_structp pngPtr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!pngPtr)
{info("Unable to create PNG structure: %s", filename);return 0;
}// Allocate/initialize the memory for image information.  REQUIRED
png_infop infoPtr = png_create_info_struct(pngPtr);if (!infoPtr)
{png_destroy_read_struct(&pngPtr, NULL, NULL);info("Unable to create PNG info : %s", filename);return 0;
}
info("enter into CreateTextureFromPng2");
png_infop endInfo = png_create_info_struct(pngPtr);
if (!endInfo)
{png_destroy_read_struct(&pngPtr, &infoPtr, NULL);info("Unable to create PNG end info : %s", filename);return 0;
}
// Set error handling if you are using the setjmp/longjmp method (this is
// the normal method of doing things with libpng).  REQUIRED unless you
// set up your own error handlers in the png_create_read_struct() earlier.
if (setjmp(png_jmpbuf(pngPtr)))
{// Free all of the memory associated with the png_ptr and info_ptrpng_destroy_read_struct(&pngPtr, &infoPtr, &endInfo);info("Error during setjmp : %s", filename);return 0;
}
png_set_read_fn(pngPtr, (void *)asset, readPngData);
info("enter into CreateTextureFromPng3");// If we have already read some of the signature
png_set_sig_bytes(pngPtr, 8);png_read_info(pngPtr, infoPtr);png_get_IHDR(pngPtr, infoPtr, &width, &height, &bitDepth, &colorType, &interlaceype, NULL, NULL);info("PNG width = %d, height = %d", width, height);// Update the png info struct.
png_read_update_info(pngPtr, infoPtr);// Allocate the memory to hold the image using the fields of info_ptrunsigned int rowBytes = png_get_rowbytes(pngPtr, infoPtr);
info("Row size: %d bytes", rowBytes);// Allocate the pixel data as a big block, to be given to openGL
pixelData = png_malloc(pngPtr, rowBytes * height);
if (!pixelData)
{png_destroy_read_struct(&pngPtr, &infoPtr, &endInfo);info("Unable to allocate PNG pixel data while loading %s", filename);return 0;
}
int numberPasses = png_set_interlace_handling(pngPtr);
info("interlacing passes = %d", numberPasses);
for (int pass = 0; pass < numberPasses; pass++)
{for (int row = 0; row < height; row++){png_read_row(pngPtr, ((unsigned char *)pixelData + (row * rowBytes)), NULL);}
}png_read_end(pngPtr, infoPtr);png_destroy_read_struct(&pngPtr, &infoPtr, &endInfo);info("enter into CreateTextureFromPng4");AAsset_close(asset);
//此时  pixelData 已经赋值结束     png_uint_32 width;       png_uint_32 height;GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelData);
glBindTexture(GL_TEXTURE_2D, 0);info("enter into CreateTextureFromPng5");
return texture;

}

2参考链接


(1)http://www.xuebuyuan.com/zh-hant/1894472.html
(2)http://blog.csdn.net/talkxin/article/details/50968313
(3)http://blog.sina.com.cn/s/blog_643634b80101hzi8.html
(4)https://stackoverflow.com/questions/19089014/iphone-device-linker-error

这篇关于安卓opengles使用ndk方式读取png图片的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/993363

相关文章

gradle第三方Jar包依赖统一管理方式

《gradle第三方Jar包依赖统一管理方式》:本文主要介绍gradle第三方Jar包依赖统一管理方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录背景实现1.顶层模块build.gradle添加依赖管理插件2.顶层模块build.gradle添加所有管理依赖包

使用Python实现IP地址和端口状态检测与监控

《使用Python实现IP地址和端口状态检测与监控》在网络运维和服务器管理中,IP地址和端口的可用性监控是保障业务连续性的基础需求,本文将带你用Python从零打造一个高可用IP监控系统,感兴趣的小伙... 目录概述:为什么需要IP监控系统使用步骤说明1. 环境准备2. 系统部署3. 核心功能配置系统效果展

使用Java将各种数据写入Excel表格的操作示例

《使用Java将各种数据写入Excel表格的操作示例》在数据处理与管理领域,Excel凭借其强大的功能和广泛的应用,成为了数据存储与展示的重要工具,在Java开发过程中,常常需要将不同类型的数据,本文... 目录前言安装免费Java库1. 写入文本、或数值到 Excel单元格2. 写入数组到 Excel表格

redis中使用lua脚本的原理与基本使用详解

《redis中使用lua脚本的原理与基本使用详解》在Redis中使用Lua脚本可以实现原子性操作、减少网络开销以及提高执行效率,下面小编就来和大家详细介绍一下在redis中使用lua脚本的原理... 目录Redis 执行 Lua 脚本的原理基本使用方法使用EVAL命令执行 Lua 脚本使用EVALSHA命令

Linux之systemV共享内存方式

《Linux之systemV共享内存方式》:本文主要介绍Linux之systemV共享内存方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、工作原理二、系统调用接口1、申请共享内存(一)key的获取(二)共享内存的申请2、将共享内存段连接到进程地址空间3、将

Maven中引入 springboot 相关依赖的方式(最新推荐)

《Maven中引入springboot相关依赖的方式(最新推荐)》:本文主要介绍Maven中引入springboot相关依赖的方式(最新推荐),本文给大家介绍的非常详细,对大家的学习或工作具有... 目录Maven中引入 springboot 相关依赖的方式1. 不使用版本管理(不推荐)2、使用版本管理(推

Java 中的 @SneakyThrows 注解使用方法(简化异常处理的利与弊)

《Java中的@SneakyThrows注解使用方法(简化异常处理的利与弊)》为了简化异常处理,Lombok提供了一个强大的注解@SneakyThrows,本文将详细介绍@SneakyThro... 目录1. @SneakyThrows 简介 1.1 什么是 Lombok?2. @SneakyThrows

使用Python和Pyecharts创建交互式地图

《使用Python和Pyecharts创建交互式地图》在数据可视化领域,创建交互式地图是一种强大的方式,可以使受众能够以引人入胜且信息丰富的方式探索地理数据,下面我们看看如何使用Python和Pyec... 目录简介Pyecharts 简介创建上海地图代码说明运行结果总结简介在数据可视化领域,创建交互式地

Java Stream流使用案例深入详解

《JavaStream流使用案例深入详解》:本文主要介绍JavaStream流使用案例详解,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录前言1. Lambda1.1 语法1.2 没参数只有一条语句或者多条语句1.3 一个参数只有一条语句或者多

Java Spring 中 @PostConstruct 注解使用原理及常见场景

《JavaSpring中@PostConstruct注解使用原理及常见场景》在JavaSpring中,@PostConstruct注解是一个非常实用的功能,它允许开发者在Spring容器完全初... 目录一、@PostConstruct 注解概述二、@PostConstruct 注解的基本使用2.1 基本代