Texture unpack的实现

        <dict>
            <key>P_inactive.png</key>
            <dict>
                <key>aliases</key>
                <array/>
                <key>spriteOffset</key>    <!--  变量名  -->
                <string>{0,0}</string>     <!--  变量值 变量类型   -->
                <key>spriteSize</key>   
                <string>{60,68}</string>    <!--  图片尺寸大小  -->
                <key>spriteSourceSize</key>
                <string>{60,68}</string>     
                <key>textureRect</key>
                <string>{{2142,2548},{60,68}}</string>  <!--  图片坐标起点:2142,2548  图片大小 :60*68   -->
                <key>textureRotated</key>   <!--  图片旋转为True,不旋转为False   -->
                <true/>
            </dict>
  • 实现代码  
#!python
#-*-coding:utf-8-*-
import os,sys
from xml.etree import ElementTree
from PIL import Image

def tree_to_dict(tree):
    d = {}  #字典 {key:value}
    for index, item in enumerate(tree):
        if item.tag == 'key':
            if tree[index+1].tag == 'string':
                d[item.text] = tree[index + 1].text
            elif tree[index + 1].tag == 'true':
                d[item.text] = True
            elif tree[index + 1].tag == 'false':
                d[item.text] = False
            elif tree[index+1].tag == 'dict':
                d[item.text] = tree_to_dict(tree[index+1])
    #遍历打印我们需要的参数包括key,string,true,false
    #for v,k in d.items():
    #    print('{v}:{k}'.format(v = v, k = k))    
    return d 
    
def gen_png_from_plist(plist_filename, png_filename):
    file_path = plist_filename.replace('.plist', '')
    #print(file_path)
    big_image = Image.open(png_filename)

    str_tmp = open(plist_filename, 'r').read()
    #print(str_tmp)

    root = ElementTree.fromstring(str_tmp)

    plist_dict = tree_to_dict(root[0])
    to_list = lambda x: x.replace('{','').replace('}','').split(',') 

    print("*****************************************")
    #print(plist_dict['frames'].items())

    for k,v in plist_dict['frames'].items():
        spriteSourceSize = v["spriteSourceSize"] if v.__contains__("spriteSourceSize") else v["sourceSize"]
        spriteSourceSize = [ int(x) for x in to_list(spriteSourceSize) ]
        # pack后剩下的有效区域
        textureRect = v["textureRect"] if v.__contains__("textureRect") else v["frame"]
        textureRect = [ int(x) for x in to_list(textureRect) ]
        # 是否旋转
        isRotate = v["textureRotated"] if v.__contains__("textureRotated") else v["rotated"]
        print(isRotate)
        # 小图在大图上的区域
        spriteOffset = v["spriteOffset"] if v.__contains__("spriteOffset") else v["offset"]
        spriteOffset = [ int(x) for x in to_list(spriteOffset) ]
        # 获得长宽
        width = int( textureRect[3] if isRotate else textureRect[2] )  
        height = int( textureRect[2] if isRotate else textureRect[3] ) 
        box = [ textureRect[0], textureRect[1], textureRect[0] + width, textureRect[1] + height ]

        rect_on_big = big_image.crop(box)
        #rect_on_big.show();
        if isRotate:
            rect_on_big = rect_on_big.rotate(90,expand = True)#expand = True避免result_image.paste报错image unmatch
            #rect_on_big.show();

        result_image = Image.new('RGBA', spriteSourceSize, (0,0,0,0))
        if isRotate:
            result_box=(  
                int(( spriteSourceSize[0] - height)/2 + spriteOffset[0]),  
                int(( spriteSourceSize[1] - width)/2 - spriteOffset[1]),  
                int(( spriteSourceSize[0] + height)/2 + spriteOffset[0]),  
                int(( spriteSourceSize[1] + width)/2 - spriteOffset[1])   
                )
            print(result_box)  
        else:
            result_box=(  
                int(( spriteSourceSize[0] - width)/2 + spriteOffset[0]),  
                int(( spriteSourceSize[1] - height)/2 - spriteOffset[1]),  
                int(( spriteSourceSize[0] + width)/2 + spriteOffset[0]),  
                int(( spriteSourceSize[1] + height)/2 - spriteOffset[1]) 
                )
            print(result_box)       
        result_image.paste(rect_on_big, result_box, mask = 0)

        outfile = filename + '/' + k
        print (outfile, "generated")
        if not os.path.exists(os.path.dirname(outfile)):
            os.makedirs(os.path.dirname(outfile))

        result_image.save(outfile)

        if isRotate:
            print("isRotate", isRotate, k)


