Version

Quick search

Texture

Changed in version 1.6.0: Added support for paletted texture on OES: ‘palette4_rgb8’, ‘palette4_rgba8’, ‘palette4_r5_g6_b5’, ‘palette4_rgba4’, ‘palette4_rgb5_a1’, ‘palette8_rgb8’, ‘palette8_rgba8’, ‘palette8_r5_g6_b5’, ‘palette8_rgba4’ and ‘palette8_rgb5_a1’.

Texture is a class that handles OpenGL textures. Depending on the hardware, some OpenGL capabilities might not be available (BGRA support, NPOT support, etc.)

You cannot instantiate this class yourself. You must use the function Texture.create() to create a new texture:

texture = Texture.create(size=(640, 480))

When you create a texture, you should be aware of the default color and buffer format:

  • the color/pixel format (Texture.colorfmt) that can be one of ‘rgb’, ‘rgba’, ‘luminance’, ‘luminance_alpha’, ‘bgr’ or ‘bgra’. The default value is ‘rgb’

  • the buffer format determines how a color component is stored into memory. This can be one of ‘ubyte’, ‘ushort’, ‘uint’, ‘byte’, ‘short’, ‘int’ or ‘float’. The default value and the most commonly used is ‘ubyte’.

So, if you want to create an RGBA texture:

texture = Texture.create(size=(640, 480), colorfmt='rgba')

You can use your texture in almost all vertex instructions with the kivy.graphics.VertexIntruction.texture parameter. If you want to use your texture in kv lang, you can save it in an ObjectProperty inside your widget.

Warning

Using Texture before OpenGL has been initialized will lead to a crash. If you need to create textures before the application has started, import Window first: from kivy.core.window import Window

Blitting custom data

You can create your own data and blit it to the texture using Texture.blit_buffer().

For example, to blit immutable bytes data:

# create a 64x64 texture, defaults to rgba / ubyte
texture = Texture.create(size=(64, 64))

# create 64x64 rgb tab, and fill with values from 0 to 255
# we'll have a gradient from black to white
size = 64 * 64 * 3
buf = [int(x * 255 / size) for x in range(size)]

# then, convert the array to a ubyte string
buf = bytes(buf)

# then blit the buffer
texture.blit_buffer(buf, colorfmt='rgb', bufferfmt='ubyte')

# that's all ! you can use it in your graphics now :)
# if self is a widget, you can do this
with self.canvas:
    Rectangle(texture=texture, pos=self.pos, size=(64, 64))

Since 1.9.0, you can blit data stored in a instance that implements the python buffer interface, or a memoryview thereof, such as numpy arrays, python array.array, a bytearray, or a cython array. This is beneficial if you expect to blit similar data, with perhaps a few changes in the data.

When using a bytes representation of the data, for every change you have to regenerate the bytes instance, from perhaps a list, which is very inefficient. When using a buffer object, you can simply edit parts of the original data. Similarly, unless starting with a bytes object, converting to bytes requires a full copy, however, when using a buffer instance, no memory is copied, except to upload it to the GPU.

Continuing with the example above:

from array import array

size = 64 * 64 * 3
buf = [int(x * 255 / size) for x in range(size)]
# initialize the array with the buffer values
arr = array('B', buf)
# now blit the array
texture.blit_buffer(arr, colorfmt='rgb', bufferfmt='ubyte')

# now change some elements in the original array
arr[24] = arr[50] = 99
# blit again the buffer
texture.blit_buffer(arr, colorfmt='rgb', bufferfmt='ubyte')

BGR/BGRA support

The first time you try to create a BGR or BGRA texture, we check whether your hardware supports BGR / BGRA textures by checking the extension ‘GL_EXT_bgra’.

If the extension is not found, the conversion to RGB / RGBA will be done in software.

NPOT texture

Changed in version 1.0.7: If your hardware supports NPOT, no POT is created.

As the OpenGL documentation says, a texture must be power-of-two sized. That means your width and height can be one of 64, 32, 256… but not 3, 68, 42. NPOT means non-power-of-two. OpenGL ES 2 supports NPOT textures natively but with some drawbacks. Another type of NPOT texture is called a rectangle texture. POT, NPOT and textures all have their own pro/cons.

Features

POT

NPOT

Rectangle

OpenGL Target

GL_TEXTURE_2D

GL_TEXTURE_2D

GL_TEXTURE_RECTANGLE_(NV|ARB|EXT)

Texture coords

0-1 range

0-1 range

width-height range

Mipmapping

Supported

Partially

No

Wrap mode

Supported

Supported

No

