【教学类-102-10】剪纸图案全套代码09——Python线条虚线优化版04(原图放大白背景)+制作1图2图6图24图

Python剪纸图案线条虚线代码优化

背景需求:

前期完成了最终版本的点状虚线剪纸图代码,需要再同样做一个线条虚线

【教学类-102-09】剪纸图案全套代码08——Python点状虚线优化版本03(原图放大白背景)+制作1图2图6图24图-优快云博客文章浏览阅读764次,点赞11次,收藏5次。【教学类-102-09】剪纸图案全套代码08——Python点状虚线优化版本03(原图放大白背景)+制作1图2图6图24图 https://blog.youkuaiyun.com/reasonsummer/article/details/147165562?spm=1011.2415.3001.5331

我把两个代码复制放入deepseek,请它组合

代码展示

'''
优化版
剪纸外轮廓描边虚线制作(黑色线段虚线)沿线剪——最终稳定版
确保显示虚线边框且无多余连接线
deepseek,阿夏
20250412
'''

from PIL import Image, ImageDraw
import os
import math
import numpy as np

# 主路径
path = r'C:\Users\jg2yXRZ\OneDrive\桌面\20250401边缘线剪纸'
a='13'
b='裙子'
c='线条'

all=path+fr'\{a}{b}合并图'

# 参数设置
white_border_width = 30  # 白边宽度(像素)
dash_length = 20       # 每段虚线长度(像素)
dash_gap = 20           # 虚线间距(像素)
dash_width = 10         # 虚线粗细(像素)
transparent_edge = 50   # 裁剪时不保留额外透明边距
target_width = 2000     # 统一宽度
target_height = 2000    # 统一高度
background_expand = 1000 # 白色背景放大尺寸

# 定义文件夹路径
in_folder = os.path.join(path, f'{a}_01{b}白背景')  # 原始图片(白背景)
big_folder = os.path.join(path, f'{a}_08{b}{c}放大背景')  # 放大背景输出
transparent_folder = os.path.join(path, f'{a}_09{b}{c}透明背景')  # 透明背景输出
output_folder = os.path.join(path, f'{a}_10{b}{c}虚线轮廓')  # 最终输出
cropped_folder = os.path.join(path, f'{a}_11{b}{c}虚线切边') # 裁剪后的透明图片
final_folder = os.path.join(path, f'{a}_12{b}{c}线条虚线切边统一图') # 统一尺寸图片

# 创建输出文件夹
os.makedirs(all, exist_ok=True)
os.makedirs(big_folder, exist_ok=True)
os.makedirs(transparent_folder, exist_ok=True)
os.makedirs(output_folder, exist_ok=True)
os.makedirs(cropped_folder, exist_ok=True)
os.makedirs(final_folder, exist_ok=True)

print('------1、白色PNG背景放大一点-----')
def expand_background():
    """放大白色背景"""
    for filename in os.listdir(in_folder):
        if filename.lower().endswith('.png'):
            input_path = os.path.join(in_folder, filename)
            with Image.open(input_path) as img:
                original_width, original_height = img.size
                
                # 创建新画布(长宽各+background_expand,白色背景)
                new_width = original_width + background_expand
                new_height = original_height + background_expand
                new_image = Image.new('RGB', (new_width, new_height), (255, 255, 255))
                
                # 计算粘贴位置(居中)
                paste_x = (new_width - original_width) // 2
                paste_y = (new_height - original_height) // 2
                
                # 将原始图片粘贴到新画布上
                new_image.paste(img, (paste_x, paste_y), img if img.mode == 'RGBA' else None)
                
                # 保存结果
                big_path = os.path.join(big_folder, filename)
                new_image.save(big_path)

expand_background()

print('------2、白色PNG背景变成透明-----')
def make_transparent():
    """将白色背景转为透明"""
    for file_name in os.listdir(big_folder):
        if file_name.lower().endswith((".png", ".jpg", ".jpeg")):
            input_file_path = os.path.join(big_folder, file_name)
            output_file_path = os.path.join(transparent_folder, file_name)
            
            img = Image.open(input_file_path)
            img = img.convert("RGBA")
            datas = img.getdata()

            new_data = []
            for item in datas:
                if item[0] == 255 and item[1] == 255 and item[2] == 255:
                    new_data.append((255, 255, 255, 0))  # 设置为完全透明
                else:
                    new_data.append(item)

            img.putdata(new_data)
            img.save(output_file_path)
            print(f"已处理: {file_name}")

