最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

python生成psd文件實例

 更新時間:2026年01月17日 09:47:36   作者:AI算法網(wǎng)奇  
文章介紹了如何使用Python生成包含多個圖層的PSD文件,通過腳本`gen_psd.py`實現(xiàn)關(guān)鍵點分割人臉并生成多圖層效果,作者分享了自己的經(jīng)驗,希望能為讀者提供參考并支持腳本之家

python生成psd文件

多個圖層,方便ps打開編輯

gen_psd.py

from PIL import Image

from psd_tools import PSDImage
from psd_tools.api.layers import PixelLayer

def image_to_psd(image_obj: Image, save_path):
    # 確保圖像模式為 RGBA
    if image_obj.mode != "RGBA":
        image_obj = image_obj.convert("RGBA")

    # 將PIL圖像轉(zhuǎn)換為PSD格式
    psd = PSDImage.frompil(image_obj)

    # 創(chuàng)建一個新圖層
    pixel_layer = PixelLayer.frompil(image_obj, psd)
    pixel_layer.visible = True  # 設(shè)置圖層為可見

    psd.append(pixel_layer)  # 將圖層添加到PSD中
    psd.save(save_path)  # 保存為PSD文件

if __name__ == "__main__":
    image_obj = Image.open(r"D:\project_2025\live2d\talking-head-anime-4-demo-main\demo\character_model\character.png")
    save_path = 'demo.psd'
    image_to_psd(image_obj, save_path)

創(chuàng)建多個圖層

from PIL import Image
from psd_tools import PSDImage
from psd_tools.api.layers import PixelLayer


def image_to_psd(image_paths, save_path):
    # 讀取第一張圖,作為 PSD 畫布
    base_img = Image.open(image_paths[0]).convert("RGBA")
    psd = PSDImage.frompil(base_img)

    # 第一個圖層
    layer0 = PixelLayer.frompil(base_img, psd)
    layer0.name = "Base"
    layer0.visible = True
    psd.append(layer0)

    # 后續(xù)圖片作為新圖層
    for i, img_path in enumerate(image_paths[1:], start=1):
        img = Image.open(img_path).convert("RGBA")
        layer = PixelLayer.frompil(img, psd)
        layer.name = f"Layer_{i}"
        layer.visible = True
        psd.append(layer)

    # 保存 PSD
    psd.save(save_path)


if __name__ == "__main__":
    image_paths = [
        r"D:\project_2025\live2d\talking-head-anime-4-demo-main\demo\data\images\lambda_02_face_mask.png",
        r"D:\project_2025\live2d\talking-head-anime-4-demo-main\demo\data\images\lambda_02.png",
    ]

    image_to_psd(image_paths, "demo.psd")

關(guān)鍵點分割人臉,生成多圖層

import os
from PIL import Image
from psd_tools import PSDImage

import cv2
import numpy as np
import os

from psd_tools.api.layers import PixelLayer

from Skps import FaceAna

def generate_eye_ellipse_mask(image_shape, landmarks, indices, scale_x=2, scale_y=1.25):
    """
    使用最小外接橢圓生成眼睛 mask
    """
    mask = np.zeros(image_shape[:2], dtype=np.uint8)
    pts = landmarks[indices].astype(np.int32)

    if pts.shape[0] < 5:
        return mask

    ellipse = cv2.fitEllipse(pts)
    (cx, cy), (w, h), angle = ellipse

    w *= scale_x
    h *= scale_y

    cv2.ellipse(
        mask,
        ((int(cx), int(cy)), (int(w), int(h)), angle),
        255,
        -1
    )
    return mask

def generate_part_mask(image_shape, landmarks, indices):
    """
    根據(jù)關(guān)鍵點索引生成對應(yīng)部位的二進(jìn)制遮罩。
    Args:
        image_shape: 原圖尺寸 (H, W)
        landmarks: 人臉關(guān)鍵點坐標(biāo)數(shù)組
        indices: 特定部位的關(guān)鍵點索引列表
    Returns:
        mask: 二值化遮罩 (0/255)
    """
    mask = np.zeros(image_shape[:2], dtype=np.uint8)
    pts = landmarks[indices].astype(np.int32)
    # 使用凸包或最小矩形來定義區(qū)域
    if len(indices) > 2:  # 對于眼睛、嘴巴等輪廓點
        hull = cv2.convexHull(pts)
        cv2.fillConvexPoly(mask, hull, 255)
    else:  # 對于可能需要矩形定義的部位
        x, y, w, h = cv2.boundingRect(pts)
        cv2.rectangle(mask, (x, y), (x + w, y + h), 255, -1)
    return mask