If you create a NPOT texture, we first check whether your hardware supports it by checking the extensions GL_ARB_texture_non_power_of_two or OES_texture_npot. If none of these are available, we create the nearest POT texture that can contain your NPOT texture. The Texture.create() will return a TextureRegion instead.

Texture atlas

A texture atlas is a single texture that contains many images. If you want to separate the original texture into many single ones, you don’t need to. You can get a region of the original texture. That will return the original texture with custom texture coordinates:

# for example, load a 128x128 image that contain 4 64x64 images
from kivy.core.image import Image
texture = Image('mycombinedimage.png').texture

bottomleft = texture.get_region(0, 0, 64, 64)
bottomright = texture.get_region(0, 64, 64, 64)
topleft = texture.get_region(0, 64, 64, 64)
topright = texture.get_region(64, 64, 64, 64)

Mipmapping

New in version 1.0.7.

Mipmapping is an OpenGL technique for enhancing the rendering of large textures to small surfaces. Without mipmapping, you might see pixelation when you render to small surfaces. The idea is to precalculate the subtexture and apply some image filter as a linear filter. Then, when you render a small surface, instead of using the biggest texture, it will use a lower filtered texture. The result can look better this way.

To make that happen, you need to specify mipmap=True when you create a texture. Some widgets already give you the ability to create mipmapped textures, such as the Label and Image.

From the OpenGL Wiki : “So a 64x16 2D texture can have 5 mip-maps: 32x8, 16x4, 8x2, 4x1, 2x1, and 1x1”. Check http://www.opengl.org/wiki/Texture for more information.

Note

As the table in previous section said, if your texture is NPOT, we create the nearest POT texture and generate a mipmap from it. This might change in the future.

Reloading the Texture

New in version 1.2.0.

If the OpenGL context is lost, the Texture must be reloaded. Textures that have a source are automatically reloaded but generated textures must be reloaded by the user.

Use the Texture.add_reload_observer() to add a reloading function that will be automatically called when needed:

def __init__(self, **kwargs):
    super(...).__init__(**kwargs)
    self.texture = Texture.create(size=(512, 512), colorfmt='RGB',
        bufferfmt='ubyte')
    self.texture.add_reload_observer(self.populate_texture)

    # and load the data now.
    self.cbuffer = '\x00\xf0\xff' * 512 * 512
    self.populate_texture(self.texture)

def populate_texture(self, texture):
    texture.blit_buffer(self.cbuffer)

This way, you can use the same method for initialization and reloading.

Note

For all text rendering with our core text renderer, the texture is generated but we already bind a method to redo the text rendering and reupload the text to the texture. You don’t have to do anything.

class kivy.graphics.texture.Texture(width, height, target, texid=0, colorfmt='rgb', bufferfmt='ubyte', mipmap=False, source=None, callback=None, icolorfmt='rgb')

Bases: builtins.object

textures or complex textures based on ImageData.

add_reload_observer(self, callback)

Add a callback to be called after the whole graphics context has been reloaded. This is where you can reupload your custom data into the GPU.

New in version 1.2.0.

Parameters:
callback: func(context) -> return None

The first parameter will be the context itself.

ask_update(self, callback)

Indicate that the content of the texture should be updated and the callback function needs to be called when the texture will be used.

bind(self)

Bind the texture to the current opengl state.

blit_buffer(self, pbuffer, size=None, colorfmt=None, pos=None, bufferfmt=None, mipmap_level=0, mipmap_generation=True, int rowlength=0)

Blit a buffer into the texture.

Note

Unless the canvas will be updated due to other changes, ask_update() should be called in order to update the texture.

Parameters:
pbuffer: bytes, or a class that implements the buffer interface (including memoryview).

A buffer containing the image data. It can be either a bytes object or a instance of a class that implements the python buffer interface, e.g. array.array, bytearray, numpy arrays etc. If it’s not a bytes object, the underlying buffer must be contiguous, have only one dimension and must not be readonly, even though the data is not modified, due to a cython limitation. See module description for usage details.

size: tuple, defaults to texture size

Size of the image (width, height)

colorfmt: str, defaults to ‘rgb’

Image format, can be one of ‘rgb’, ‘rgba’, ‘bgr’, ‘bgra’, ‘luminance’ or ‘luminance_alpha’.

pos: tuple, defaults to (0, 0)

Position to blit in the texture.

bufferfmt: str, defaults to ‘ubyte’

Type of the data buffer, can be one of ‘ubyte’, ‘ushort’, ‘uint’, ‘byte’, ‘short’, ‘int’ or ‘float’.

mipmap_level: int, defaults to 0

Indicate which mipmap level we are going to update.

