1# Copyright 2018-2019 The glTF-Blender-IO authors. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15import bpy 16import os 17import tempfile 18from os.path import dirname, join, isfile, basename, normpath 19import urllib.parse 20import re 21 22from ...io.imp.gltf2_io_binary import BinaryData 23 24 25# Note that Image is not a glTF2.0 object 26class BlenderImage(): 27 """Manage Image.""" 28 def __new__(cls, *args, **kwargs): 29 raise RuntimeError("%s should not be instantiated" % cls) 30 31 @staticmethod 32 def create(gltf, img_idx): 33 """Image creation.""" 34 img = gltf.data.images[img_idx] 35 img_name = img.name 36 37 if img.blender_image_name is not None: 38 # Image is already used somewhere 39 return 40 41 tmp_dir = None 42 try: 43 if img.uri is not None and not img.uri.startswith('data:'): 44 # Image stored in a file 45 img_from_file = True 46 path = join(dirname(gltf.filename), _uri_to_path(img.uri)) 47 img_name = img_name or basename(path) 48 if not isfile(path): 49 gltf.log.error("Missing file (index " + str(img_idx) + "): " + img.uri) 50 return 51 else: 52 # Image stored as data => create a tempfile, pack, and delete file 53 img_from_file = False 54 img_data = BinaryData.get_image_data(gltf, img_idx) 55 if img_data is None: 56 return 57 img_name = img_name or 'Image_%d' % img_idx 58 tmp_dir = tempfile.TemporaryDirectory(prefix='gltfimg-') 59 filename = _filenamify(img_name) or 'Image_%d' % img_idx 60 filename += _img_extension(img) 61 path = join(tmp_dir.name, filename) 62 with open(path, 'wb') as f: 63 f.write(img_data) 64 65 num_images = len(bpy.data.images) 66 blender_image = bpy.data.images.load(os.path.abspath(path), check_existing=img_from_file) 67 if len(bpy.data.images) != num_images: # If created a new image 68 blender_image.name = img_name 69 if gltf.import_settings['import_pack_images'] or not img_from_file: 70 blender_image.pack() 71 72 img.blender_image_name = blender_image.name 73 74 finally: 75 if tmp_dir is not None: 76 tmp_dir.cleanup() 77 78def _uri_to_path(uri): 79 uri = urllib.parse.unquote(uri) 80 return normpath(uri) 81 82def _img_extension(img): 83 if img.mime_type == 'image/png': 84 return '.png' 85 if img.mime_type == 'image/jpeg': 86 return '.jpg' 87 return '' 88 89def _filenamify(s): 90 s = s.strip().replace(' ', '_') 91 return re.sub(r'(?u)[^-\w.]', '', s) 92