def masks_to_psd(base_image_path, masks_dict, output_psd_path):

    # 1. 讀取基礎(chǔ)圖像作為背景層
    base_img = Image.open(base_image_path).convert("RGBA")
    # 2. 創(chuàng)建一個以基礎(chǔ)圖像為畫布的PSD對象[citation:4][citation:9]
    psd = PSDImage.frompil(base_img)

    # 3. 為每個部位創(chuàng)建圖層[citation:4][citation:9]
    for layer_name, mask in masks_dict.items():
        # 將二值mask (0/255) 轉(zhuǎn)換為RGBA圖像

        rgba_array = np.array(base_img).copy()  # 形狀為 (H, W, 4)
        rgba_array[mask == 0, 3] = 0  # 索引3代表RGBA中的A(Alpha)通道

        part_img = Image.fromarray(rgba_array, mode='RGBA')
        # 第一個圖層
        layer0 = PixelLayer.frompil(part_img, psd)
        layer0.name = layer_name
        layer0.visible = True
        psd.append(layer0)

    # 4. 保存PSD文件[citation:4]
    psd.save(output_psd_path)
    print(f"PSD文件已生成: {output_psd_path}")

def generate_face_outer_mask(image_shape, landmarks, indices):
    """
    生成頭部輪廓以外的 mask
    """
    h, w = image_shape[:2]
    mask_face = np.zeros((h, w), np.uint8)

    pts = landmarks[indices].astype(np.int32)
    hull = cv2.convexHull(pts)
    cv2.fillConvexPoly(mask_face, hull, 255)

    # 反轉(zhuǎn):臉外 = 255
    mask_outer = cv2.bitwise_not(mask_face)
    return mask_outer

def generate_brow_mask(image_shape, landmarks, indices, scale_x=1.2, scale_y=1.5):
    """
    生成眉毛 mask(扁橢圓 / 拉長)
    """
    mask = np.zeros(image_shape[:2], dtype=np.uint8)
    pts = landmarks[indices].astype(np.int32)

    if pts.shape[0] < 3:
        return mask

    hull = cv2.convexHull(pts)

    # 計算中心
    cx = np.mean(hull[:, 0, 0])
    cy = np.mean(hull[:, 0, 1])

    # 縮放 hull(手動仿射)
    scaled = []
    for p in hull[:, 0, :]:
        x = cx + (p[0] - cx) * scale_x
        y = cy + (p[1] - cy) * scale_y
        scaled.append([int(x), int(y)])

    scaled = np.array(scaled, np.int32)
    cv2.fillConvexPoly(mask, scaled, 255)
    return mask

def process_single_image(image_path, facer, output_dir="output"):
    """
    處理單張圖片的主流程。
    """
    # 1. 讀取圖片并運(yùn)行關(guān)鍵點檢測
    image = cv2.imread(image_path)
    result = facer.run(image)
    # 假設(shè)只處理檢測到的第一張臉
    if len(result) == 0:
        print(f"未檢測到人臉: {image_path}")
        return
    landmarks = result[0]['kps']  # 形狀應(yīng)為 (98, 2)

    # 2. 定義各部位的關(guān)鍵點索引 (需根據(jù)你的98點模型調(diào)整)
    # 以下索引為示例,請務(wù)必根據(jù)你的模型定義進(jìn)行核對和修改
    PARTS_INDEX = {
        "Face_Outline": list(range(0, 32)),  # 臉部輪廓示例索引
        "Left_Eye": list(range(60, 68)),  # 左眼
        "Right_Eye": list(range(68, 76)),  # 右眼
        "Nose": list(range(51, 60)),  # 鼻子
        "Mouth": list(range(76, 96)),  # 嘴巴
        "Left_Brow" : list(range(33, 41)),
        "Right_Brow" : list(range(42, 50))
        # 你可以根據(jù)需要添加更多部位,如眉毛: list(range(33, 51))
    }

    # 3. 為每個部位生成遮罩
    masks = {}
    for part_name, indices in PARTS_INDEX.items():

        if part_name == "Face_Outline":
            mask = generate_face_outer_mask(image.shape, landmarks, indices)

        elif part_name in ["Left_Eye", "Right_Eye"]:
            mask = generate_eye_ellipse_mask(image.shape, landmarks, indices)
        elif part_name in ["Left_Brow", "Right_Brow"]:
            mask = generate_brow_mask(image.shape, landmarks, indices)
        else:
            mask = generate_part_mask(image.shape, landmarks, indices)

        masks[part_name] = mask
        # 可選:保存每個部位的遮罩為PNG以供檢查
        # cv2.imwrite(os.path.join(output_dir, f"{part_name}.png"), mask)

    # 4. 生成PSD
    os.makedirs(output_dir, exist_ok=True)
    base_name = os.path.splitext(os.path.basename(image_path))[0]
    psd_path = os.path.join(output_dir, f"{base_name}_layers.psd")
    masks_to_psd(image_path, masks, psd_path)


