Home Technical Talk

Blender 2.79: Getting All Pixels From All Textures?

polycounter lvl 6
Offline / Send Message
MrQuetch polycounter lvl 6
Hello, everyone.

The title is pretty self-explanatory. There isn't much more to be said than that. I'm trying to write a script to get every pixel from every texture applied to a model in Blender 2.79. I've found a URL that is already leading me in the right direction: https://blender.stackexchange.com/questions/124264/how-to-read-a-pixel-from-an-image-texture-with-python

However, it simply refers to a texture already loaded in memory. I'd like to get the texture or textures specifically from the model itself. If anyone is wondering why I want to get the pixels from textures, it's because I want to be able to convert my textures to C arrays for the N64. Rather than having to do all of the texture conversions outside of Blender - I feel it'd be easier to simply convert the textures already mapped on to the object itself. Additionally, this will help me further in my development processes.

Thank you very much in advance. Any additional help is greatly appreciated.

Replies

  • MrQuetch
    Options
    Offline / Send Message
    MrQuetch polycounter lvl 6
    I know it's been over two months. But, I looked back into Blender Python again, and have managed to get this. So far, it only converts one texture in the scene. However, I'm trying to find ways to get all textures from all objects in the scene. Anyways, here is my code for single textures: 
    outfile.write("unsigned int %s_tex[] = \n" % (me.name))
    outfile.write("{\n")
    
    # loops through number of pixels 1,024 multipled by 4 which is 4,096
    for i in range(0, 4096, 4):
        current_pixel += 1
        
        pixel = texture_file.pixels[i:i+4]
        pixel_r = round(pixel[0] * 255)
        pixel_g = round(pixel[1] * 255)
        pixel_b = round(pixel[2] * 255)
        
        outfile.write("0x%02X%02X%02XFF," % (pixel_r, pixel_g, pixel_b))
        
        if current_pixel >= 32:
            current_pixel = 0
            outfile.write("\n")
    
    outfile.write("};\n\n")

    I know this looks a bit strange. Basically, I'm exporting the bitmap to be used as a C array of colored pixels for Nintendo 64 homebrew textures. I'm not entirely sure why the for-loop needed three parameters instead of two, but it works as expected. Also, I don't understand why the array needs to get the value of 'i' twice - there's a colon inside, too. Could anyone explain why that part works the way it does? I'm just trying to wrap my head around it. I'm just happy it works as intended. Thanks.

  • poopipe
    Options
    Offline / Send Message
    poopipe grand marshal polycounter
    :  means a range.  So thats i to i+4

    The third arg to the for loop is step size so its looking at  0,4,8 etc.. Rather than 0,1,2,3 etc

    It's grabbing groups of pixels, putting them in a list and then you're getting them out of the new list for the output. 


  • RN
    Options
    Offline / Send Message
    RN sublime tool
    MrQuetch said:
    I'm trying to find ways to get all textures from all objects in the scene.
    An object is of type bpy.types.Object and it doesn't know what a texture is, so what you really want is:
    - Go through all objects in the scene (context.scene.objects, it's an iterable)
    - Go through all materials slots of each object (object.material_slots, also an interable)
    - If the slot has a valid material (because it could be None), get the material (materialSlot.material)
    - Get the textures of the material (method depends on if you're using nodes, with material.node_tree, or the legacy texture slots from the Blender Render engine, with the iterable material.texture_slots -> slot.texture)
Sign In or Register to comment.