android ndk c++ 绘制图片方式

cpp 复制代码
extern "C" JNIEXPORT void JNICALL
    Java_tv_danmaku_ijk_nativedemo_MainActivity_drawBitmap(JNIEnv *env, jobject thiz, jobject surface, jobject bitmap) {
        AndroidBitmapInfo info;
        if (AndroidBitmap_getInfo(env, bitmap, &info) < 0) {
            LOGE("AndroidBitmap_getInfo error"); return;
        }
        char *data = NULL;
        if (AndroidBitmap_lockPixels(env,bitmap,(void **) &data) < 0){
         LOGE("AndroidBitmap_lockPixels error");
         return;
        }
        if (AndroidBitmap_unlockPixels(env, bitmap) < 0){
            LOGE("AndroidBitmap_unlockPixels error");
            return;
        }
        ANativeWindow *window = ANativeWindow_fromSurface(env,surface);
        if (window == NULL) { LOGE("window is null"); return; }
        int32_t result = ANativeWindow_setBuffersGeometry(window, info.width, info.height, WINDOW_FORMAT_RGBA_8888);
        if (result < 0) {
        LOGE("ANativeWindow_setBuffersGeometry error");
             ANativeWindow_release(window);
              window = NULL;
              return;
         }
         ANativeWindow_acquire(window);
         ANativeWindow_Buffer buffer;
         if (ANativeWindow_lock(window, &buffer, NULL) < 0) {
             LOGE("ANativeWindow_lock error");
             ANativeWindow_release(window);
             window = NULL;
             return;
         } 
         int32_t *bitmapPixes = (int32_t *) data; 
         uint32_t *line = (uint32_t *) buffer.bits; 
         for (int y = 0; y < buffer.height; y++) { 
             for (int x = 0; x < buffer.width; x++) { 
                 line[x] = bitmapPixes[buffer.width*y + x]; 
             } 
             line = line + buffer.stride; 
         } 
         if (ANativeWindow_unlockAndPost(window) < 0) { 
            LOGE("ANativeWindow_unlockAndPost error"); 
         } 
         ANativeWindow_release(window); 
        }
    }

另一种方式

