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

【教学类-102-01】自制剪纸图案(留白边、沿线剪)01

背景需求:

班级里个别化美工区买了一套剪纸

这批中班孩子的80、90后父母很重视孩子的手脑协调性,在家经常剪纸。所以孩子们延边剪的水平都不错。而且很有兴趣挑选图案

不到一周,一百张彩色图纸就全部剪完了(有车类、用品、交通工具、字母等图形)

图案造型是点状虚线、留0.5CM白边

思考:

用的太快了,彩色图案比较贵。所以我想自制一些黑白线条图纸,留白边,让幼儿先涂色、再沿线剪。

(AI也可以生成彩色图片,但是学校里用彩色打印不值得。所以只考虑黑白线条图案)

思路:

1、根据之前制作青蛙立体书的经验,想实现边框线描,必须将背景变成透明色、与非透明的青蛙主体进行区分

【教学类-83-02】20241214立体书三角嘴2.0——青蛙(扁菱形嘴)-CSDN博客文章浏览阅读1.1k次,点赞49次,收藏16次。【教学类-83-02】20241214立体书三角嘴2.0——青蛙(长扁菱形) https://blog.csdn.net/reasonsummer/article/details/144510078?spm=1011.2415.3001.5331

所以我选了已经用PS修图的青蛙图片作为实验品

2、关键词思路:找到透明与非透明的交界线,向外(在透明部分)画5磅白色边框。然后再次对新的白色边框外延与非透明部分进行检测,画一根1磅黑线。

3、问题:测试过程中,发现画的线条都是在交界线上的,5磅就是对外2.5磅,对内2.5磅,会遮住一部分图案。

  

多次修改后都无法改变,最后将原图覆盖在新图最上方,解决了这个难题

代码展示

'''
剪纸练习:将透明背景的png图片的边缘留空白,然后再边缘的边缘画黑色线(留边剪)
星火讯飞 阿夏
20250401
'''


from PIL import Image, ImageDraw  # 导入Pillow库中的Image和ImageDraw模块
import os  # 导入os模块用于文件和目录操作

# 距离图片边缘的距离(留多少白边)
bianju = 10  
# 留白线的粗细(剪切边的粗细)
bianju2 = 2  

def detect_edges(image):
    """
    检测图像的边缘。如果像素透明,则标记为边缘。
    :param image: 输入的图像
    :return: 包含边缘信息的图像
    """
    # 如果图像不是RGBA模式,将其转换为RGBA模式
    if image.mode != 'RGBA':
        image = image.convert('RGBA')
    
    width, height = image.size  # 获取图像的宽度和高度
    edges = Image.new('L', (width, height), 0)  # 创建一个新的灰度图像来存储边缘信息,初始值为0(黑色)
    draw = ImageDraw.Draw(edges)  # 创建一个ImageDraw对象用于绘制
    
    pixels = image.load()  # 加载图像的像素数据
    for y in range(1, height - 1):  # 遍历图像的每一行,除了第一行和最后一行
        for x in range(1, width - 1):  # 遍历图像的每一列,除了第一列和最后一列
            r, g, b, a = pixels[x, y]  # 获取当前像素的RGBA值
            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)  # 创建一个新的灰度图像来存储扩展后的边缘信息,初始值为0(黑色)
    draw = ImageDraw.Draw(expanded_edges)  # 创建一个ImageDraw对象用于绘制
    
    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图像,并将结果保存到输出文件夹中。
    :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"):  # 只处理PNG文件
            image_path = os.path.join(input_folder, filename)  # 获取图像的完整路径
            image = Image.open(image_path).convert('RGBA')  # 打开图像并转换为RGBA模式
            
            # 检测图像的边缘
            edges = detect_edges(image)
            
            # 扩展边缘像素,扩展距离为bianju
            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()  # 加载最终结果的像素数据
            for y in range(1, final_result.height - 1):  # 遍历每一行,除了第一行和最后一行
                for x in range(1, final_result.width - 1):  # 遍历每一列,除了第一列和最后一列
                    r, g, b, a = pixels[x, y]  # 获取当前像素的RGBA值
                    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.line([(x, y), (x-1, y)], fill=(0, 0, 0), width=bianju2)  # 在透明侧绘制水平黑线
                            draw.line([(x, y), (x, y-1)], fill=(0, 0, 0), width=bianju2)  # 在透明侧绘制垂直黑线
                            break  # 跳出循环
            # 将临时图像与最终结果合成
            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'\png'
    output_folder =path+r'\234'
    os.makedirs(output_folder,exist_ok=True)
    process_images(input_folder, output_folder)

两个边距/粗细的对比

描边作品展示:

1、因为每个图案大小不同,所以描边粗细显示不同

2、透明图已经切过白边,图案顶天立地最大化,下次制作剪纸图,切边从0改成20,确保留边外轮廓都能显示出来。

3、设置的边距、粗细数字越大,检测边缘的数量越多,所以生成图案比较慢。

4、虚线边缘可能还是要用PS来制作(Python无法判断间隔线,因为边缘不是直线,算不了间隔。)

思路:用UIBOT自动处理每一张图片,制作留白边的虚线线条。但是这样时间很长,也不像Python可以控制白边的粗细,剪切黑线的粗细。

相关文章:

  • 蓝桥23省赛——接龙数列
  • Spring Boot 实现文件秒传功能
  • 小程序28-事件传参-data-*自定义数据
  • 自然语言处理(25:(终章Attention 1.)Attention的结构​)
  • Prometheus operator怎么添加targets和告警规则
  • 模拟实现线程池
  • 快速排序求第k小的数
  • C-RAN(Cloud-Radio Access Network,云化无线接入网)
  • Moo0 VideoResizer,简单高效压缩视频!
  • HDFS的shell命令
  • 第五节 空间命名作用域、sys模块、argparse模块、正则表达式
  • sublime text快捷键以及常见使用技巧
  • Linux统计Nginx日志
  • AI知识补全(十四):零样本学习与少样本学习是什么?
  • SpringIoC和DI
  • Debian/Ubuntu的networking的`/etc/network/interfaces`配置文件,如何禁用ipv6的route路由网关?
  • nvidia 各 GPU 架构匹配的 CUDA arch 和 CUDA gencode
  • 边缘检测技术现状初探1
  • Java全栈面试宝典:线程机制与Spring IOC容器深度解析
  • 167. 两数之和 II - 输入有序数组 leetcode
  • 重庆网站优化排名/中国没有限制的搜索引擎
  • 怎么查网站是那个公司做的/百度网盘网页
  • wordpress中文网站模板/广州网站建设工作室
  • 网站建设的目标有哪些/免费b站推广软件
  • 苏州园区人才网/宁波seo推广优化
  • html怎么制作动态网站/今日新闻事件