Skip to content

Commit

Permalink
Merge pull request #883 from scurest/export-image-formats
Browse files Browse the repository at this point in the history
Export: implement image options change (#882)
  • Loading branch information
emackey authored Jan 22, 2020
2 parents 69176a3 + d705e9a commit 0027b2a
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 49 deletions.
12 changes: 6 additions & 6 deletions addons/io_scene_gltf2/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,18 +113,18 @@ def __init__(self):

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(
Expand Down
39 changes: 6 additions & 33 deletions addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -245,23 +238,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
22 changes: 12 additions & 10 deletions addons/io_scene_gltf2/blender/exp/gltf2_blender_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,15 +86,18 @@ def is_filled(self, chan: Channel) -> bool:
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
Expand All @@ -115,8 +118,7 @@ def encode(self, mime_type: Optional[str]) -> bytes:
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()
Expand Down

0 comments on commit 0027b2a

Please sign in to comment.