[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