[Bf-extensions-cvs] [bcc79238] master: Add option to choose jpeg quality at export

Julien Duroure noreply at git.blender.org
Wed Jan 18 17:58:14 CET 2023


Commit: bcc792388887d15bbed6f87842cf8fe6079f8323
Author: Julien Duroure
Date:   Wed Jan 18 17:45:31 2023 +0100
Branches: master
https://developer.blender.org/rBAbcc792388887d15bbed6f87842cf8fe6079f8323

Add option to choose jpeg quality at export

===================================================================

M	io_scene_gltf2/__init__.py
M	io_scene_gltf2/blender/exp/gltf2_blender_gather_image.py
M	io_scene_gltf2/blender/exp/gltf2_blender_image.py

===================================================================

diff --git a/io_scene_gltf2/__init__.py b/io_scene_gltf2/__init__.py
index 8235ae8a..dbc8e942 100755
--- a/io_scene_gltf2/__init__.py
+++ b/io_scene_gltf2/__init__.py
@@ -4,7 +4,7 @@
 bl_info = {
     'name': 'glTF 2.0 format',
     'author': 'Julien Duroure, Scurest, Norbert Nopper, Urs Hanselmann, Moritz Becher, Benjamin Schmithüsen, Jim Eckerlein, and many external contributors',
-    "version": (3, 5, 13),
+    "version": (3, 5, 14),
     'blender': (3, 4, 0),
     'location': 'File > Import-Export',
     'description': 'Import-Export as glTF 2.0',
@@ -189,6 +189,14 @@ class ExportGLTF2_Base(ConvertGLTF2_Base):
         default='',
     )
 