make_transparent()

print('------3、添加虚线轮廓-----')
def get_edge_pixels(image):
    """获取图像中不透明像素与透明像素交界的边缘像素坐标"""
    edge_pixels = []
    pixels = image.load()
    width, height = image.size
    
    for y in range(height):
        for x in range(width):
            if pixels[x, y][3] > 0:  # 不透明像素
                # 检查4邻域
                for dx, dy in [(-1,0),(1,0),(0,-1),(0,1)]:
                    nx, ny = x+dx, y+dy
                    if 0 <= nx < width and 0 <= ny < height:
                        if pixels[nx, ny][3] == 0:  # 邻域透明
                            edge_pixels.append((x, y))
                            break
    return edge_pixels

def expand_edge_pixels(edge_pixels, distance, width, height):
    """扩展边缘像素坐标到指定距离"""
    expanded_pixels = set()
    for x, y in edge_pixels:
        for dy in range(-distance, distance+1):
            for dx in range(-distance, distance+1):
                nx, ny = x+dx, y+dy
                if 0 <= nx < width and 0 <= ny < height:
                    expanded_pixels.add((nx, ny))
    return expanded_pixels

def get_contour_pixels(border_pixels, width, height):
    """获取白边区域的外轮廓像素(使用边缘追踪算法)"""
    # 找到起始点(最左上角的边界像素)
    start_point = None
    for y in range(height):
        for x in range(width):
            if (x,y) in border_pixels:
                start_point = (x,y)
                break
        if start_point:
            break
    
    if not start_point:
        return []
    
    # 使用Moore-Neighbor追踪算法获取轮廓
    contour = []
    current = start_point
    previous = (current[0]-1, current[1])  # 假设从左侧开始
    
    directions = [
        (0, -1), (1, -1), (1, 0), (1, 1),
        (0, 1), (-1, 1), (-1, 0), (-1, -1)
    ]
    
    while True:
        contour.append(current)
        # 找到下一个边界点
        found = False
        start_dir = (directions.index((previous[0]-current[0], previous[1]-current[1])) + 1) % 8
        for i in range(8):
            dir_idx = (start_dir + i) % 8
            dx, dy = directions[dir_idx]
            neighbor = (current[0]+dx, current[1]+dy)
            
            if 0 <= neighbor[0] < width and 0 <= neighbor[1] < height:
                if neighbor in border_pixels:
                    previous = current
                    current = neighbor
                    found = True
                    break
        
        if not found or current == start_point:
            break
    
    return contour

def draw_uniform_dashes(image, contour, dash_length, dash_gap, dash_width):
    """在轮廓上均匀绘制黑色虚线"""
    dash_layer = Image.new('RGBA', image.size, (0, 0, 0, 0))
    draw = ImageDraw.Draw(dash_layer)
    
    if not contour:
        return dash_layer
    
    # 计算轮廓总长度
    total_length = 0
    segments = []
    for i in range(len(contour)):
        p1 = contour[i]
        p2 = contour[(i+1)%len(contour)]
        dx = p2[0] - p1[0]
        dy = p2[1] - p1[1]
        length = math.sqrt(dx*dx + dy*dy)
        segments.append((p1, p2, length))
        total_length += length
    
    # 计算虚线周期长度
    dash_cycle = dash_length + dash_gap
    
    # 计算需要绘制的虚线数量
    num_dashes = int(total_length / dash_cycle)
    if num_dashes == 0:
        num_dashes = 1
    
    # 均匀分布虚线
    current_pos = 0
    segment_idx = 0
    remaining_seg = segments[0][2]
    
    while current_pos < total_length and segment_idx < len(segments):
        # 找到当前虚线起点所在线段
        while current_pos > remaining_seg and segment_idx < len(segments)-1:
            current_pos -= rem
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿夏reasonsummer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值