当前位置: 首页 > news >正文

【教学类-102-03】自制剪纸图案(留白边、沿线剪)03——Python制作白色描边和黑点虚线间隔(透明png图片)

背景需求:

用Python对透明背景png图案的制作拓展白色描边,制作点状虚线

from PIL import Image, ImageDraw
import os

# 距离图片边缘的距离(留多少白边)
bianju = 10  
# 留白线的粗细(剪切边的粗细)
bianju2 = 2
# 圆点的大小
dot_size = 5
# 圆点之间的间隔
dot_spacing = 5

def detect_edges(image):
    """检测图像的边缘。如果像素透明,则标记为边缘。"""
    if image.mode != 'RGBA':
        image = image.convert('RGBA')
    
    width, height = image.size
    edges = Image.new('L', (width, height), 0)
    draw = ImageDraw.Draw(edges)
    
    pixels = image.load()
    for y in range(1, height - 1):
        for x in range(1, width - 1):
            r, g, b, a = pixels[x, y]
            if a == 0:
                continue
            
            neighbors = [
                pixels[x-1, y], pixels[x+1, y],
                pixels[x, y-1], pixels[x, y+1]
            ]
            for nr, ng, nb, na in neighbors:
                if na == 0:
                    draw.point((x, y), fill=255)
                    break
    return edges

def expand_edges(edges, distance):
    """扩展图像的边缘。根据给定的距离,将边缘像素扩展到指定范围。"""
    expanded_edges = Image.new('L', edges.size, 0)
    draw = ImageDraw.Draw(expanded_edges)
    
    pixels = edges.load()
    for y in range(edges.height):
        for x in range(edges.width):
            if pixels[x, y] > 0:
                for dy in range(-distance, distance + 1):
                    for dx in range(-distance, distance + 1):
                        nx, ny = x + dx, y + dy
                        if 0 <= nx < edges.width and 0 <= ny < edges.height:
                            draw.point((nx, ny), fill=255)
    return expanded_edges

def process_images(input_folder, output_folder):
    """处理输入文件夹中的所有PNG图像,并将结果保存到输出文件夹中。"""
    if not os.path.exists(output_folder):
        os.makedirs(output_folder)
    
    for filename in os.listdir(input_folder):
        if filename.endswith(".png"):
            image_path = os.path.join(input_folder, filename)
            image = Image.open(image_path).convert('RGBA')
            
            edges = detect_edges(image)
            expanded_edges = expand_edges(edges, bianju)
            
            result = Image.new('RGBA', image.size, (255, 255, 255, 0))
            red_fill = Image.new('RGBA', image.size, (255, 255, 255, 255))
            masked_red_fill = Image.composite(red_fill, Image.new('RGBA', image.size), expanded_edges)
            final_result = Image.alpha_composite(image, masked_red_fill)
            
            temp_image = Image.new('RGBA', final_result.size, (0, 0, 0, 0))
            draw = ImageDraw.Draw(temp_image)
            pixels = final_result.load()
            
            # 用于交替绘制黑白圆点的计数器
            dot_counter = 0
            
            for y in range(1, final_result.height - 1, dot_spacing):
                for x in range(1, final_result.width - 1, dot_spacing):
                    r, g, b, a = pixels[x, y]
                    if a == 0:
                        continue
                    
                    # 检查是否是边缘像素
                    neighbors = [
                        pixels[x-1, y], pixels[x+1, y],
                        pixels[x, y-1], pixels[x, y+1]
                    ]
                    edge_found = False
                    for nr, ng, nb, na in neighbors:
                        if na == 0:
                            edge_found = True
                            break
                    
                    if edge_found:
                        # 交替绘制黑白圆点
                        if dot_counter % 2 == 0:
                            draw.ellipse([
                                x - dot_size//2, y - dot_size//2,
                                x + dot_size//2, y + dot_size//2
                            ], fill=(0, 0, 0))
                        else:
                            draw.ellipse([
                                x - dot_size//2, y - dot_size//2,
                                x + dot_size//2, y + dot_size//2
                            ], fill=(255, 255, 255))
                        dot_counter += 1
            
            final_result = Image.alpha_composite(final_result, temp_image)
            final_result = Image.alpha_composite(final_result, image)
            
            output_path = os.path.join(output_folder, filename)
            final_result.save(output_path)
            print(f"Processed {filename} and saved to {output_path}")

if __name__ == '__main__':
    path = r'C:\Users\jg2yXRZ\OneDrive\桌面\20250401边缘线剪纸'
    input_folder = path + r'\01_01原图'
    output_folder = path + r'\01_02边图'
    os.makedirs(output_folder, exist_ok=True)
    process_images(input_folder, output_folder)

换了一张边距充分的图片也是一样的结果

黑白圆点不平均,

代码展示

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

# 参数配置
WHITE_BORDER_WIDTH = 5   # 白色边缘宽度
DOT_SIZE = 5             # 圆点直径
DOT_SPACING = 10         # 圆点间距(像素)
DOT_OFFSET = 3           # 圆点向外偏移量

def precise_edge_detection(image):
    """使用更精确的边缘检测算法"""
    if image.mode != 'RGBA':
        image = image.convert('RGBA')
    
    # 转换为numpy数组处理
    arr = np.array(image)
    alpha = arr[:,:,3]
    
    # 使用sobel算子检测边缘
    from scipy import ndimage
    sobel_x = ndimage.sobel(alpha, axis=0)
    sobel_y = ndimage.sobel(alpha, axis=1)
    edge_mask = np.hypot(sobel_x, sobel_y) > 0
    
    # 转换为PIL图像
    edge_image = Image.fromarray((edge_mask * 255).astype(np.uint8))
    return edge_image

def create_white_border(edge_image, width):
    """创建白色边缘区域"""
    from scipy import ndimage
    arr = np.array(edge_image)
    distance = ndimage.distance_transform_edt(arr == 0)
    white_border = (distance <= width) & (distance > 0)
    return Image.fromarray((white_border * 255).astype(np.uint8))