if __name__ == '__main__':
    filename = sys.argv[1]  # 输入的文件名
    plist_filename = filename + '.plist' # 
    png_filename = filename + '.png'  #
    if (os.path.exists(plist_filename) and os.path.exists(png_filename)):  #
        gen_png_from_plist( plist_filename, png_filename )
    else:
        print ("make sure you have both plist and png files in the same directory")

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
实现文字映射到VR全景图片任意位置,需要使用以下步骤: 1. 将全景图片加载到内存中。可以使用OpenCV库加载图片。 2. 创建一个虚拟环境,例如OpenGL场景,用于展示全景图片和文字。 3. 将文本转换为纹理,并将其加载到OpenGL中。 4. 将全景图片和文字纹理映射到OpenGL场景中。可以使用OpenGL的纹理映射功能来实现。 下面是一个简单的示例代码,用于将文字映射到VR全景图片的任意位置。这里我们使用OpenGL来创建虚拟环境,并使用FreeType库将文本转换为纹理。 ```c++ #include <iostream> #include <GL/glew.h> #include <GLFW/glfw3.h> #include <opencv2/opencv.hpp> #include <ft2build.h> #include FT_FREETYPE_H using namespace std; using namespace cv; // 顶点着色器 const char* vertexShaderSource = "#version 330 core\n" "layout (location = 0) in vec3 aPos;\n" "layout (location = 1) in vec2 aTexCoord;\n" "out vec2 TexCoord;\n" "void main()\n" "{\n" " gl_Position = vec4(aPos, 1.0);\n" " TexCoord = vec2(aTexCoord.x, aTexCoord.y);\n" "}\0"; // 片段着色器 const char* fragmentShaderSource = "#version 330 core\n" "in vec2 TexCoord;\n" "out vec4 FragColor;\n" "uniform sampler2D ourTexture;\n" "void main()\n" "{\n" " FragColor = texture(ourTexture, TexCoord);\n" "}\n\0"; // 文本渲染器 class TextRenderer { public: TextRenderer(const char* fontPath, int fontSize) { FT_Init_FreeType(&ft); FT_New_Face(ft, fontPath, 0, &face); FT_Set_Pixel_Sizes(face, 0, fontSize); glGenTextures(1, &texId); glBindTexture(GL_TEXTURE_2D, texId); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } void renderText(const char* text, float x, float y, float sx, float sy) { glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, buffer); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texId); glUniform1i(glGetUniformLocation(shaderProgram, "ourTexture"), 0); GLfloat vertices[] = { x, y + height * sy, 0.0f, 0.0f, x + width * sx, y + height * sy, 1.0f, 0.0f, x + width * sx, y, 1.0f, 1.0f, x, y, 0.0f, 1.0f }; unsigned int indices[] = { 0, 1, 2, 2, 3, 0 }; GLuint VAO, VBO, EBO; glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); glGenBuffers(1, &EBO); glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (void*)0); glEnableVertexAttribArray(0); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (void*)(2 * sizeof(GLfloat))); glEnableVertexAttribArray(1); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); glDeleteVertexArrays(1, &VAO); glDeleteBuffers(1, &VBO); glDeleteBuffers(1, &EBO); } void setText(const char* text) { FT_GlyphSlot g = face->glyph; int w = 0, h = 0; for (int i = 0; i < strlen(text); i++) { FT_Load_Char(face, text[i], FT_LOAD_RENDER); w += g->bitmap.width; h = max(h, g->bitmap.rows); } width = w; height = h; buffer = new unsigned char[width * height]; int x = 0; for (int i = 0; i < strlen(text); i++) { FT_Load_Char(face, text[i], FT_LOAD_RENDER); for (int j = 0; j < g->bitmap.width; j++) { for (int k = 0; k < g->bitmap.rows; k++) { buffer[(k + g->bitmap_top) * width + (x + j)] = g->bitmap.buffer[k * g->bitmap.width + j]; } } x += g->bitmap.width; } } private: FT_Library ft; FT_Face face; unsigned char* buffer; GLuint texId; int width, height; }; int main() { // 初始化OpenGL glfwInit(); GLFWwindow* window = glfwCreateWindow(800, 600, "Text on VR panorama", NULL, NULL); glfwMakeContextCurrent(window); glewExperimental = GL_TRUE; glewInit(); // 加载全景图片 Mat img = imread("panorama.jpg"); if (img.empty()) { cout << "Failed to load image!" << endl; return -1; } // 创建文本渲染器 TextRenderer renderer("arial.ttf", 48); // 创建着色器程序 GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); glCompileShader(vertexShader); GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL); glCompileShader(fragmentShader); GLuint shaderProgram = glCreateProgram(); glAttachShader(shaderProgram, vertexShader); glAttachShader(shaderProgram, fragmentShader); glLinkProgram(shaderProgram); // 加载图片到OpenGL中 GLuint textureId; glGenTextures(1, &textureId); glBindTexture(GL_TEXTURE_2D, textureId); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img.cols, img.rows, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, img.ptr()); // 渲染循环 while (!glfwWindowShouldClose(window)) { glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glUseProgram(shaderProgram); GLfloat vertices[] = { // 顶点坐标 纹理坐标 -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, -1.0f, -1.0f, 0.0f, 0.0f, }; unsigned int indices[] = { 0, 1, 2, 2, 3, 0 }; GLuint VAO, VBO, EBO; glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); glGenBuffers(1, &EBO); glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (void*)0); glEnableVertexAttribArray(0); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (void*)(2 * sizeof(GLfloat))); glEnableVertexAttribArray(1); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, textureId); glUniform1i(glGetUniformLocation(shaderProgram, "ourTexture"), 0); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); // 渲染文本 renderer.setText("Hello, world!"); renderer.renderText("Hello, world!", 400, 300, 0.5, 0.5); glfwSwapBuffers(window); glfwPollEvents(); } glfwTerminate(); return 0; } ``` 这是一个简单的示例代码,演示了如何将文本映射到VR全景图片的任意位置。您可以根据自己的需求进行修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值