mipmap_generation: bool, defaults to True

Indicate if we need to regenerate the mipmap from level 0.

Changed in version 1.0.7: added mipmap_level and mipmap_generation

Changed in version 1.9.0: pbuffer can now be any class instance that implements the python buffer interface and / or memoryviews thereof.

blit_data(self, im, pos=None)

Replace a whole texture with image data.

bufferfmt

Return the buffer format used in this texture (readonly).

New in version 1.2.0.

colorfmt

Return the color format used in this texture (readonly).

New in version 1.0.7.

static create(size=None, colorfmt=None, bufferfmt=None, mipmap=False, callback=None, icolorfmt=None)

texture_create(size=None, colorfmt=None, bufferfmt=None, mipmap=False, callback=None, icolorfmt=None) Create a texture based on size.

Parameters:
size: tuple, defaults to (128, 128)

Size of the texture.

colorfmt: str, defaults to ‘rgba’

Color format of the texture. Can be ‘rgba’ or ‘rgb’, ‘luminance’ or ‘luminance_alpha’. On desktop, additional values are available: ‘red’, ‘rg’.

icolorfmt: str, defaults to the value of colorfmt

Internal format storage of the texture. Can be ‘rgba’ or ‘rgb’, ‘luminance’ or ‘luminance_alpha’. On desktop, additional values are available: ‘r8’, ‘rg8’, ‘rgba8’.

bufferfmt: str, defaults to ‘ubyte’

Internal buffer format of the texture. Can be ‘ubyte’, ‘ushort’, ‘uint’, ‘bute’, ‘short’, ‘int’ or ‘float’.

mipmap: bool, defaults to False

If True, it will automatically generate the mipmap texture.

callback: callable(), defaults to False

If a function is provided, it will be called when data is needed in the texture.

Changed in version 1.7.0: callback has been added

static create_from_data(im, mipmap=False)

texture_create_from_data(im, mipmap=False) Create a texture from an ImageData class.

flip_horizontal(self)

Flip tex_coords for horizontal display.

New in version 1.9.0.

flip_vertical(self)

Flip tex_coords for vertical display.

get_region(self, x, y, width, height)

Return a part of the texture defined by the rectangular arguments (x, y, width, height). Returns a TextureRegion instance.

height

Return the height of the texture (readonly).

id

Return the OpenGL ID of the texture (readonly).

mag_filter

Get/set the mag filter texture. Available values:

  • linear

  • nearest

Check the opengl documentation for more information about the behavior of these values : http://www.khronos.org/opengles/sdk/docs/man/xhtml/glTexParameter.xml.

min_filter

Get/set the min filter texture. Available values:

  • linear

  • nearest

  • linear_mipmap_linear

  • linear_mipmap_nearest

  • nearest_mipmap_nearest

  • nearest_mipmap_linear

Check the opengl documentation for more information about the behavior of these values : http://www.khronos.org/opengles/sdk/docs/man/xhtml/glTexParameter.xml.

mipmap

Return True if the texture has mipmap enabled (readonly).

pixels

Get the pixels texture, in RGBA format only, unsigned byte. The origin of the image is at bottom left.

New in version 1.7.0.

remove_reload_observer(self, callback)

Remove a callback from the observer list, previously added by add_reload_observer().

New in version 1.2.0.

save(self, filename, flipped=True, fmt=None)

Save the texture content to a file. Check kivy.core.image.Image.save() for more information.

The flipped parameter flips the saved image vertically, and defaults to True.

New in version 1.7.0.

Changed in version 1.8.0: Parameter flipped added, defaults to True. All the OpenGL Texture are read from bottom / left, it need to be flipped before saving. If you don’t want to flip the image, set flipped to False.

Changed in version 1.11.0: Parameter fmt added, to pass the final format to the image provider. Used if filename is a BytesIO

size

Return the (width, height) of the texture (readonly).

target

Return the OpenGL target of the texture (readonly).

tex_coords

Return the list of tex_coords (opengl).

uvpos

Get/set the UV position inside the texture.

uvsize

Get/set the UV size inside the texture.

Warning

The size can be negative if the texture is flipped.

width

Return the width of the texture (readonly).

wrap

Get/set the wrap texture. Available values:

  • repeat

  • mirrored_repeat

  • clamp_to_edge

Check the opengl documentation for more information about the behavior of these values : http://www.khronos.org/opengles/sdk/docs/man/xhtml/glTexParameter.xml.

class kivy.graphics.texture.TextureRegion(int x, int y, int width, int height, Texture origin)

Bases: kivy.graphics.texture.Texture

texture handling.

ask_update(self, callback)
bind(self)
pixels