close

image

 

前言

當我們需要把 PSD 檔內圖層,一張張的輸出成很多圖片時,就可以來看這篇教學囉。

像以前製作遊戲的時候,從美術那邊拿到 PSD 檔,要把所有圖層分開輸出成圖片,還需要圖層座標、大小等參數,才能夠拼回原本的樣子,且又是不同物件,後來都用程式處理這件事。

直接批次把圖層生成圖片,當初用的是 XML 格式,圖層的參數可以放到裡面,也有用圖層名稱區別類型,例如:圖層名「Button:AAA」 = <Button name="AAA"></Button> 之類的。

大家也可以做類似的應用,除了遊戲,網頁應該也適合這樣做😎。

不過抱歉,當時的 PSDParser 已經不見了,最近要使用的功能就簡單許多,想把 PSD 拆開放到簡報軟體裡。

這裡提供 PSD 圖層分開輸出的程式碼☺️,而且不需要開啟 PhotoShop 呢。

安裝

程式碼使用 Python,請先有 Python,這裡用的是 3.9.0,可以修改程式碼到符合自己的 Python 版本,也可以看我們以前的教學 pyenv-virtualenv 教學(介紹篇)pyenv-virtualenv 教學(安裝篇),再創一個 Python 3.9.0 環境喔~

然後安裝套件:

pip install Pillow psd-tools
 

程式碼

根據輸出圖片名稱

以下兩個擇一即可。

圖片名同圖層名

# 首陽問路:https://firstsun.pixnet.net
import os
from psd_tools import PSDImage

def B2Q(s):
    """ 把字串半形轉全形 """
    rstring = ""
    for uchar in s:
        u_code = ord(uchar)
        if uchar in '[\/:*?"<>|]':  # 非法字符
            if u_code == 32:  # 全形空格直接轉換
                u_code = 12288
            elif 33 <= u_code <= 126:  # 全形字元(除空格)根據關係轉化
                u_code += 65248
        rstring += chr(u_code)
    return rstring

print("請輸入 .psd 檔的路徑:")

INPUT_PATH = os.path.abspath(input().strip())
OUTPUT_DIR = f"output_{os.path.basename(INPUT_PATH)}"

# 建立輸出資料夾
if not os.path.isdir(OUTPUT_DIR):
    os.mkdir(OUTPUT_DIR)

psd = PSDImage.open(INPUT_PATH)

for layer in list(psd.descendants()):
    try:
        # 防止檔名有非法字元
        name = B2Q(str(layer.name))
        layer.composite().save(f"{OUTPUT_DIR}/{name}.png")
    except Exception as error:
        print(error)

圖層名為第幾個圖層

# 首陽問路:https://firstsun.pixnet.net
import os
from psd_tools import PSDImage

print("請輸入 .psd 檔的路徑:")

INPUT_PATH = os.path.abspath(input().strip())
OUTPUT_DIR = f"output_{os.path.basename(INPUT_PATH)}"

# 建立輸出資料夾
if not os.path.isdir(OUTPUT_DIR):
    os.mkdir(OUTPUT_DIR)

psd = PSDImage.open(INPUT_PATH)

for index, layer in enumerate(list(psd.descendants())):
    try:
        layer.composite().save(f"{OUTPUT_DIR}/{index}.png")
    except Exception as error:
        print(error)

是從最下面的圖層當第 0 個,想要相反的話,可以這樣改:

enumerate(list(psd.descendants())) -> enumerate(reversed(list(psd.descendants())))

到第幾層圖層

上面 psd.descendants() 的地方,是如果有 Group,也會進去處理裡面的圖層,如果像我一樣只想處理第一層的圖層,不處理子圖層,改成這樣就可以了 psd.descendants() -> psd

注意事項

之前遇過圖片 mask 超出運算範圍,導致生成錯誤,是 library 本身限制的問題,應該不常發生,但也有其他錯誤的可能。

因此請檢查一下生成的檔案,如有出錯,請您用軟體自行匯出該圖層,可以用 Photopea

如果是用圖層名當檔名,要記得讓圖層名不一樣,以免生成的時候互相覆蓋。

操作

拿到程式碼後存檔成 .py 檔,我把它稱作 all_psd_layers_to_png.py,執行它!

而 clouds.psd 改成要用的 PSD 檔即可,比較大的檔案要稍微等一下。

如果您喜歡這樣的終端機,可參考安裝方式:全民寫程式|Oh My Zsh|安裝、主題、插件|終端機優化|終端機美化

這是 clouds.psd 的圖層內容:

image

執行完後,會獲得 output_clouds.psd 資料夾,裡面的內容給大家看看,這裡用的是 Group 不包含子圖層的程式碼,有兩張圖片先刪掉沒有在裡面:

image

參考資料

更多 Python 文章

謝謝您的觀看了☺️~

arrow
arrow

    首陽 發表在 痞客邦 留言(11) 人氣()