From 59adfc0979aaf940e47a28ff7a196881fc019668 Mon Sep 17 00:00:00 2001 From: Oxicid Date: Thu, 13 Apr 2023 05:51:43 +0200 Subject: [PATCH] io_mesh_uv_layout: speed up png export with OIIO (x7) Since png eventually stores data in int8 type, when using bpy to save an image, you actually have to convert the types twice, first to float and then back to int8. Using library OIIO allows you to avoid such conversions, as directly with int8, thereby speed of the whole operation increases in 7 times. Also, OIIO is more correct in premultiplied alpha, now the texture is not darkened. Ref !104545 with minor updates by @ideasman42. --- io_mesh_uv_layout/__init__.py | 2 +- io_mesh_uv_layout/export_uv_png.py | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/io_mesh_uv_layout/__init__.py b/io_mesh_uv_layout/__init__.py index 7145384c..dfa47e70 100644 --- a/io_mesh_uv_layout/__init__.py +++ b/io_mesh_uv_layout/__init__.py @@ -3,7 +3,7 @@ bl_info = { "name": "UV Layout", "author": "Campbell Barton, Matt Ebb", - "version": (1, 1, 5), + "version": (1, 1, 6), "blender": (3, 0, 0), "location": "UV Editor > UV > Export UV Layout", "description": "Export the UV layout as a 2D graphic", diff --git a/io_mesh_uv_layout/export_uv_png.py b/io_mesh_uv_layout/export_uv_png.py index ad1b2284..f6c5cf40 100644 --- a/io_mesh_uv_layout/export_uv_png.py +++ b/io_mesh_uv_layout/export_uv_png.py @@ -6,6 +6,12 @@ from mathutils import Vector, Matrix from mathutils.geometry import tessellate_polygon from gpu_extras.batch import batch_for_shader +# Use OIIO if available, else Blender for writing the image. +try: + import OpenImageIO as oiio +except ImportError: + oiio = None + def export(filepath, face_data, colors, width, height, opacity): offscreen = gpu.types.GPUOffScreen(width, height) @@ -44,6 +50,12 @@ def get_normalize_uvs_matrix(): matrix.col[3][1] = -1 matrix[0][0] = 2 matrix[1][1] = 2 + + # OIIO writes arrays from the left-upper corner. + if oiio: + matrix.col[3][1] *= -1.0 + matrix[1][1] *= -1.0 + return matrix @@ -90,6 +102,14 @@ def draw_lines(face_data): def save_pixels(filepath, pixel_data, width, height): + if oiio: + spec = oiio.ImageSpec(width, height, 4, "uint8") + image = oiio.ImageOutput.create(filepath) + image.open(filepath, spec) + image.write_image(pixel_data) + image.close() + return + image = bpy.data.images.new("temp", width, height, alpha=True) image.filepath = filepath image.pixels = [v / 255 for v in pixel_data] -- 2.11.4.GIT