if __name__ == "__main__":
    # 初始化你的關(guān)鍵點檢測器
    facer = FaceAna()

    image_path = r"D:\project_2025\live2d\talking-head-anime-4-demo-main\demo\data\images\lambda_02.png"
    process_single_image(image_path, facer, output_dir="psd_output")

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Pandas?時間序列分析中的resample函數(shù)

    Pandas?時間序列分析中的resample函數(shù)

    這篇文章主要介紹了Pandas?時間序列分析中的resample函數(shù),Pandas?中的resample函數(shù)用于各種頻率的轉(zhuǎn)換工作,下面我們就來看看其的參數(shù)、相關(guān)資料等,需要的小伙伴可以參考一下,希望給你帶來幫助
    2022-02-02
  • Python類的動態(tài)綁定實現(xiàn)原理

    Python類的動態(tài)綁定實現(xiàn)原理

    這篇文章主要介紹了Python類的動態(tài)綁定實現(xiàn)原理,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-03-03
  • Python使用django解決跨域請求的問題

    Python使用django解決跨域請求的問題

    這篇文章主要給大家介紹了python如何使用django解決跨域請求的問題,文中有詳細(xì)的代碼示例,具有一定的參考價值,需要的朋友可以參考下
    2023-07-07
  • Python代碼實現(xiàn)為Word文檔加上專業(yè)水印

    Python代碼實現(xiàn)為Word文檔加上專業(yè)水印

    在日常辦公中,為 Word 文檔添加水印是一項常見需求,本文將介紹如何使用 Spire.Doc for Python 庫,通過簡潔的 Python 代碼輕松為 Word 文檔添加文字水印和圖片水印,有需要的可以了解下
    2026-03-03
  • Python?DataFrame處理缺失值的完整指南與實戰(zhàn)技巧

    Python?DataFrame處理缺失值的完整指南與實戰(zhàn)技巧

    在數(shù)據(jù)分析工作中,缺失值(Missing?Values)是不可避免的挑戰(zhàn),本文將系統(tǒng)介紹DataFrame缺失值的識別、處理策略和實戰(zhàn)技巧,希望對大家有所幫助
    2026-02-02
  • python解析xml文件并修改其屬性值方式

    python解析xml文件并修改其屬性值方式

    本文介紹了兩種解析和修改XML文件的方法:使用Python自帶的xml.etree.ElementTree和第三方的lxml,lxml方法可以添加standalone屬性,而ElementTree則不能
    2025-02-02
  • python2爬取百度貼吧指定關(guān)鍵字和圖片代碼實例

    python2爬取百度貼吧指定關(guān)鍵字和圖片代碼實例

    這篇文章主要介紹了python2爬取百度貼吧指定關(guān)鍵字和圖片代碼實例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-08-08
  • python實現(xiàn)RabbitMQ的消息隊列的示例代碼

    python實現(xiàn)RabbitMQ的消息隊列的示例代碼

    這篇文章主要介紹了python實現(xiàn)RabbitMQ的消息隊列的示例代碼,總結(jié)了RabbitMQ中三種exchange模式的實現(xiàn),分別是fanout, direct和topic。感興趣的小伙伴們可以參考一下
    2018-11-11
  • python簡單的三元一次方程求解實例

    python簡單的三元一次方程求解實例

    這篇文章主要介紹了python簡單的三元一次方程求解實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-04-04
  • Python使用asyncio.Queue進(jìn)行任務(wù)調(diào)度的實現(xiàn)

    Python使用asyncio.Queue進(jìn)行任務(wù)調(diào)度的實現(xiàn)

    本文主要介紹了Python使用asyncio.Queue進(jìn)行任務(wù)調(diào)度的實現(xiàn),它可以用于任務(wù)調(diào)度和數(shù)據(jù)交換,文中通過示例代碼介紹的非常詳細(xì),感興趣的可以了解一下
    2024-02-02

最新評論

东城区| 东兰县| 武平县| 营口市| 大渡口区| 福海县| 林州市| 嘉义县| 土默特左旗| 陆川县| 揭西县| 阿坝县| 浑源县| 准格尔旗| 舒兰市| 林西县| 泽州县| 涿鹿县| 米脂县| 洛南县| 信宜市| 东丰县| 武定县| 临夏县| 库车县| 佛山市| 九台市| 万盛区| 左权县| 武宣县| 历史| 昆明市| 延吉市| 丹阳市| 巴楚县| 清流县| 栾城县| 胶南市| 乌鲁木齐县| 鲁甸县| 高安市|