def get_smooth_contour(white_border):
    """使用Marching Squares算法获取平滑轮廓"""
    arr = np.array(white_border) > 0
    contours = measure.find_contours(arr, 0.5)
    
    if not contours:
        return []
    
    # 取最长的轮廓
    main_contour = max(contours, key=len)
    
    # 简化轮廓点
    from scipy.interpolate import splprep, splev
    tck, u = splprep(main_contour.T, u=None, s=0.0, per=1)
    u_new = np.linspace(u.min(), u.max(), len(main_contour)//2)
    x_new, y_new = splev(u_new, tck, der=0)
    
    return list(zip(x_new, y_new))

def distribute_dots_on_contour(contour, image_size):
    """在轮廓上均匀分布圆点"""
    if not contour:
        return []
    
    # 计算轮廓总长度
    total_length = 0
    lengths = []
    for i in range(len(contour)):
        x1, y1 = contour[i]
        x2, y2 = contour[(i+1)%len(contour)]
        segment_length = math.hypot(x2-x1, y2-y1)
        lengths.append(segment_length)
        total_length += segment_length
    
    # 计算需要的圆点数量
    num_dots = int(total_length / DOT_SPACING)
    if num_dots < 1:
        return []
    
    # 均匀分布点
    dot_positions = []
    target_length = 0
    current_segment = 0
    accumulated_length = 0
    
    for _ in range(num_dots):
        # 找到目标位置所在的线段
        while accumulated_length + lengths[current_segment] < target_length:
            accumulated_length += lengths[current_segment]
            current_segment = (current_segment + 1) % len(contour)
        
        # 计算在线段上的位置
        segment_start = contour[current_segment]
        segment_end = contour[(current_segment+1)%len(contour)]
        ratio = (target_length - accumulated_length) / lengths[current_segment]
        
        x = segment_start[0] * (1-ratio) + segment_end[0] * ratio
        y = segment_start[1] * (1-ratio) + segment_end[1] * ratio
        
        # 计算法线方向(向外)
        dx = segment_end[0] - segment_start[0]
        dy = segment_end[1] - segment_start[1]
        nx = -dy / math.hypot(dx, dy)
        ny = dx / math.hypot(dx, dy)
        
        # 向外偏移
        dot_x = x + nx * DOT_OFFSET
        dot_y = y + ny * DOT_OFFSET
        
        # 确保在图像范围内
        dot_x = max(DOT_SIZE//2, min(dot_x, image_size[0] - DOT_SIZE//2 - 1))
        dot_y = max(DOT_SIZE//2, min(dot_y, image_size[1] - DOT_SIZE//2 - 1))
        
        dot_positions.append((dot_x, dot_y))
        target_length += total_length / num_dots
        if target_length > total_length:
            target_length -= total_length
    
    return dot_positions

def process_image(image_path, output_path):
    """处理单个图像"""
    try:
        image = Image.open(image_path).convert('RGBA')
    except:
        print(f"无法打开图像: {image_path}")
        return
    
    # 第一步:精确边缘检测
    edges = precise_edge_detection(image)
    
    # 第二步:创建白色边缘
    white_border = create_white_border(edges, WHITE_BORDER_WIDTH)
    
    # 创建白色边缘图像
    white_image = Image.new('RGBA', image.size, (0,0,0,0))
    white_draw = ImageDraw.Draw(white_image)
    white_draw.bitmap((0,0), white_border.convert('L'), fill=(255,255,255,255))
    
    # 合并图像
    result = Image.alpha_composite(image, white_image)
    
    # 第三步:获取平滑轮廓
    contour = get_smooth_contour(white_border)
    
    if contour:
        # 第四步:在轮廓上均匀分布圆点
        dot_positions = distribute_dots_on_contour(contour, image.size)
        
        # 绘制圆点
        draw = ImageDraw.Draw(result)
        for i, (x, y) in enumerate(dot_positions):
            if i % 2 == 0:
                draw.ellipse([
                    x-DOT_SIZE//2, y-DOT_SIZE//2,
                    x+DOT_SIZE//2, y+DOT_SIZE//2
                ], fill=(0, 0, 0, 255))  # 黑点
            else:
                draw.ellipse([
                    x-DOT_SIZE//2, y-DOT_SIZE//2,
                    x+DOT_SIZE//2, y+DOT_SIZE//2
                ], fill=(255, 255, 255, 255))  # 白点
    
    # 保存结果
    result.save(output_path)
    print(f"处理完成: {output_path}")

def process_folder(input_folder, output_folder):
    """处理文件夹中的所有PNG图像"""
    if not os.path.exists(output_folder):
        os.makedirs(output_folder)
    
    for filename in os.listdir(input_folder):
        if filename.lower().endswith('.png'):
            input_path = os.path.join(input_folder, filename)
            output_path = os.path.join(output_folder, filename)
            process_image(input_path, output_path)

if __name__ == '__main__':
    input_folder = r'C:\Users\jg2yXRZ\OneDrive\桌面\20250401边缘线剪纸\01_01原图'
    output_folder = r'C:\Users\jg2yXRZ\OneDrive\桌面\20250401边缘线剪纸\01_02边图'
    process_folder(input_folder, output_folder)

我试了无数次修改,这个黑点子始终是逆时针旋转90度

换一个问法继续测试

第1次修改

'''
094把内部边缘线变成点状
deepseek 阿夏
20250405
'''

from PIL import Image, ImageDraw
import os

# 白边宽度(像素)
white_border_width = 20
# 黑点直径(像素)
dot_size = 5
# 黑点间距(像素)
dot_spacing = 5

def get_edge_pixels(image):
    """
    获取图像中不透明像素与透明像素交界的边缘像素坐标
    :param image: 输入的RGBA图像
    :return: 边缘像素坐标列表
    """
    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邻域像素
                neighbors = [
                    (x-1, y), (x+1, y),
                    (x, y-1), (x, y+1)
                ]
                for nx, ny in neighbors:
                    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):
    """
    扩展边缘像素坐标到指定距离
    :param edge_pixels: 原始边缘像素坐标列表
    :param distance: 扩展距离(像素)
    :return: 扩展后的像素坐标集合
    """
    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
                expanded_pixels.add((nx, ny))
    return expanded_pixels

def draw_dots_on_border(image, original_edge_pixels, border_pixels):
    """
    在原始边缘与白边交界处绘制黑点
    :param image: 原始图像
    :param original_edge_pixels: 原始边缘像素坐标
    :param border_pixels: 白边区域像素坐标集合
    :return: 带有点状边框的图像
    """
    # 创建一个透明图层用于绘制点
    dot_layer = Image.new('RGBA', image.size, (0, 0, 0, 0))
    draw = ImageDraw.Draw(dot_layer)
    
    # 找出需要绘制黑点的位置(原始边缘与白边交界处)
    dots_to_draw = []
    for x, y in original_edge_pixels:
        if (x, y) in border_pixels:
            dots_to_draw.append((x, y))
    
    # 按照间距绘制黑点
    for i in range(0, len(dots_to_draw), dot_spacing):
        x, y = dots_to_draw[i]
        draw.ellipse([
            (x - dot_size//2, y - dot_size//2),
            (x + dot_size//2, y + dot_size//2)
        ], fill=(0, 0, 0, 255))
    
    return dot_layer

def process_image(input_path, output_path):
    """
    处理单个图像
    :param input_path: 输入图像路径
    :param output_path: 输出图像路径
    """
    # 打开原始图像
    original = Image.open(input_path).convert('RGBA')
    width, height = original.size
    
    # 获取原始图像的边缘像素
    original_edge_pixels = get_edge_pixels(original)
    
    # 扩展边缘像素创建白边区域
    border_pixels = expand_edge_pixels(original_edge_pixels, white_border_width)
    
    # 创建白边图层
    white_border = Image.new('RGBA', (width, height), (255, 255, 255, 255))
    # 创建蒙版
    mask = Image.new('L', (width, height), 0)
    mask_pixels = mask.load()
    for x, y in border_pixels:
        if 0 <= x < width and 0 <= y < height:
            mask_pixels[x, y] = 255
    white_border.putalpha(mask)
    
    # 将白边与原始图像合成
    result = Image.alpha_composite(original, white_border)
    
    # 在白边与原始图像交界处绘制黑点
    dot_layer = draw_dots_on_border(original, original_edge_pixels, border_pixels)
    result = Image.alpha_composite(result, dot_layer)
    
    # 保存结果
    result.save(output_path, format='PNG')
    print(f"Processed and saved to {output_path}")

def process_images(input_folder, output_folder):
    """
    处理文件夹中的所有PNG图像
    :param input_folder: 输入文件夹路径
    :param output_folder: 输出文件夹路径
    """
    if not os.path.exists(output_folder):
        os.makedirs(output_folder)
    
    for filename in os.listdir(input_folder):
        if filename.lower().endswith(".png"):
            input_path = os.path.join(input_folder, filename)
            output_path = os.path.join(output_folder, filename)
            process_image(input_path, output_path)


if __name__ == '__main__':
    path = r'C:\Users\jg2yXRZ\OneDrive\桌面\20250401边缘线剪纸'
    input_folder = os.path.join(path, '03_01正方形原图')
    output_folder = os.path.join(path, '03_02正方形边图')
    os.makedirs(output_folder, exist_ok=True)
    process_images(input_folder, output_folder)

青蛙的黑点在青蛙外轮廓上(我需要的是白色描边的外侧

第2次修改

'''
095把白色拓展边缘全部做成点状
deepseek 阿夏
20250405
'''

from PIL import Image, ImageDraw
import os
import math

# 距离图片边缘的距离(留多少白边)
bianju = 20  # 增加白边宽度到20磅
# 黑点的直径
dot_size = 5
# 黑点之间的间距
dot_spacing = 5

def detect_edges(image):
    """
    检测图像的边缘。如果像素透明,则标记为边缘。
    :param image: 输入的图像
    :return: 包含边缘信息的图像
    """
    if image.mode != 'RGBA':
        image = image.convert('RGBA')
    
    width, height = image.size
    edges = Image.new('L', (width, height), 0)
    draw = ImageDraw.Draw(edges)
    
    pixels = image.load()
    for y in range(1, height - 1):
        for x in range(1, width - 1):
            r, g, b, a = pixels[x, y]
            if a == 0:
                continue
            
            neighbors = [
                pixels[x-1, y], pixels[x+1, y],
                pixels[x, y-1], pixels[x, y+1]
            ]
            for nr, ng, nb, na in neighbors:
                if na == 0:
                    draw.point((x, y), fill=255)
                    break
    return edges

def expand_edges(edges, distance):
    """
    扩展图像的边缘。根据给定的距离,将边缘像素扩展到指定范围。
    :param edges: 包含边缘信息的图像
    :param distance: 扩展的距离
    :return: 扩展后的边缘图像
    """
    expanded_edges = Image.new('L', edges.size, 0)
    draw = ImageDraw.Draw(expanded_edges)
    
    pixels = edges.load()
    for y in range(edges.height):
        for x in range(edges.width):
            if pixels[x, y] > 0:
                for dy in range(-distance, distance + 1):
                    for dx in range(-distance, distance + 1):
                        nx, ny = x + dx, y + dy
                        if 0 <= nx < edges.width and 0 <= ny < edges.height:
                            draw.point((nx, ny), fill=255)
    return expanded_edges

def draw_dotted_border(image, edge_mask):
    """
    在图像的边缘区域绘制点状边框
    :param image: 原始图像
    :param edge_mask: 边缘区域掩膜
    :return: 带有点状边框的图像
    """
    # 创建一个透明图层用于绘制点
    dot_layer = Image.new('RGBA', image.size, (0, 0, 0, 0))
    draw = ImageDraw.Draw(dot_layer)
    
    pixels = edge_mask.load()
    width, height = edge_mask.size
    
    # 计算点的步长(直径+间距)
    step = dot_size + dot_spacing
    
    # 遍历图像,在边缘区域绘制点
    for y in range(0, height, step):
        for x in range(0, width, step):
            if 0 <= x < width and 0 <= y < height and pixels[x, y] > 0:
                # 绘制一个黑点
                draw.ellipse([
                    (x - dot_size//2, y - dot_size//2),
                    (x + dot_size//2, y + dot_size//2)
                ], fill=(0, 0, 0, 255))
    
    return dot_layer

def process_images(input_folder, output_folder):
    """
    处理输入文件夹中的所有PNG图像,并将结果保存到输出文件夹中。
    :param input_folder: 输入文件夹路径
    :param output_folder: 输出文件夹路径
    """
    if not os.path.exists(output_folder):
        os.makedirs(output_folder)
    
    for filename in os.listdir(input_folder):
        if filename.endswith(".png"):
            image_path = os.path.join(input_folder, filename)
            image = Image.open(image_path).convert('RGBA')
            
            # 检测图像的边缘
            edges = detect_edges(image)
            
            # 扩展边缘像素,扩展距离为bianju
            expanded_edges = expand_edges(edges, bianju)
            
            # 创建一个白色边缘层
            white_border = Image.new('RGBA', image.size, (255, 255, 255, 255))
            # 将白色边缘应用到扩展边缘区域
            white_border.putalpha(expanded_edges)
            
            # 将原始图像与白色边缘合成
            result_with_white_border = Image.alpha_composite(image, white_border)
            
            # 在边缘区域绘制点状边框
            dot_border = draw_dotted_border(image, expanded_edges)
            
            # 将点状边框与结果合成
            final_result = Image.alpha_composite(result_with_white_border, dot_border)
            
            # 保存结果(保持透明背景)
            output_path = os.path.join(output_folder, filename)
            final_result.save(output_path, format='PNG')
            print(f"Processed {filename} and saved to {output_path}")

if __name__ == '__main__':
    path = r'C:\Users\jg2yXRZ\OneDrive\桌面\20250401边缘线剪纸'
    input_folder = os.path.join(path, '03_01正方形原图')
    output_folder = os.path.join(path, '03_02正方形边图')
    os.makedirs(output_folder, exist_ok=True)
    process_images(input_folder, output_folder)

它把白色描边20磅的位置全部填充了点子

第3次修改

'''
096内外黑色小点子
deepseek 阿夏
20250405
'''

from PIL import Image, ImageDraw
import os

# 白边宽度(像素)
white_border_width = 20
# 黑点直径(像素)
dot_size = 5
# 黑点间距(像素)
dot_spacing = 5

def get_edge_pixels(image):
    """
    获取图像中不透明像素与透明像素交界的边缘像素坐标
    :param image: 输入的RGBA图像
    :return: 边缘像素坐标列表
    """
    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邻域像素
                neighbors = [
                    (x-1, y), (x+1, y),
                    (x, y-1), (x, y+1)
                ]
                for nx, ny in neighbors:
                    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):
    """
    扩展边缘像素坐标到指定距离
    :param edge_pixels: 原始边缘像素坐标列表
    :param distance: 扩展距离(像素)
    :return: 扩展后的像素坐标集合
    """
    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
                expanded_pixels.add((nx, ny))
    return expanded_pixels

def get_outer_edge_pixels(border_pixels, width, height):
    """
    获取白边区域的外边缘像素(与透明区域接触的一侧)
    :param border_pixels: 白边区域的所有像素
    :param width: 图像宽度
    :param height: 图像高度
    :return: 外边缘像素列表
    """
    outer_edge = set()
    border_set = border_pixels
    
    for x, y in border_set:
        # 检查8邻域是否有透明像素
        neighbors = [
            (x-1, y-1), (x, y-1), (x+1, y-1),
            (x-1, y),             (x+1, y),
            (x-1, y+1), (x, y+1), (x+1, y+1)
        ]
        
        for nx, ny in neighbors:
            if (0 <= nx < width and 0 <= ny < height) and (nx, ny) not in border_set:
                outer_edge.add((x, y))
                break
    
    return list(outer_edge)

def draw_dots_on_outer_edge(image, outer_edge_pixels):
    """
    在白边外侧边缘绘制黑点
    :param image: 原始图像
    :param outer_edge_pixels: 外边缘像素坐标
    :return: 带有点状边框的图像
    """
    # 创建一个透明图层用于绘制点
    dot_layer = Image.new('RGBA', image.size, (0, 0, 0, 0))
    draw = ImageDraw.Draw(dot_layer)
    
    # 按照间距绘制黑点
    for i in range(0, len(outer_edge_pixels), dot_spacing):
        x, y = outer_edge_pixels[i]
        draw.ellipse([
            (x - dot_size//2, y - dot_size//2),
            (x + dot_size//2, y + dot_size//2)
        ], fill=(0, 0, 0, 255))
    
    return dot_layer

def process_image(input_path, output_path):
    """
    处理单个图像
    :param input_path: 输入图像路径
    :param output_path: 输出图像路径
    """
    # 打开原始图像
    original = Image.open(input_path).convert('RGBA')
    width, height = original.size
    
    # 获取原始图像的边缘像素
    original_edge_pixels = get_edge_pixels(original)
    
    # 扩展边缘像素创建白边区域
    border_pixels = expand_edge_pixels(original_edge_pixels, white_border_width)
    
    # 获取白边区域的外边缘像素(靠近透明区域的一侧)
    outer_edge_pixels = get_outer_edge_pixels(border_pixels, width, height)
    
    # 创建白边图层
    white_border = Image.new('RGBA', (width, height), (255, 255, 255, 255))
    # 创建蒙版
    mask = Image.new('L', (width, height), 0)
    mask_pixels = mask.load()
    for x, y in border_pixels:
        if 0 <= x < width and 0 <= y < height:
            mask_pixels[x, y] = 255
    white_border.putalpha(mask)
    
    # 将白边与原始图像合成
    result = Image.alpha_composite(original, white_border)
    
    # 在白边外侧绘制黑点
    dot_layer = draw_dots_on_outer_edge(original, outer_edge_pixels)
    result = Image.alpha_composite(result, dot_layer)
    
    # 保存结果
    result.save(output_path, format='PNG')
    print(f"Processed and saved to {output_path}")

def process_images(input_folder, output_folder):
    """
    处理文件夹中的所有PNG图像
    :param input_folder: 输入文件夹路径
    :param output_folder: 输出文件夹路径
    """
    if not os.path.exists(output_folder):
        os.makedirs(output_folder)
    
    for filename in os.listdir(input_folder):
        if filename.lower().endswith(".png"):
            input_path = os.path.join(input_folder, filename)
            output_path = os.path.join(output_folder, filename)
            process_image(input_path, output_path)

if __name__ == '__main__':
    path = r'C:\Users\jg2yXRZ\OneDrive\桌面\20250401边缘线剪纸'
    input_folder = os.path.join(path, '03_01正方形原图')
    output_folder = os.path.join(path, '03_02正方形边图')
    os.makedirs(output_folder, exist_ok=True)
    process_images(input_folder, output_folder)

白色描边的外侧和内侧都是黑点子

我感觉无论如何白色描边都会遮挡青蛙外轮廓,所以需要把原图青蛙最后覆盖在最上面,这样就能挡住内侧的黑点子。

第4次修改

'''
097把原图覆盖在最上面
deepseek 阿夏
20250405
'''

from PIL import Image, ImageDraw
import os

# 白边宽度(像素)
white_border_width = 20
# 黑点直径(像素)
dot_size = 5
# 黑点间距(像素)
dot_spacing = 5

def get_edge_pixels(image):
    """
    获取图像中不透明像素与透明像素交界的边缘像素坐标
    :param image: 输入的RGBA图像
    :return: 边缘像素坐标列表
    """
    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邻域像素
                neighbors = [
                    (x-1, y), (x+1, y),
                    (x, y-1), (x, y+1)
                ]
                for nx, ny in neighbors:
                    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):
    """
    扩展边缘像素坐标到指定距离
    :param edge_pixels: 原始边缘像素坐标列表
    :param distance: 扩展距离(像素)
    :return: 扩展后的像素坐标集合
    """
    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
                expanded_pixels.add((nx, ny))
    return expanded_pixels

def get_outer_edge_pixels(border_pixels, width, height):
    """
    获取白边区域的外边缘像素(与透明区域接触的一侧)
    :param border_pixels: 白边区域的所有像素
    :param width: 图像宽度
    :param height: 图像高度
    :return: 外边缘像素列表
    """
    outer_edge = set()
    border_set = border_pixels
    
    for x, y in border_set:
        # 检查8邻域是否有透明像素
        neighbors = [
            (x-1, y-1), (x, y-1), (x+1, y-1),
            (x-1, y),             (x+1, y),
            (x-1, y+1), (x, y+1), (x+1, y+1)
        ]
        
        for nx, ny in neighbors:
            if (0 <= nx < width and 0 <= ny < height) and (nx, ny) not in border_set:
                outer_edge.add((x, y))
                break
    
    return list(outer_edge)

def draw_dots_on_outer_edge(image, outer_edge_pixels):
    """
    在白边外侧边缘绘制黑点
    :param image: 原始图像
    :param outer_edge_pixels: 外边缘像素坐标
    :return: 带有点状边框的图像
    """
    # 创建一个透明图层用于绘制点
    dot_layer = Image.new('RGBA', image.size, (0, 0, 0, 0))
    draw = ImageDraw.Draw(dot_layer)
    
    # 按照间距绘制黑点
    for i in range(0, len(outer_edge_pixels), dot_spacing):
        x, y = outer_edge_pixels[i]
        draw.ellipse([
            (x - dot_size//2, y - dot_size//2),
            (x + dot_size//2, y + dot_size//2)
        ], fill=(0, 0, 0, 255))
    
    return dot_layer

def process_image(input_path, output_path):
    """
    处理单个图像
    :param input_path: 输入图像路径
    :param output_path: 输出图像路径
    """
    # 打开原始图像并保留副本
    original = Image.open(input_path).convert('RGBA')
    original_copy = original.copy()  # 创建原始图像的副本用于最后覆盖
    width, height = original.size
    
    # 获取原始图像的边缘像素
    original_edge_pixels = get_edge_pixels(original)
    
    # 扩展边缘像素创建白边区域
    border_pixels = expand_edge_pixels(original_edge_pixels, white_border_width)
    
    # 获取白边区域的外边缘像素(靠近透明区域的一侧)
    outer_edge_pixels = get_outer_edge_pixels(border_pixels, width, height)
    
    # 创建白边图层
    white_border = Image.new('RGBA', (width, height), (255, 255, 255, 255))
    # 创建蒙版
    mask = Image.new('L', (width, height), 0)
    mask_pixels = mask.load()
    for x, y in border_pixels:
        if 0 <= x < width and 0 <= y < height:
            mask_pixels[x, y] = 255
    white_border.putalpha(mask)
    
    # 将白边与原始图像合成
    result = Image.alpha_composite(original, white_border)
    
    # 在白边外侧绘制黑点
    dot_layer = draw_dots_on_outer_edge(original, outer_edge_pixels)
    result = Image.alpha_composite(result, dot_layer)
    
    # 最后将原始图像覆盖在最上层
    result = Image.alpha_composite(result, original_copy)
    
    # 保存结果
    result.save(output_path, format='PNG')
    print(f"Processed and saved to {output_path}")

def process_images(input_folder, output_folder):
    """
    处理文件夹中的所有PNG图像
    :param input_folder: 输入文件夹路径
    :param output_folder: 输出文件夹路径
    """
    if not os.path.exists(output_folder):
        os.makedirs(output_folder)
    
    for filename in os.listdir(input_folder):
        if filename.lower().endswith(".png"):
            input_path = os.path.join(input_folder, filename)
            output_path = os.path.join(output_folder, filename)
            process_image(input_path, output_path)

if __name__ == '__main__':
    path = r'C:\Users\jg2yXRZ\OneDrive\桌面\20250401边缘线剪纸'
    input_folder = os.path.join(path, '03_01正方形原图')
    output_folder = os.path.join(path, '03_02正方形边图')
    os.makedirs(output_folder, exist_ok=True)
    process_images(input_folder, output_folder)

青蛙外形完整了,白色描边旁边也有黑点子了。

但是黑色点子分布不均匀

第4次修改

'''
剪纸外轮廓描边虚线点制作(黑点)沿线剪——平均边缘点子的距离(最终效果)
deepseek 阿夏
20250405
'''

from PIL import Image, ImageDraw
import os
import math

# 白边宽度(像素)
white_border_width = 30
# 黑点直径(像素)
dot_size = 10
# 黑点间距(像素)
dot_spacing = dot_size*2  # 增加间距确保均匀分布

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_dots(image, contour, dot_size, dot_spacing):
    """在轮廓上均匀绘制黑点"""
    dot_layer = Image.new('RGBA', image.size, (0, 0, 0, 0))
    draw = ImageDraw.Draw(dot_layer)
    
    if not contour:
        return dot_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
    
    # 计算需要绘制的点数
    num_dots = int(total_length / dot_spacing)
    if num_dots == 0:
        num_dots = 1
    
    # 均匀分布点
    step = total_length / num_dots
    current_dist = 0
    segment_idx = 0
    remaining_seg = segments[0][2]
    
    for _ in range(num_dots):
        # 找到当前点所在线段
        while current_dist > remaining_seg and segment_idx < len(segments)-1:
            current_dist -= remaining_seg
            segment_idx += 1
            remaining_seg = segments[segment_idx][2]
        
        p1, p2, seg_len = segments[segment_idx]
        ratio = current_dist / seg_len
        x = p1[0] + ratio * (p2[0] - p1[0])
        y = p1[1] + ratio * (p2[1] - p1[1])
        
        # 绘制黑点
        draw.ellipse([
            (x - dot_size/2, y - dot_size/2),
            (x + dot_size/2, y + dot_size/2)
        ], fill=(0, 0, 0, 255))
        
        current_dist += step
    
    return dot_layer

def process_image(input_path, output_path):
    """处理单个图像"""
    original = Image.open(input_path).convert('RGBA')
    original_copy = original.copy()
    width, height = original.size
    
    # 获取边缘并扩展白边
    edge_pixels = get_edge_pixels(original)
    border_pixels = expand_edge_pixels(edge_pixels, white_border_width, width, height)
    
    # 获取精确的外轮廓
    contour = get_contour_pixels(border_pixels, width, height)
    
    # 创建白边图层
    white_border = Image.new('RGBA', (width, height), (255, 255, 255, 255))
    mask = Image.new('L', (width, height), 0)
    mask_pixels = mask.load()
    for x, y in border_pixels:
        mask_pixels[x, y] = 255
    white_border.putalpha(mask)
    
    # 合成白边
    result = Image.alpha_composite(original, white_border)
    
    # 绘制均匀分布的黑点
    dot_layer = draw_uniform_dots(original, contour, dot_size, dot_spacing)
    result = Image.alpha_composite(result, dot_layer)
    
    # 覆盖原始图像
    result = Image.alpha_composite(result, original_copy)
    
    result.save(output_path, format='PNG')
    print(f"Processed: {os.path.basename(input_path)}")

def process_images(input_folder, output_folder):
    """批量处理图像"""
    if not os.path.exists(output_folder):
        os.makedirs(output_folder)
    
    for filename in os.listdir(input_folder):
        if filename.lower().endswith('.png'):
            input_path = os.path.join(input_folder, filename)
            output_path = os.path.join(output_folder, filename)
            process_image(input_path, output_path)

if __name__ == '__main__':
    path = r'C:\Users\jg2yXRZ\OneDrive\桌面\20250401边缘线剪纸'
    input_folder = os.path.join(path, '03_01正方形原图')
    output_folder = os.path.join(path, '03_02正方形边图')
    process_images(input_folder, output_folder)

遍历所有png图片

最终代码

'''
剪纸外轮廓描边虚线点制作(黑点)沿线剪——平均边缘点子的距离(最终效果)
deepseek 阿夏
20250405
'''

from PIL import Image, ImageDraw
import os
import math

# 白边宽度(像素)
white_border_width = 30
# 黑点直径(像素)
dot_size = 10
# 黑点间距(像素)
dot_spacing = dot_size*2  # 增加间距确保均匀分布

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_dots(image, contour, dot_size, dot_spacing):
    """在轮廓上均匀绘制黑点"""
    dot_layer = Image.new('RGBA', image.size, (0, 0, 0, 0))
    draw = ImageDraw.Draw(dot_layer)
    
    if not contour:
        return dot_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
    
    # 计算需要绘制的点数
    num_dots = int(total_length / dot_spacing)
    if num_dots == 0:
        num_dots = 1
    
    # 均匀分布点
    step = total_length / num_dots
    current_dist = 0
    segment_idx = 0
    remaining_seg = segments[0][2]
    
    for _ in range(num_dots):
        # 找到当前点所在线段
        while current_dist > remaining_seg and segment_idx < len(segments)-1:
            current_dist -= remaining_seg
            segment_idx += 1
            remaining_seg = segments[segment_idx][2]
        
        p1, p2, seg_len = segments[segment_idx]
        ratio = current_dist / seg_len
        x = p1[0] + ratio * (p2[0] - p1[0])
        y = p1[1] + ratio * (p2[1] - p1[1])
        
        # 绘制黑点
        draw.ellipse([
            (x - dot_size/2, y - dot_size/2),
            (x + dot_size/2, y + dot_size/2)
        ], fill=(0, 0, 0, 255))
        
        current_dist += step
    
    return dot_layer

def process_image(input_path, output_path):
    """处理单个图像"""
    original = Image.open(input_path).convert('RGBA')
    original_copy = original.copy()
    width, height = original.size
    
    # 获取边缘并扩展白边
    edge_pixels = get_edge_pixels(original)
    border_pixels = expand_edge_pixels(edge_pixels, white_border_width, width, height)
    
    # 获取精确的外轮廓
    contour = get_contour_pixels(border_pixels, width, height)
    
    # 创建白边图层
    white_border = Image.new('RGBA', (width, height), (255, 255, 255, 255))
    mask = Image.new('L', (width, height), 0)
    mask_pixels = mask.load()
    for x, y in border_pixels:
        mask_pixels[x, y] = 255
    white_border.putalpha(mask)
    
    # 合成白边
    result = Image.alpha_composite(original, white_border)
    
    # 绘制均匀分布的黑点
    dot_layer = draw_uniform_dots(original, contour, dot_size, dot_spacing)
    result = Image.alpha_composite(result, dot_layer)
    
    # 覆盖原始图像
    result = Image.alpha_composite(result, original_copy)
    
    result.save(output_path, format='PNG')
    print(f"Processed: {os.path.basename(input_path)}")

def process_images(input_folder, output_folder):
    """批量处理图像"""
    if not os.path.exists(output_folder):
        os.makedirs(output_folder)
    
    for filename in os.listdir(input_folder):
        if filename.lower().endswith('.png'):
            input_path = os.path.join(input_folder, filename)
            output_path = os.path.join(output_folder, filename)
            process_image(input_path, output_path)

if __name__ == '__main__':
    path = r'C:\Users\jg2yXRZ\OneDrive\桌面\20250401边缘线剪纸'
    input_folder = os.path.join(path, '03_01正方形原图')
    output_folder = os.path.join(path, '03_02正方形边图')
    process_images(input_folder, output_folder)

切掉上下左右白边+统一大小(1000*1000)

'''
图片处理流程:
1. 裁剪透明白边,保存透明PNG
2. 对裁剪后的图片统一尺寸,保存透明PNG
deepseek、阿夏
20250405
'''

import os
from PIL import Image

# 全局设置
path = r'C:\Users\jg2yXRZ\OneDrive\桌面\20250401边缘线剪纸'
input_folder = path + r'\03_02正方形边图'  # 原始图片文件夹
cropped_folder = path + r'\03_03切边图透明'  # 裁剪后的透明图片
resized_folder = path + r'\03_04统一图'  # 统一尺寸后的图片

# 创建输出文件夹
os.makedirs(cropped_folder, exist_ok=True)
os.makedirs(resized_folder, exist_ok=True)

# 参数设置
transparent_edge = 40  # 裁剪时不保留额外透明边距
target_width = 1000   # 统一宽度
target_height = 1000  # 统一高度

def find_content_boundary(image):
    """
    找到图像中非透明内容的精确边界
    :param image: PIL Image对象(RGBA模式)
    :return: (left, top, right, bottom) 内容边界坐标
    """
    if image.mode != 'RGBA':
        image = image.convert('RGBA')
    
    width, height = image.size
    pixels = image.load()
    
    left, right = width, 0
    top, bottom = height, 0
    
    for y in range(height):
        for x in range(width):
            if pixels[x, y][3] > 0:  # 非透明像素
                if x < left: left = x
                if x > right: right = x
                if y < top: top = y
                if y > bottom: bottom = y
    
    return left, top, right+1, bottom+1  # +1确保包含边界像素

def crop_to_content(image):
    """精确裁剪到非透明内容边界"""
    boundary = find_content_boundary(image)
    return image.crop(boundary)

def resize_with_transparency(image, target_size):
    """
    保持透明背景调整图像尺寸
    :param image: 已裁剪的图片
    :param target_size: (width, height)目标尺寸
    :return: 调整尺寸后的图像
    """
    # 计算缩放比例(保持宽高比)
    width_ratio = target_size[0] / image.width
    height_ratio = target_size[1] / image.height
    scale_ratio = min(width_ratio, height_ratio)
    
    # 等比缩放
    new_width = int(image.width * scale_ratio)
    new_height = int(image.height * scale_ratio)
    resized = image.resize((new_width, new_height), Image.LANCZOS)
    
    # 创建新透明画布
    new_image = Image.new('RGBA', target_size, (0, 0, 0, 0))
    
    # 计算居中位置
    x_offset = (target_size[0] - new_width) // 2
    y_offset = (target_size[1] - new_height) // 2
    
    # 粘贴缩放后的图像
    new_image.paste(resized, (x_offset, y_offset), resized)
    
    return new_image

def process_images():
    """完整的图片处理流程"""
    # 第一步:精确裁剪透明白边
    print("=== 开始裁剪透明白边 ===")
    for filename in os.listdir(input_folder):
        if filename.lower().endswith('.png'):
            input_path = os.path.join(input_folder, filename)
            output_path = os.path.join(cropped_folder, filename)
            
            try:
                img = Image.open(input_path).convert('RGBA')
                cropped = crop_to_content(img)
                cropped.save(output_path, format='PNG')
                print(f"裁剪完成: {filename}")
            except Exception as e:
                print(f"裁剪失败 {filename}: {str(e)}")
    
    # 第二步:统一已裁剪图片的尺寸
    print("\n=== 开始统一已裁剪图片的尺寸 ===")
    for filename in os.listdir(cropped_folder):
        if filename.lower().endswith('.png'):
            input_path = os.path.join(cropped_folder, filename)
            output_path = os.path.join(resized_folder, filename)
            
            try:
                img = Image.open(input_path).convert('RGBA')
                resized = resize_with_transparency(img, (target_width, target_height))
                resized.save(output_path, format='PNG')
                print(f"尺寸统一完成: {filename}")
            except Exception as e:
                print(f"尺寸调整失败 {filename}: {str(e)}")
    
    print("\n=== 处理完成 ===")
    print(f"裁剪后的图片保存在: {cropped_folder}")
    print(f"统一尺寸的图片保存在: {resized_folder}")

if __name__ == '__main__':
    process_images()

切掉PNG透明图的白边(没有预留上下左右的边距,只有0,顶天立地)

统一PNG图片,大小1000*1000(没有预留上下左右的边距)

做成gif

'''
青蛙图片虚线描边后,做成gif动画,便于贴入CSDN
deepseek,阿夏
20250404
'''
size=1000
d=1000
c=20

from PIL import Image
import os

def create_optimized_gif(input_folder, output_file, duration=d, max_size=size, colors=c, skip_frames=1):
    """完整优化版本"""
    images = []
    for i, filename in enumerate(sorted(os.listdir(input_folder))):
        if i % (skip_frames + 1) != 0:  # 跳过部分帧
            continue
            
        if filename.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp', '.gif')):
            filepath = os.path.join(input_folder, filename)
            try:
                img = Image.open(filepath)
                
                # 调整尺寸
                if max_size:
                    img.thumbnail((max_size, max_size), Image.LANCZOS)
                
                # 转换为P模式(调色板)并减少颜色
                if img.mode != 'P':
                    img = img.convert('P', palette=Image.ADAPTIVE, colors=colors)
                
                images.append(img)
            except Exception as e:
                print(f"无法加载图片 {filename}: {e}")
    
    if not images:
        print("没有找到可用的图片文件")
        return
    
    # 保存为优化后的GIF
    images[0].save(
        output_file,
        save_all=True,
        append_images=images[1:],
        duration=duration,
        loop=0,
        optimize=True,
        disposal=2
    )
    
    print(f"优化后的GIF已创建: {output_file} (大小: {os.path.getsize(output_file)/1024:.2f}KB)")

if __name__ == "__main__":
    path=r'C:\Users\jg2yXRZ\OneDrive\桌面\20250401边缘线剪纸'
    input_folder = path+r"\03_04统一图"  # 图片所在的文件夹
    output_file =path+ r"\Python青蛙切边虚线描边.gif"  # 输出的GIF文件名
    
    # 创建GIF,每帧显示3秒(3000毫秒)
   
    create_optimized_gif( input_folder, output_file, duration=d, max_size=size, colors=c, skip_frames=1)


# from PIL import Image
# import os

# def create_gif(input_folder, output_file, duration=2000, loop=0):
#     """
#     将文件夹中的图片合并为GIF
    
#     参数:
#         input_folder: 包含图片的文件夹路径
#         output_file: 输出的GIF文件路径
#         duration: 每帧显示时间(毫秒),默认3000(3秒)
#         loop: 循环次数,0表示无限循环
#     """
#     # 获取文件夹中所有图片文件
#     images = []
#     for filename in sorted(os.listdir(input_folder)):
#         if filename.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp', '.gif')):
#             filepath = os.path.join(input_folder, filename)
#             try:
#                 img = Image.open(filepath)
#                 images.append(img)
#             except Exception as e:
#                 print(f"无法加载图片 {filename}: {e}")
    
#     if not images:
#         print("没有找到可用的图片文件")
#         return
    
#     # 保存第一张图片以获取尺寸
#     first_image = images[0]
    
#     # 保存为GIF
#     first_image.save(
#         output_file,
#         save_all=True,
#         append_images=images[1:],
#         duration=duration,
#         loop=loop
#     )
    
#     print(f"GIF已成功创建: {output_file}")

# # 使用示例
# if __name__ == "__main__":
#     path=r'C:\Users\jg2yXRZ\OneDrive\桌面\20250401边缘线剪纸'
#     input_folder = path+r"\02_02青蛙白色点图"  # 图片所在的文件夹
#     output_file =path+ r"\青蛙虚线描边.gif"  # 输出的GIF文件名
    
#     # 创建GIF,每帧显示3秒(3000毫秒)
#     create_gif(input_folder, output_file, duration=2000)

相关文章:

  • 做效果图网站seo优化广告
  • 做问卷调查的是哪个网站好share群组链接分享
  • 可以帮忙做网站做公司qq推广软件
  • 柏乡网站建设优化营商环境 助推高质量发展
  • 做房产网站怎么样百度点击软件名风
  • 做装修效果图的网站有哪些杭州制作公司网站
  • 【Introduction to Reinforcement Learning】翻译解读4
  • KWDB创作者计划—边缘计算:从概念到落地的技术解读
  • 荣耀90 GT信息
  • 【微机及接口技术】- 第八章 可编程并行接口
  • 软考中级-软件设计师 2023年上半年下午题真题解析:通关秘籍+避坑指南
  • R语言进行聚类分析
  • JBDC java数据库连接(2)
  • System V 信号量:控制进程间共享资源的访问
  • WPS JS宏编程教程(从基础到进阶)-- 第五部分:JS数组与WPS结合应用
  • 4.8学习总结 贪心算法+Stream流
  • 获取cookie的chrome插件:Get cookies.txt LOCALLY
  • 前端知识点---闭包(javascript)
  • 【设计模式】创建型 -- 单例模式 (c++实现)
  • 最小K个数
  • ecovadis认证基本概述,ecovadis认证审核有效期
  • spring mvc 在拦截器、控制器和视图中获取和使用国际化区域信息的完整示例
  • 【零基础入门unity游戏开发——动画篇】新动画Animator的使用 —— AnimatorController和Animator的使用
  • 【杂谈】-小型推理模型:人工智能领域的新兴力量
  • Day2_Python tornado库2_post方法_上传图片文件
  • NumPy依赖库BLAS和LAPACK详细信息解析