+    export_jpeg_quality: IntProperty(
+        name='JPEG quality',
+        description='Quality of JPEG export',
+        default=75,
+        min=0,
+        max=100
+    )
+
     export_keep_originals: BoolProperty(
         name='Keep original',
         description=('Keep original textures files if possible. '
@@ -589,6 +597,7 @@ class ExportGLTF2_Base(ConvertGLTF2_Base):
 
         export_settings['gltf_format'] = self.export_format
         export_settings['gltf_image_format'] = self.export_image_format
+        export_settings['gltf_jpeg_quality'] = self.export_jpeg_quality
         export_settings['gltf_copyright'] = self.export_copyright
         export_settings['gltf_texcoords'] = self.export_texcoords
         export_settings['gltf_normals'] = self.export_normals
@@ -877,6 +886,8 @@ class GLTF_PT_export_geometry_material(bpy.types.Panel):
         col = layout.column()
         col.active = operator.export_materials == "EXPORT"
         col.prop(operator, 'export_image_format')
+        if operator.export_image_format in ["AUTO", "JPEG"]:
+            col.prop(operator, 'export_jpeg_quality')
 
 class GLTF_PT_export_geometry_original_pbr(bpy.types.Panel):
     bl_space_type = 'FILE_BROWSER'
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_image.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_image.py
index 1e815e9b..98878f92 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_image.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_image.py
@@ -103,7 +103,7 @@ def __filter_image(sockets, export_settings):
 @cached
 def __gather_buffer_view(image_data, mime_type, name, export_settings):
     if export_settings[gltf2_blender_export_keys.FORMAT] != 'GLTF_SEPARATE':
-        data, factor = image_data.encode(mime_type)
+        data, factor = image_data.encode(mime_type, export_settings)
         return gltf2_io_binary_data.BinaryData(data=data), factor
     return None, None
 
@@ -171,7 +171,7 @@ def __gather_name(export_image, export_settings):
 def __gather_uri(image_data, mime_type, name, export_settings):
     if export_settings[gltf2_blender_export_keys.FORMAT] == 'GLTF_SEPARATE':
         # as usual we just store the data in place instead of already resolving the references
-        data, factor = image_data.encode(mime_type=mime_type)
+        data, factor = image_data.encode(mime_type, export_settings)
         return gltf2_io_image_data.ImageData(
             data=data,
             mime_type=mime_type,
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_image.py b/io_scene_gltf2/blender/exp/gltf2_blender_image.py
index 6730f479..7ada4bab 100644
--- a/io_scene_gltf2/blender/exp/gltf2_blender_image.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_image.py
@@ -125,7 +125,7 @@ class ExportImage:
             len(set(fill.image.name for fill in self.fills.values())) == 1
         )
 
-    def encode(self, mime_type: Optional[str]) -> Tuple[bytes, bool]:
+    def encode(self, mime_type: Optional[str], export_settings) -> Tuple[bytes, bool]:
         self.file_format = {
             "image/jpeg": "JPEG",
             "image/png": "PNG"
@@ -133,19 +133,19 @@ class ExportImage:
 
         # Happy path = we can just use an existing Blender image
         if self.__on_happy_path():
-            return self.__encode_happy(), None
+            return self.__encode_happy(export_settings), None
 
         # Unhappy path = we need to create the image self.fills describes or self.stores describes
         if self.numpy_calc is None:
-            return self.__encode_unhappy(), None
+            return self.__encode_unhappy(export_settings), None
         else:
             pixels, width, height, factor = self.numpy_calc(self.stored)
-            return self.__encode_from_numpy_array(pixels, (width, height)), factor
+            return self.__encode_from_numpy_array(pixels, (width, height), export_settings), factor
 
-    def __encode_happy(self) -> bytes:
-        return self.__encode_from_image(self.blender_image())
+    def __encode_happy(self, export_settings) -> bytes:
+        return self.__encode_from_image(self.blender_image(), export_settings)
 
-    def __encode_unhappy(self) -> bytes:
+    def __encode_unhappy(self, export_settings) -> bytes:
         # We need to assemble the image out of channels.
         # Do it with numpy and image.pixels.
 
@@ -159,7 +159,7 @@ class ExportImage:
         if not images:
             # No ImageFills; use a 1x1 white pixel
             pixels = np.array([1.0, 1.0, 1.0, 1.0], np.float32)
-            return self.__encode_from_numpy_array(pixels, (1, 1))
+            return self.__encode_from_numpy_array(pixels, (1, 1), export_settings)
 
         width = max(image.size[0] for image in images)
         height = max(image.size[1] for image in images)
@@ -185,9 +185,9 @@ class ExportImage:
 
         tmp_buf = None  # GC this
 
-        return self.__encode_from_numpy_array(out_buf, (width, height))
+        return self.__encode_from_numpy_array(out_buf, (width, height), export_settings)
 
-    def __encode_from_numpy_array(self, pixels: np.ndarray, dim: Tuple[int, int]) -> bytes:
+    def __encode_from_numpy_array(self, pixels: np.ndarray, dim: Tuple[int, int], export_settings) -> bytes:
         with TmpImageGuard() as guard:
             guard.image = bpy.data.images.new(
                 "##gltf-export:tmp-image##",
@@ -199,9 +199,9 @@ class ExportImage:
 
             tmp_image.pixels.foreach_set(pixels)
 
-            return _encode_temp_image(tmp_image, self.file_format)
+            return _encode_temp_image(tmp_image, self.file_format, export_settings)
 
-    def __encode_from_image(self, image: bpy.types.Image) -> bytes:
+    def __encode_from_image(self, image: bpy.types.Image, export_settings) -> bytes:
         # See if there is an existing file we can use.
         data = None
         if image.source == 'FILE' and not image.is_dirty:
@@ -225,17 +225,21 @@ class ExportImage:
         with TmpImageGuard() as guard:
             make_temp_image_copy(guard, src_image=image)
             tmp_image = guard.image
-            return _encode_temp_image(tmp_image, self.file_format)
+            return _encode_temp_image(tmp_image, self.file_format, export_settings)
 
 
-def _encode_temp_image(tmp_image: bpy.types.Image, file_format: str) -> bytes:
+def _encode_temp_image(tmp_image: bpy.types.Image, file_format: str, export_settings) -> bytes:
     with tempfile.TemporaryDirectory() as tmpdirname:
         tmpfilename = tmpdirname + '/img'
         tmp_image.filepath_raw = tmpfilename
 
         tmp_image.file_format = file_format
 
-        tmp_image.save()
+        # if image is jpeg, use quality export settings
+        if file_format == "JPEG":
+            tmp_image.save(quality=export_settings['gltf_jpeg_quality'])
+        else:
+            tmp_image.save()
 
         with open(tmpfilename, "rb") as f:
             return f.read()



More information about the Bf-extensions-cvs mailing list