cpp 复制代码
    extern "C" JNIEXPORT void JNICALL
    Java_tv_danmaku_ijk_nativedemo_MainActivity_drawBitmapSurface(JNIEnv *env, jobject thiz, jobject surface, jobject bitmap, jstring vertex_shader, jstring fragment_shader) {
    ANativeWindow *window = ANativeWindow_fromSurface(env, surface);
    EGLint majorVersion, minorVersion;
    EGLDisplay eglDisplay;
    EGLSurface eglSurface;
    EGLContext eglContext;
    GLuint program;
    // EGL初始化
    eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    if (eglInitialize(eglDisplay, &majorVersion, &minorVersion) == EGL_FALSE){
    LOGE("eglInitialize error");
    return; }
    // 配置Surface
    const EGLint attribs[] = {
        EGL_RENDERABLE_TYPE,
         EGL_OPENGL_ES3_BIT,
         EGL_SURFACE_TYPE,
         EGL_WINDOW_BIT,
         EGL_BLUE_SIZE, 8,
         EGL_GREEN_SIZE, 8,
         EGL_RED_SIZE, 8,
         EGL_ALPHA_SIZE, 8,
         EGL_NONE
        };

        EGLConfig configs;
        EGLint numConfig;
        eglChooseConfig(eglDisplay, attribs, &configs, 1, &numConfig);
        eglSurface = eglCreateWindowSurface(eglDisplay, configs, window, NULL);
        // 创建上下文
        const EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE};
        eglContext = eglCreateContext(eglDisplay, configs, NULL, contextAttribs);
        eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
        GLuint vertexShader, fragmentShader;
        // 创建着色器
        vertexShader = glCreateShader(GL_VERTEX_SHADER);
        fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
        const char* vertexShaderSource = env->GetStringUTFChars(vertex_shader, nullptr);
         const char* fragmentShaderSource = env->GetStringUTFChars(fragment_shader, nullptr);
         glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
         glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
         env->ReleaseStringUTFChars(vertex_shader, vertexShaderSource);
         env->ReleaseStringUTFChars(fragment_shader, fragmentShaderSource);
         // 调用glCompileShader 编译着色器,并检查编译状态
         glCompileShader(vertexShader);
         glCompileShader(fragmentShader);
         GLint success;
          glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
          if (!success){
           GLchar infoLog[1024];
           glGetShaderInfoLog(vertexShader, 1024, NULL, infoLog);
            LOGE("glGetShaderiv error %s", infoLog); }
            // 编译着色器
            program = glCreateProgram();
            glAttachShader(program,vertexShader);
            glAttachShader(program, fragmentShader);
            glLinkProgram(program);
            GLint linkStatus;
            glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
            if (linkStatus == GL_FALSE){ GLchar infoLog[512];
                glGetProgramInfoLog(program, 512, NULL, infoLog);
                LOGE("glLinkProgram error %s", infoLog);
            }
             LOGE("glLinkProgram surccess ");
             // 绑定纹理
             GLuint texture;
             glGenTextures(1, &texture);
             glBindTexture(GL_TEXTURE_2D, texture);
             // 加载位图数据
             AndroidBitmapInfo info;
             void* pixels;
              AndroidBitmap_getInfo(env, bitmap, &info);
              AndroidBitmap_lockPixels(env, bitmap, &pixels);
              glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, info.width, info.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
              GLint matrixId = glGetUniformLocation(program, "deformationMatrix");
              GLfloat deformMatrix[16] = {
                   1.0f, 0.0f, 0.0f, 0.0f, // 第一列
                   0.0f, 1.0f, 0.0f, 0.0f, // 第二列
                   0.0f, 0.0f, 1.0f, 0.0f, // 第三列
                   0.0f, 0.0f, 0.0f, 1.0f // 第四列
              };
                // 设置变形矩阵
                glUniformMatrix4fv(matrixId, 1, GL_FALSE, deformMatrix);
                glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
                eglSwapBuffers(eglDisplay, eglSurface);
                AndroidBitmap_unlockPixels(env, bitmap);
                LOGE("----->>>> surccess ");
              }
          }
相关推荐
我变成萤火虫9 分钟前
2026 ICPC沈阳邀请赛Vp补题
数据结构·c++·算法·贪心算法·stl·排序算法·动态规划
Dxy123931021623 分钟前
Python XPath position() 完整使用指南,避坑合集(lxml适用)
前端·javascript·python
AndrewHZ26 分钟前
图像处理入门009 | OpenCV 图像读取与显示:imread/imshow 全解析
图像处理·python·opencv·算法·计算机视觉·图像显示
卷无止境33 分钟前
手写 SQL 在 Tortoise ORM 里到底能派上什么用场
后端·python·fastapi
龙虾PRO36 分钟前
2026 DeepSeek Harness 部署完整教程:npx 一键启动至 Python SDK 全流程接入
开发语言·python
卷无止境36 分钟前
FastAPI、Tortoise ORM 与 PostgreSQL 三件套 是否好用呢?
后端·python·fastapi
小小龙学IT1 小时前
Google Test(gtest/gmock)开源 C++ 单元测试与 Mock 框架完全指南
c++·单元测试·开源
CTA量化套保9 小时前
近期零基础量化学习:先分阶段,再用 AI 检查缺口
人工智能·python
清水白石00810 小时前
Python 死锁排查全攻略:从线程卡死到锁依赖定位与工程化修复
linux·网络·python
Elias不吃糖10 小时前
Langfuse 入门:Trace、Prompt、Dataset、Experiment、Evaluator
前端·python·prompt·langfuse