Skip to content
Snippets Groups Projects
Commit 872e3e6a authored by Julien Duroure's avatar Julien Duroure
Browse files

glTF exporter: image options change

parent 3049742f
No related branches found
No related tags found
No related merge requests found
......@@ -15,7 +15,7 @@
bl_info = {
'name': 'glTF 2.0 format',
'author': 'Julien Duroure, Norbert Nopper, Urs Hanselmann, Moritz Becher, Benjamin Schmithüsen, Jim Eckerlein, and many external contributors',
"version": (1, 2, 2),
"version": (1, 2, 3),
'blender': (2, 81, 6),
'location': 'File > Import-Export',
'description': 'Import-Export as glTF 2.0',
......@@ -113,18 +113,18 @@ class ExportGLTF2_Base:
export_image_format: EnumProperty(
name='Images',
items=(('NAME', 'Automatic',
'Determine the image format from the blender image name'),
items=(('AUTO', 'Automatic',
'Save PNGs as PNGs and JPEGs as JPEGs.\n'
'If neither one, use PNG'),
('JPEG', 'JPEG Format (.jpg)',
'Encode and save textures as .jpg files. Be aware of a possible loss in quality'),
('PNG', 'PNG Format (.png)',
'Encode and save textures as .png files')
'Save images as JPEGs. (Images that need alpha are saved as PNGs though.)\n'
'Be aware of a possible loss in quality'),
),
description=(
'Output format for images. PNG is lossless and generally preferred, but JPEG might be preferable for web '
'applications due to the smaller file size'
),
default='NAME'
default='AUTO'
)
export_texture_dir: StringProperty(
......
......@@ -42,7 +42,7 @@ def gather_image(
# The export image has no data
return None
mime_type = __gather_mime_type(blender_shader_sockets_or_texture_slots, export_settings)
mime_type = __gather_mime_type(blender_shader_sockets_or_texture_slots, image_data, export_settings)
name = __gather_name(blender_shader_sockets_or_texture_slots, export_settings)
uri = __gather_uri(image_data, mime_type, name, export_settings)
......@@ -95,27 +95,20 @@ def __gather_extras(sockets_or_slots, export_settings):
return None
def __gather_mime_type(sockets_or_slots, export_settings):
def __gather_mime_type(sockets_or_slots, export_image, export_settings):
# force png if Alpha contained so we can export alpha
for socket in sockets_or_slots:
if socket.name == "Alpha":
return "image/png"
if export_settings["gltf_image_format"] == "NAME":
extension = __get_extension_from_slot(sockets_or_slots, export_settings)
extension = extension.lower()
if extension in [".jpeg", ".jpg", ".png"]:
return {
".jpeg": "image/jpeg",
".jpg": "image/jpeg",
".png": "image/png",
}[extension]
if export_settings["gltf_image_format"] == "AUTO":
image = export_image.blender_image()
if image is not None and image.file_format == 'JPEG':
return "image/jpeg"
return "image/png"
elif export_settings["gltf_image_format"] == "JPEG":
return "image/jpeg"
else:
return "image/png"
def __gather_name(sockets_or_slots, export_settings):
......@@ -246,23 +239,3 @@ def __get_texname_from_slot(sockets_or_slots, export_settings):
elif isinstance(sockets_or_slots[0], bpy.types.MaterialTextureSlot):
return sockets_or_slots[0].texture.image.name
@cached
def __get_extension_from_slot(sockets_or_slots, export_settings):
if __is_socket(sockets_or_slots):
for socket in sockets_or_slots:
node = __get_tex_from_socket(socket, export_settings)
if node is not None:
image_name = node.shader_node.image.name
filepath = bpy.data.images[image_name].filepath
name, extension = os.path.splitext(filepath)
if extension:
return extension
return '.png'
elif isinstance(sockets_or_slots[0], bpy.types.MaterialTextureSlot):
image_name = sockets_or_slots[0].texture.image.name
filepath = bpy.data.images[image_name].filepath
name, extension = os.path.splitext(filepath)
return extension
......@@ -86,15 +86,18 @@ class ExportImage:
def empty(self) -> bool:
return not self.fills
def blender_image(self) -> Optional[bpy.types.Image]:
"""If there's an existing Blender image we can use,
returns it. Otherwise (if channels need packing),
returns None.
"""
if self.__on_happy_path():
for fill in self.fills.values():
return fill.image
return None
def __on_happy_path(self) -> bool:
# Whether there is an existing Blender image we can use for this
# ExportImage because all the channels come from the matching
# channel of that image, eg.
#
# self.fills = {
# Channel.R: FillImage(image=im, src_chan=Channel.R),
# Channel.G: FillImage(image=im, src_chan=Channel.G),
# }
# All src_chans match their dst_chan and come from the same image
return (
all(isinstance(fill, FillImage) for fill in self.fills.values()) and
all(dst_chan == fill.src_chan for dst_chan, fill in self.fills.items()) and
......@@ -115,8 +118,7 @@ class ExportImage:
return self.__encode_unhappy()
def __encode_happy(self) -> bytes:
for fill in self.fills.values():
return self.__encode_from_image(fill.image)
return self.__encode_from_image(self.blender_image())
def __encode_unhappy(self) -> bytes:
result = self.__encode_unhappy_with_compositor()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment