def main(argv=None): """ psd-tools command line utility. Usage: psd-tools export <input_file> <output_file> [options] psd-tools show <input_file> [options] psd-tools debug <input_file> [options] psd-tools -h | --help psd-tools --version Options: -v --verbose Be more verbose. Example: psd-tools show example.psd # Show the file content psd-tools export example.psd example.png # Export as PNG psd-tools export example.psd[0] example-0.png # Export layer as PNG """ args = docopt.docopt(main.__doc__, version=__version__, argv=argv) if args['--verbose']: logger.setLevel(logging.DEBUG) else: logger.setLevel(logging.INFO) if args['export']: input_parts = args['<input_file>'].split('[') input_file = input_parts[0] if len(input_parts) > 1: indices = [int(x.rstrip(']')) for x in input_parts[1:]] else: indices = [] layer = PSDImage.open(input_file) for index in indices: layer = layer[index] if isinstance(layer, PSDImage) and layer.has_preview(): image = layer.topil() else: image = layer.compose() image.save(args['<output_file>']) elif args['show']: psd = PSDImage.open(args['<input_file>']) pprint(psd) elif args['debug']: psd = PSDImage.open(args['<input_file>']) pprint(psd._record)
def procFile(dirName, fileName): inputFilePath = dirName + os.path.sep + fileName outputFileName = os.path.splitext(fileName)[0] + OUTPUT_EXT try: # check filesize if os.stat(inputFilePath).st_size < MIN_FILE_SIZE * 1024: logger.info( '{0} -> less than {1}KB'.format(inputFilePath, MIN_FILE_SIZE)) return # open psd = PSDImage.open(inputFilePath) # export composed layer image = resizeImage(psd.compose()) image.save(TARGETSET_DIR + outputFileName) logger.info('{0} -> target'.format(inputFilePath)) # export background layer rawFound = False for layer in psd: if layer.name == RAW_LAYER_LABEL: layerImage = layer.topil() width, height = layerImage.size image = resizeImage(layerImage) resizedWidth, resizedHeight = image.size logger.info('{0} -> resized: ({1} , {2}) to ({3}, {4})'.format( inputFilePath, width, height, resizedWidth, resizedHeight)) image.save(RAWSET_DIR + outputFileName) logger.info('{0} -> raw'.format(inputFilePath)) rawFound = True break if rawFound == False: logger.info('{0} -> raw not found'.format(inputFilePath)) except: logger.error('{0} -> error'.format(inputFilePath)) logger.error('error info -> {0}'.format(sys.exc_info()[0]))
def main(): # Testing basic functionality of the psd_utils args = parser.parse_args() psd_files = [] if os.path.isfile(args.input): psd_files.append(args.input) else: psd_file_list = os.listdir(args.input).sort() psd_files = [f for f in psd_file_list if f.endswith(".psd")] for psd_file in psd_files: psd = PSDImage.open(psd_file) if args.method == "instance": seg = label_by_instance(psd) elif args.method == "class": seg = label_by_class(psd) else: seg = None print("Not implemented.") if seg is not None: if os.path.isfile(args.output): seg.save(args.output) else: os.makedirs(args.output, exist_ok=True) head, tail = os.path.split(psd_file) filename = tail.replace(".psd", ".png") outpath = os.path.join(args.output, filename) seg.save(outpath)
def test_draw_pattern_fill(filename): psd = PSDImage.open(full_name(filename)) desc = psd[0].tagged_blocks.get_data(Tag.PATTERN_FILL_SETTING) draw_pattern_fill(psd.viewbox, psd, desc) desc[b'Scl '] = Double(50.) desc[b'Opct'] = Double(67.) draw_pattern_fill(psd.viewbox, psd, desc)
def main(): lines = read_in() img_directory = lines[0] psd = PSDImage.open(img_directory) layer_string = '{ \"components\": [' for component in psd: layer_string += '{ \"nome\": \"' + component.name + '\"' if hasattr(component, '_layers'): layer_string += ',' + ' \"colors\": [' for color in component._layers[:-1]: layer_string += '{ \"color\": \"' + color.name + '\" }' + ',' else: layer_string += '{ \"color\": \"' + \ component._layers[-1].name + '\" }' layer_string += ']' layer_string += '}' + ',' # else: # layer_string += '}' layer_string = layer_string[:-1] layer_string += ']}' print(layer_string)
def analysePsdFile(self, uiName_: str): _psdName = uiName_ _psd = PSDImage.open(self.psdFolderPath + _psdName + ".psd") if _psd.color_mode == ColorMode.RGB: print("psd color mode : RGB") print('_psd.channels = ' + str(_psd.channels)) _psdDict = self.psdToJson(_psd, self.targetFolderPath, _psdName) _unityDict = {} _unityDict["name"] = _psdName _unityDict["type"] = "Root" _unityDict["bbox"] = {} _unityDict["bbox"]["left"] = _psdDict["bbox"]["left"] _unityDict["bbox"]["top"] = _psdDict["bbox"]["top"] _unityDict["bbox"]["right"] = _psdDict["bbox"]["right"] _unityDict["bbox"]["bottom"] = _psdDict["bbox"]["bottom"] self.convertToUnityUIJson(_psdDict, _unityDict) fileUtils.writeFileWithStr( self.targetFolderPath + "jsons/" + _psdName + ".json", str( json.dumps(_unityDict, indent=4, sort_keys=False, ensure_ascii=False)))
def start(path): reset_log() global OUTPUT_DIR OUTPUT_DIR = "./OUTPUT" + "/" + os.path.basename(path) if os.path.isdir(OUTPUT_DIR): shutil.rmtree(OUTPUT_DIR) if not os.path.exists(OUTPUT_DIR): os.makedirs(OUTPUT_DIR) if not os.path.exists(f"{OUTPUT_DIR}/thumbnail"): os.makedirs(f"{OUTPUT_DIR}/thumbnail") psd = PSDImage.open(path) set_visible_all(psd, False) set_visible(psd, False) print('Start render image :') count_images(psd) count_images(psd) content = render_img(psd, path) content_output = {"Root": content} print('DONE') with open(f'{OUTPUT_DIR}/output.json', 'w') as f: f.write(json.dumps(content_output)) f.close()
def test_draw_pattern_fill(): psd = PSDImage.open(full_name('layers-minimal/pattern-fill.psd')) setting = psd[0].tagged_blocks.get_data(Tag.PATTERN_FILL_SETTING) draw_pattern_fill(psd.size, psd, setting) setting[b'Scl '] = Double(50.) setting[b'Opct'] = Double(67.) draw_pattern_fill(psd.size, psd, setting)
def TransChinese(img_path, SiteName): #将要处理的中文括号,冒号改为英文括号,横杠 for root, dirs, files in os.walk(img_path): for a in files: if (a.endswith('.psd') == True): b = a if '(' in a: a = a.replace('(', '(') if ')' in a: a = a.replace(')', ')') if ':' in a: a = a.replace(':', '-') if ':' in a: a = a.replace(':', '-') b, a = os.path.join(root, b), os.path.join(root, SiteName + a) try: os.renames(b, a) except FileExistsError: a = os.path.splitext(a)[0] + '(1)' + os.path.splitext(a)[1] os.rename(b, a) d = a.replace('psd', 'png') psd = PSDImage.open(a) image = psd.compose() image.save(d) # print('正在操作'+ b +'到'+ a) print('psd2png转换完成')
def main(filename, outputPath, contentPath, cookie): psd = PSDImage.open(filename) top = Frame(psd) imgFrames = [] RecursiveFrame(top, psd, imgFrames) for i in range(len(imgFrames)): name = FILE_FORMAT.format(i + 1) imgPath = outputPath.as_posix() + "/" + name imgFrames[i].layer.composite().save(imgPath) if contentPath: subPath = "/".join(contentPath.parts[-2:]) imgFrames[i].instance[ "Image"] = "rbxasset://" + subPath + "/" + name imgFrames[i].layer.composite().save(contentPath.as_posix() + "/" + name) if cookie: assetids = TarmacSync(outputPath, cookie) for i in range(len(imgFrames)): imgFrames[i].instance["Image"] = assetids[i] json = open(outputPath.as_posix() + "/output.json", "w") json.write(top.ToJSON()) json.close()
def pngCreator(files, img_extension): for file in files: # Iterate through the files if os.path.isfile(f'{os.getcwd()}\{file}'): # Get the base filename filename_full = os.path.basename(file) # Get the filename and extension filename, extension = os.path.splitext(filename_full) # Check the extension of file is psd if extension == '.psd': # Open the file psd = PSDImage.open(file) # Save the file according to extension provided psd.composite().save(f'{filename}.{img_extension}') print(f'File created: {filename}.{img_extension}') else: print(f'Extension NOT Valid for file: {file}')
def psd2pdf(psd_file: str) -> None: pdf_file = psd_file[:-4] + '.pdf' psd = PSDImage.open(psd_file) size = psd.width, psd.height layers = {} pages = [] for layer in psd: number = ''.join(filter(str.isdigit, layer.name)) img = layer.topil() if img: var = sum(ImageStat.Stat(img).var) if var: layers[number] = img # print(number) layer_numbers = list(layers.keys()) base_layers = [layer for layer in layer_numbers if len(layer) == 1] for page_num in base_layers: image = Image.new('RGBA', size, color='white') base_layer = layers[page_num] pages_num = [(p, layers[p]) for p in layers if len(p) == 2 and p[0] == page_num] pages_num.sort() to_compose = [] for p in pages_num: to_compose.append(p) base_image = Image.composite(base_layer, image, get_masks(base_layer)) if not to_compose: pages.append(base_image.convert('RGB')) for layer_num, layer in to_compose: the_image = Image.composite(layer, base_image, get_masks(layer)) pages.append(the_image.convert('RGB')) pages[0].save(pdf_file, save_all=True, quality=90, append_images=pages[1:])
def process(self, instance): # Check if python module `psd_tools` is installed try: global PSDImage from psd_tools import PSDImage except Exception: raise AssertionError( "BUG: Python module `psd-tools` is not installed!") self.allowed_group_names = [ name.lower() for name in self.allowed_group_names ] repres = instance.data.get("representations") if not repres: self.log.info("There are no representations on instance.") return for repre in tuple(repres): # Skip all files without .psd extension if repre["ext"] != ".psd": continue # TODO add check of list of "files" value psd_filename = repre["files"] psd_folder_path = repre["stagingDir"] psd_filepath = os.path.join(psd_folder_path, psd_filename) self.log.debug(f"psd_filepath: \"{psd_filepath}\"") psd_object = PSDImage.open(psd_filepath) self.create_new_instances(instance, psd_object) # Remove the instance from context instance.context.remove(instance)
def editor(request): # Extrapolating the PSD to a PIL.Image psd = PSDImage.open( '/mnt/Skryre/Users/Aki/Documents/Projects/Programs/Python/Alter/alter/static/psd/Customizable Synx Base.psd' ) PIL_img = psd.composite() # Saving the PIL.Image as a .png file in a buffer buffer = BytesIO() PIL_img.save(buffer, format='png') buffer.seek(0) # Converting the buffer to a usable base64 format for display on the webpage image_png = buffer.getvalue() img = base64.b64encode(image_png) img = img.decode('utf-8') buffer.close() # Getting an ordered list of layers from the PSD psd_structure = reversed(list(psd)) # Context dictionary for passing variable to HTML templates context = { 'img_file': img, 'psd': psd_structure, } return render(request, 'alter_app/editor.html', context)
def downloadZipTask(self, project_id, mode): project_list = Project.query.filter(Project.id.in_(project_id)).all() zip_path = os.path.join(app.config['DOWNLOAD_FOLDER'], 'temp') if not os.path.exists(zip_path): os.makedirs(zip_path) zip_file = os.path.join(zip_path, str(shortuuid.uuid()) + '.zip') zipf = zipfile.ZipFile(zip_file, 'w', zipfile.ZIP_DEFLATED) for i, project in enumerate(project_list): for phase in project.phases: if phase.upload_files: last_upload_phase = phase if last_upload_phase: foldername = project.title if project.status != 'finish': foldername = '{}-{}'.format(project.title, project.current_stage().name) for j, upload_file in enumerate(last_upload_phase.upload_files): index_number = '{:03}'.format(j) # compress if mode == 'compress' and upload_file.format in [ 'png', 'psd', 'bmp', 'tga', 'tiff', 'tif' ]: try: im_path = os.path.join(app.config['UPLOAD_FOLDER'], upload_file.url) if upload_file.format == 'psd': psd = PSDImage.open(im_path) im = psd.compose() else: im = Image.open(im_path) im = im.convert('RGB') filename = '{}.{}.{}'.format(project.title, index_number, 'jpg') im.save(os.path.join(zip_path, filename), "JPEG") zipf.write(os.path.join(zip_path, filename), os.path.join(foldername, filename)) except Exception as e: print(e) else: filename = '{}.{}.{}'.format(project.title, index_number, upload_file.format) zipf.write( os.path.join(app.config['UPLOAD_FOLDER'], upload_file.url), os.path.join(foldername, filename)) self.update_state(state='PROGRESS', meta={ 'current': i + 1, 'total': len(project_list) }) zipf.close() return {'current': 100, 'total': 100, 'result': buildUrl(zip_file, dir='')}
def psd_to_png(img): """Convert pictures from psd to png""" from psd_tools import PSDImage psd = PSDImage.open(img).compose() if psd is None: raise Exception("PSD has no visible pixel") psd.save(img.split('.')[0] + '.png')
def main(): args = get_args() # TODO: Use argparse input_dir = args.input_dir logger.info('Input directory: {}'.format(input_dir)) output_dir = args.output_dir logger.info('Input directory: {}'.format(output_dir)) # Initialize sqlite db_path = 'decomposed_psd.db' conn = sqlite3.connect(db_path) c = conn.cursor() if args.create_table: create_table(c) psd_paths = glob.glob(str(Path(input_dir) / Path('*.psd'))) psd_paths_len = len(psd_paths) logger.info('All files: {}'.format(psd_paths_len)) for psd_idx, psd_path in enumerate(psd_paths): logger.info(' - [{:6}/{:6}] {}'.format(psd_idx, psd_paths_len, psd_path)) psd_stem = Path(psd_path).stem c.execute( "INSERT INTO creatives (psd_stem, psd_path) VALUES ('{}', '{}')". format(psd_stem, psd_path)) # XXX: Test run try: psd = PSDImage.open(psd_path) # Create a directory to save layers image layers_dir = Path(output_dir) / Path(psd_stem) layers_dir.mkdir(parents=True, exist_ok=True) layers_len = len(psd) for layer_idx, layer in enumerate(psd): logger.info(' - [{:3}/{:3}] {}'.format( layer_idx, layers_len, layer.name)) layer_path = save_layer_img(layers_dir, layer, layer_idx) left, top, right, bottom = layer.bbox c.execute(( "INSERT INTO layers (psd_stem, psd_path, layer_path, layer_order, left, top, right, bottom) " "values ('{}', '{}', '{}', {}, {}, {}, {}, {})").format( psd_stem, psd_path, layer_path, layer_idx, left, top, right, bottom)) conn.commit() except Exception as e: logger.error('\n***** ERROR: {} *****\n'.format(psd_path)) logger.error(e) conn.close() return
def test_draw_gradient_fill(): psd = PSDImage.open(full_name('layers-minimal/gradient-fill.psd')) desc = psd[0].tagged_blocks.get_data(Tag.GRADIENT_FILL_SETTING) draw_gradient_fill(psd.viewbox, desc) for angle in (-90., 0., 90., 180.): desc.get(Key.Angle.value).value = angle draw_gradient_fill(psd.viewbox, desc) desc.get(b'Type').enum = Enum.Radial.value draw_gradient_fill(psd.viewbox, desc)
def main(): args = sys.argv[1:] input = args[0] output = args[1] psd = PSDImage.open(input) with open(output, 'w') as w: w.write(build_tree(psd))
def post(self, request, *args, **kwargs): if "file" not in request.FILES: return redirect("illust:index") mime_type = magic.from_buffer(request.FILES["file"].read(1024), mime=True) print(mime_type) #mime属性の保存(後のサムネイル生成処理に繋げる) copied = request.POST.copy() copied["mime"] = mime_type form = DesignForm(copied, request.FILES) if form.is_valid(): print("バリデーションOK ") if mime_type in ALLOWED_MIME: result = form.save() else: print("このファイルは許可されていません") return redirect("illust:index") else: print("バリデーションNG") return redirect("illust:index") #======ここから先、サムネイル作成処理========== #処理結果のIDを元に、サムネイルの保存を行い、thumbnailに保存したパスを指定する design = Design.objects.filter(id=result.id).first() #upload_to、settings内にあるMEDIA_ROOTを読み取り、そこに画像ファイルを保存。 from django.conf import settings path = Design.thumbnail.field.upload_to thumbnail_path = path + str(design.id) + ".png" full_path = settings.MEDIA_ROOT + "/" + thumbnail_path #フォトショップの場合 if design.mime == "image/vnd.adobe.photoshop": from psd_tools import PSDImage image = PSDImage.open(settings.MEDIA_ROOT + "/" + str(design.file)) image.composite().save(full_path) #イラストレーターの場合 elif design.mime == "application/postscript": from PIL import Image image = Image.open(settings.MEDIA_ROOT + "/" + str(design.file)) image.save(full_path) else: return redirect("illust:index") design.thumbnail = thumbnail_path design.save() return redirect("illust:index")
def load_textures(self): try: psd_img = PSDImage.open("./resource/test.psd") img = psd_img.compose() img = np.array(img) self.texture = self.gl.texture((img.shape[1], img.shape[0]), img.shape[2], img) self._need_reload_texture = False except Exception as e: print(e)
def write_file_png(name, path, branch, current_path): if not os.path.isfile(f'{current_path}/{name}.png'): layer_img = PSDImage.open(path) set_visible_all(layer_img, False) set_visible(layer_img, False) visible_branch(layer_img, branch) image = layer_img.composite(ignore_preview=True) image.save(f'{current_path}/{name}.png') add_log('image', 1) print(f'save successfully file: {name}') get_log()
def test_gradient_styles(filename): psd = PSDImage.open(full_name(filename)) for artboard in psd: for layer in artboard: desc = layer.tagged_blocks.get_data(Tag.GRADIENT_FILL_SETTING) form = desc.get(Key.Gradient).get(Type.GradientForm).enum reference = composite(layer)[0] result = composite(layer, force=True)[0] if form == Enum.CustomStops: assert _mse(reference, result) <= 0.08 elif form == Enum.ColorNoise: # Noise gradient is not of good quality. assert _mse(reference, result) <= 0.2
def compile(self): self.need_compile = False try: VS, FS = open("./gl/vs.glsl").read(), open("./gl/fs.glsl").read() self.program = self.gl.program(vertex_shader=VS, fragment_shader=FS) self.vao = self.gl.vertex_array(self.program, [(self.vb, "2f", "in_pos")], self.ib) psd_img = PSDImage.open("./res/tex.psd") self.texture = self.gl.texture(psd_img.size, 3, psd_img.compose().tobytes()) self.texture.build_mipmaps() self.texture.use(0) except Exception as e: print(e)
def parse_psd(psd_image_file): """ Parse PSD file and returns list of layer names and list of layer pixel intensities :param psd_image_file: path to PSD file :return: list(str), list(ndarray) list of layer names and list of images (layers) """ psd = PSDImage.open(psd_image_file) layer_names = [] arrays = [] for layer in psd: layer_names.append(layer.name) arrays.append(np.array(layer.topil())) return layer_names, arrays
def test_gradient_styles(filename): psd = PSDImage.open(full_name(filename)) for artboard in psd: for layer in artboard: setting = layer.tagged_blocks.get_data(Tag.GRADIENT_FILL_SETTING) form = setting.get(Key.Gradient).get(Type.GradientForm).enum reference = layer.compose().convert('RGB') rendered = layer.compose(force=True).convert('RGB') if form == Enum.CustomStops: assert _calculate_hash_error(reference, rendered) <= 0.1 elif form == Enum.ColorNoise: # Noise gradient is not of good quality. with pytest.raises(AssertionError): assert _calculate_hash_error(reference, rendered) <= 0.1
def test_quality(rasterizer, tmpdir, psd_file): svg_file = os.path.join(tmpdir.dirname, "output.svg") psd = PSDImage.open(psd_file) if not psd.has_preview(): pytest.skip('psd file does not have a preview, skipping tests') preview = psd.composite() rendered = rasterizer.rasterize_from_string(psd2svg.psd2svg(psd)) assert preview.width == rendered.width assert preview.height == rendered.height preview_hash = imagehash.average_hash(preview) rendered_hash = imagehash.average_hash(rendered) error_count = np.sum(np.bitwise_xor(preview_hash.hash, rendered_hash.hash)) error_rate = error_count / float(preview_hash.hash.size) assert error_rate <= 0.125
def reload_textures(self): self._need_reload_textures = False try: self.textures = [] psd = PSDImage.open("./resources/test_resource.psd") for layer in psd: img = np.array(layer.compose(bbox=psd.bbox)) texture = self.gl.texture((img.shape[1], img.shape[0]), img.shape[2], img) self.textures.append(texture) print("textures reloaded") except Exception as e: print(e)
def get_psd_or_raise(file): """Return if a path is a psd file. :param file: path to file :type file: str """ file_path = Path(file) if not file_path.is_file(): raise RuntimeError('The path is not a file.') if not file_path.exists(): raise RuntimeError('File doesn\'t exist.') try: return PSDImage.open(file) except: raise RuntimeError('The path must be a PSD file.')
def readPsd(psdPath="F:\\MyWork\\Config\\psd\\", name="我的职级1.psd", isall=False): psdFile = r'' + psdPath + name if not os.path.exists(psdFile): Log.logError("psd路径不存在:", psdPath + name) return Log.log("开始导出PSD") psdName = name.split(".")[0] savePath = psdPath + psdName jsonPath = savePath + "\\json" imgPath = savePath + "\\img" createDir(jsonPath) createDir(imgPath) Log.log("导出图片路径:", imgPath) psd = PSDImage.open(psdFile) psd.compose().save(imgPath + "\\exportpsd.png") # psd.composite().save(imgPath + "\\exportpsd.png") PSDInfo.width = psd.size[0] PSDInfo.height = psd.size[1] psddata = psd.descendants() psdNode = Node(None) nodeList = [psdNode] imgList = ["exportpsd"] dataList = list(psddata) for layer in dataList: if not isall and not layer.visible: continue if layer.height == 0 or layer.height == 0: continue layer.name = layer.name.replace(' ', '') node = Node(layer) if node.type == "cc.Sprite": reg = re.compile(r'[/:\'\"\\/|*&^%$@!()?<>,.‘“?,。:]') node.src = reg.sub("", node.src) name = imgPath + ('\\%s.png' % (node.src)) try: layer.compose().save(name) imgList.append(node.src) except BaseException as e: Log.logError("图层", layer.name, "导出失败") # layer.composite().save(name) if node.type != "cc.Node": nodeList.append(node) saveNode(nodeList, imgList, jsonPath)