def check_image_dimensions(self, image_file): from PIL import Image with Image.open(image_file) as im: width, height = im.size if width > Tex0.MAX_IMG_SIZE or height > Tex0.MAX_IMG_SIZE: new_width, new_height = Tex0.get_scaled_size(width, height) b = Bug( 2, 2, f'Texture {image_file} too large ({width}x{height}).', f'Resize to {new_width}x{new_height}.') im = im.resize((new_width, new_height), self.RESAMPLE) im.save(image_file) b.resolve() elif not Tex0.is_power_of_two( width) or not Tex0.is_power_of_two(height): new_width = Tex0.nearest_power_of_two(width) new_height = Tex0.nearest_power_of_two(height) b = Bug( 2, 2, f'Texture {image_file} not a power of 2 ({width}x{height})', f'Resize to {new_width}x{new_height}') im = im.resize((new_width, new_height), self.RESAMPLE) im.save(image_file) b.resolve() return im
def batch_encode(self, files, brres, tex_format=None, num_mips=-1, check=False, overwrite=None): """Batch encode, faster than single encode when doing multiple files""" if overwrite is None: overwrite = self.OVERWRITE_IMAGES mips = '--n-mm=' + str( num_mips) if num_mips >= 0 else '--n-mm=auto' if not tex_format: tex_format = self.IMG_FORMAT t_files = [] for x in files: try: t_files.append(self.find_file(x)) except EncodeError: AutoFix.warn('Failed to find image {}'.format(x)) # tmp = 'abmatt-tmp' # create a new dir to work in tmp = self._move_to_temp_dir(t_files) t_files = [os.path.basename(x) for x in t_files] path_set = set() textures = brres.get_texture_map() for x in t_files: path, name = self.convert_png(os.path.join(tmp, x), remove_old=True) if overwrite or name not in textures: path_set.add(path) else: os.remove(path) if not len(path_set): self._move_out_of_temp_dir(tmp) return None if check: for x in path_set: self.check_image_dimensions(x) args = [self.converter, '-x', tex_format, mips, '-qo', 'encode'] file_names = [os.path.basename(x) for x in path_set] args.extend(file_names) result = subprocess.call(args, cwd=tmp, startupinfo=self.si) if result: self._move_out_of_temp_dir(tmp) raise EncodeError('Failed to encode images {}'.format(files)) tex0s = [] new_files = [x for x in os.listdir(tmp) if x not in file_names] for x in new_files: t = Tex0(x, brres, BinFile(os.path.join(tmp, x))) tex0s.append(t) brres.add_tex0(t) self._move_out_of_temp_dir(tmp) # cleanup return tex0s
def paste_material_tex0s(self, material, old_brres): pasted_count = 0 if old_brres is not self: old_map = old_brres.texture_map for layer in material.layers: tex0 = old_map.get(layer.name) if tex0 is not None and layer.name not in self.texture_map: t = Tex0(tex0.name, parent=self) t.paste(tex0) if self.add_tex0(t, False, False): pasted_count += 1 return pasted_count
def convert(self, tex0, tex_format): tmp = self.get_temp_dest() f = BinFile(tmp, 'w') tex0.pack(f) f.commitWrite() result = subprocess.call( [self.converter, 'encode', tmp, '-oq', '-x', tex_format], startupinfo=self.si) if result: os.remove(tmp) raise EncodeError('Failed to encode {}'.format(tex0.name)) t = Tex0(tex0.name, tex0.parent, BinFile(tmp)) os.remove(tmp) return t
def add_tex0(self, tex0, replace=True, mark_modified=True): if tex0.name in self.texture_map: if not replace: return False self.remove_tex0(tex0.name) AutoFix.get().info('Replaced tex0 {}'.format(tex0.name)) if tex0.parent is not None and tex0.parent is not self: t = Tex0(tex0.name, self) t.paste(tex0) tex0 = t self.textures.append(tex0) self.texture_map[tex0.name] = tex0 tex0.parent = self # this may be redundant if mark_modified: self.mark_modified() return True
def encode(self, img_file, brres, tex_format=None, num_mips=-1, check=False, overwrite=None): if overwrite is None: overwrite = self.OVERWRITE_IMAGES img_file, name = self.convert_png(self.find_file(img_file)) if not overwrite and brres is not None and name in brres.get_texture_map( ): AutoFix.warn(f'Tex0 {name} already exists!') return None if check: self.check_image_dimensions(img_file) # encode mips = '--n-mm=' + str( num_mips) if num_mips >= 0 else '--n-mm=auto' if not tex_format: tex_format = self.IMG_FORMAT dest = self.get_temp_dest() result = subprocess.call([ self.converter, 'encode', img_file, '-d', dest, '-x', tex_format, mips, '-qo' ], startupinfo=self.si) if result: raise EncodeError('Failed to encode {}'.format(img_file)) t = Tex0(name, brres, BinFile(dest)) t.name = name if brres is not None: brres.add_tex0(t) os.remove(dest) t.name = name return t
def load_config(app_dir=None, loudness=None, autofix_level=None): if app_dir is None: app_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'etc', 'abmatt') conf = Config.get_instance(os.path.join(app_dir, 'config.conf')) tmp_dir = os.path.join(app_dir, 'temp_files') converter = ImgConverter(tmp_dir) Tex0.converter = converter if not loudness: loudness = conf['loudness'] if loudness: try: AutoFix.set_loudness(loudness) except ValueError: AutoFix.warn('Invalid loudness level {}'.format(loudness)) AutoFix.set_fix_level(autofix_level, turn_off_fixes) if not len(conf): AutoFix.warn('No configuration detected (etc/abmatt/config.conf).') return Command.set_max_brres_files(conf) # Matching stuff MATCHING.set_case_sensitive(conf['case_sensitive']) MATCHING.set_partial_matching(conf['partial_matching']) MATCHING.set_regex_enable(conf['regex_matching']) # Autofixes try: SubFile.FORCE_VERSION = validBool(conf['force_version']) except ValueError: pass try: Brres.REMOVE_UNUSED_TEXTURES = validBool( conf['remove_unused_textures']) except ValueError: pass try: Layer.MINFILTER_AUTO = validBool(conf['minfilter_auto']) except ValueError: pass set_rename_unknown(conf['rename_unknown_refs']) set_remove_unknown(conf['remove_unknown_refs']) set_remove_unused(conf['remove_unused_refs']) try: Mdl0.DETECT_MODEL_NAME = validBool(conf['detect_model_name']) except ValueError: pass try: Shader.MAP_ID_AUTO = validBool(conf['map_id_auto']) except ValueError: pass try: Material.DEFAULT_COLOR = parse_color(conf['default_material_color']) except ValueError: pass try: Tex0.RESIZE_TO_POW_TWO = validBool(conf['resize_pow_two']) except ValueError: pass try: Tex0.set_max_image_size(validInt(conf['max_image_size'], 0, 10000)) except (TypeError, ValueError): pass try: Geometry.ENABLE_VERTEX_COLORS = validBool(conf['enable_vertex_colors']) except ValueError: pass Converter.ENCODE_PRESET = conf['encode_preset'] resample = conf['img_resample'] if resample is not None: ImgConverterI.set_resample(resample) if conf['material_library']: MaterialLibrary.LIBRARY_PATH = conf.config.get('material_library') else: MaterialLibrary.LIBRARY_PATH = os.path.join(app_dir, 'mat_lib.brres') return conf