【教学类-102-19】蝴蝶三色图作品1——卡纸蝴蝶“原始比例图”(滴颜料按压对称花纹、A4横版最大号22.85CM,统一最大长宽背景,横竖等比例转换)

背景需求:

前期做了18次实验,基本实现了三色图三线的各种变化效果和16种图纸大小的批量导入

今天开始制作具体可用的学具——黑卡纸蝴蝶(滴颜料按压对撑颜色)

【教学类-102-11】蝴蝶外轮廓01——Python对黑白图片进行PS填充三种颜色+图案描边+图案填充白色+制作1图2图6图24图-CSDN博客文章浏览阅读1.1k次,点赞27次,收藏10次。【教学类-102-11】蝴蝶外轮廓01——Python对黑白图片进行PS填充三种颜色+图案描边+图案填充白色+制作1图2图6图24图 https://blog.csdn.net/reasonsummer/article/details/147234191?sharetype=blogdetail&sharerId=147234191&sharerefer=PC&sharesource=reasonsummer&spm=1011.2480.3001.8118

【教学类-102-12】蝴蝶外轮廓02——Python对黑白图片进行PS填充三种颜色+图案黑色描边(RBG160-250)+内部图案填充白色+制作1图2图6图24图_python操作ps-CSDN博客文章浏览阅读834次,点赞27次,收藏17次。【教学类-102-12】蝴蝶外轮廓02——Python对黑白图片进行PS填充三种颜色+图案黑色描边(RBG160-250)+内部图案填充白色+制作1图2图6图24图_python操作ps https://blog.csdn.net/reasonsummer/article/details/147256932?spm=1011.2415.3001.5331

1、黑色底纹的彩笔图案看不清楚

幼儿使用时,因为滴颜料按压,制作速度很快,大部分时间都是等颜料干透,所以我搭档就让他们先在卡纸上画对称图案,最后在滴颜料。(磨时间)

但是黑色卡纸上画彩色笔,看的不清楚。黑卡纸主要是为了衬托颜料的色彩。

2、折叠中线有误差

为了按压颜料,需要幼儿自己尝试对称折叠蝴蝶。卡纸比较硬,幼儿折叠后大致对位,但并不是很精准。

所以我想制作白色卡纸的蝴蝶,上面有折痕线,增加幼儿对折的精准度。

代码展示

'''
优化版
剪纸外轮廓描边虚线制作(黑点虚线)沿线剪——最终稳定版
将图片变成三色(透明、黑色、蓝色)或黑白色也可以
先把255白背景图片背景部分白色放大,然后(蝴蝶)做成透明图,及点状虚线,透明\切边\统一大小,保存1图2图4图24图,虚线与上下左右有空隙
黑线在透明与非透明交界线上,透明部分5磅,非透明不放呢5磅,
将非透明部分改成纯白色,没有任何灰色。
将三色图的外轮廓和内部花纹边线都显示出来。
三种线(花纹线、轮廓线、点状虚线)都可以单独设置颜色灰度和粗细。
竖版图(瓶子都是竖长条,尝试获取所有图片的最大长宽,制作来统一背景图),再插入竖版1图2图4图8图
选择1,获取统一图大小,修改WORD里面单元格样式。
选择2,把统一图做到WORD多图内(横板8种,竖版8种))
将竖图选择高的部分转化成宽度,进行文件名标注.便于按照图片本体宽度从大到小排列
再图片上添加中线虚线,便于对折。对称剪。
扩大描边,减少弯曲度,降低裁剪难度
点状虚线从灰色变成黑色,点子直径更大

样式1:滴颜料对称蝴蝶


deepseek,阿夏
20250425
'''
from PIL import Image, ImageDraw
import os
import math
x=int(input('1.统一图,2、多图\n'))

print('------0、基本信息-----')
# 主路径
path = r'C:\Users\jg2yXRZ\OneDrive\桌面\20250401边缘线剪纸'
# path=r'D:\图片\20240614蛋筒彩蛋

# 图片夹名称
a='15'
b='蝴蝶三色'
c='实线花纹白色图'

# 保存
all=path+fr'\{a}_10{b}合并图'

# 参数设置

# 1、内部花纹框
# 花纹边框颜色((内部)
cchw=255
# 调整蓝色区域边框宽度(像素)
blue_width = 4 

# 2、轮廓线
# 轮廓线黑线边框颜色(中间150,150,150)
ccn=0
# 轮廓线的宽度
mb_border_width = 10  # 黑边宽度(像素)
w=int(mb_border_width/2)  # 内5外5

# 3、点状虚线裁剪边
# 点状虚线边框颜色(外边)
ccw=150
# 白色描边宽度(像素)轮廓线外层
white_border_width = 40
# 黑点直径(像素)
dot_size = 10
 # # 黑点间距(像素)增加间距确保均匀分布  
dot_spacing = dot_size * 2

# 4、裁剪时不保留额外透明边距
transparent_edge = 0  # 裁剪时不保留额外透明边距

# 5、画布尺寸放大
target_width = 2000     # 统一宽度
target_height =target_width    # 统一高度
background_expand = 1000 # 白色背景放大尺寸

# 6、添加中线虚线(折痕)

# Parameters for center line


# 中线参数
xxx=180# 颜色
total_line_width = 10  # 总宽度10磅
left_width = int(total_line_width)/2       # 左边5磅
right_width = left_width     # 右边5磅
# line_width = 10  # 线条粗细
dash_length = 30  # 黑线段
gap_length = 30  # 白线段

# 定义文件夹路径
in_folder = os.path.join(path,f'{a}_01{b}白背景')  # 原始图片(白背景)
big_folder = os.path.join(path, f'{a}_02{b}{c}放大背景')  # 放大背景输出
transparent_folder = os.path.join(path, f'{a}_03{b}{c}透明背景')  # 透明背景输出
output_folder = os.path.join(path, f'{a}_04{b}{c}黑边轮廓')  # 最终输出
dotput_folder = os.path.join(path, f'{a}_05{b}{c}黑边点虚线轮廓')  # 最终输出
input_folder = output_folder  # 原始图片文件夹
cropped_folder = os.path.join(path,f'{a}_06{b}{c}切边') # 裁剪后的透明图片
final_folder  = os.path.join(path,f'{a}_07{b}{c}切边统一图')
center_line_folder = os.path.join(path, f'{a}_08{b}{c}中线图')


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

# 灰线深浅测试
# for cr3 in range(cchw,cchw+10,10):
      # 黑色边框颜色# 灰色
if x==1:
    #   中线(内)    
    rrw=ggw=bbw=ccw
    rrn=ggn=bbn=ccn
    rrh=ggh=bbh=cchw
    rrx=ggx=bbx=xxx
    # rrn,ggn,bbn=ccn,ccn,ccn
    # # 花纹边框颜色# 灰色
    # rrh,ggh,bbh=cchw,cchw,cchw 

    print('------1、白色PNG背景放大一点-----')
    # 遍历输入文件夹中的所有PNG文件
    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
                
                # 创建新画布(长宽各+200,白色背景)
                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)

    print('------2、白色PNG背景变成透明-----')
    def process_image_to_transparent(file_path):
        img = Image.open(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))
            elif item[0] == 254 and item[1] == 255 and item[2] == 255:
                new_data.append((254, 255, 255, 0))
            else:
                new_data.append(item)

        img.putdata(new_data)
        return img

    print("正在转换白背景为透明背景...")
    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)
            processed_image = process_image_to_transparent(input_file_path)
            processed_image.save(output_file_path)
            print(f"已处理: {file_name}")


    print('------3、添加双色不同宽度实线轮廓-----')

    def convert_to_white(image):
        """将所有非透明像素强制转换为纯白色,并确保完全透明像素为(0,0,0,0)"""
        img = image.convert("RGBA")
        datas = img.getdata()
        
        new_data = []
        for item in datas:
            if item[3] > 0:  # 不透明像素
                new_data.append((255, 255, 255, 255))  # 纯白
            else:
                new_data.append((0, 0, 0, 0))  # 完全透明
        img.putdata(new_data)
        return img

    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:  # 不透明像素
                    for dx, dy in [(-1,0),(1,0),(0,-1),(0,1)]:  # 4邻域检查
                        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 create_border_mask(edge_pixels, width, height, border_width):
        """创建指定宽度的边框遮罩"""
        border_pixels = set()
        w = border_width // 2  # 半径
        
        for x, y in edge_pixels:
            # 创建圆形画笔效果
            for dy in range(-w, w+1):
                for dx in range(-w, w+1):
                    nx, ny = x+dx, y+dy
                    if 0 <= nx < width and 0 <= ny < height:
                        dist = (dx**2 + dy**2)**0.5
                        if dist <= w:
                            border_pixels.add((nx, ny))
        
        return border_pixels

    def draw_dual_width_border(image, normal_border_pixels, cyan_border_pixels):
        """绘制不同宽度的双色边框"""
        border_layer = Image.new('RGBA', image.size, (0, 0, 0, 0))
        pixels = border_layer.load()    

    # 
        # 先绘制较宽的普通边框 (10磅/13像素)
        for x, y in normal_border_pixels:
            pixels[x, y] = (rrn, ggn, bbn, 255)  # 普通边框颜色
        
        # 再绘制较窄的蓝色区域边框 (6磅/8像素),这会覆盖重叠部分
        for x, y in cyan_border_pixels:
            pixels[x, y] = (rrh,ggh,bbh, 255)  # 蓝色部分边框颜色
            
        return border_layer

    def add_dual_width_border(input_path, output_path):
        """处理单个图像,添加不同宽度的双色边框"""
        original = Image.open(input_path).convert('RGBA')
        width, height = original.size
        
        # 0. 首先识别原图中的(0,255,255)区域边界
        original_pixels = original.load()
        cyan_edges = set()
        
        for y in range(height):
            for x in range(width):
                if original_pixels[x, y][3] > 0:  # 不透明像素
                    # 检查是否是(0,255,255)
                    if original_pixels[x, y][0] == 0 and original_pixels[x, y][1] == 255 and original_pixels[x, y][2] == 255:
                        # 检查4邻域是否有非(0,255,255)的不透明像素
                        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 original_pixels[nx, ny][3] > 0 and not (
                                    original_pixels[nx, ny][0] == 0 and 
                                    original_pixels[nx, ny][1] == 255 and 
                                    original_pixels[nx, ny][2] == 255):
                                    cyan_edges.add((x, y))
                                    break
        
        # 1. 将所有非透明像素转为纯白色
        white_image = convert_to_white(original)
        
        # 2. 获取透明与不透明的边缘
        edge_pixels = get_edge_pixels(white_image)
        
        # # 3. 创建不同宽度的边框区域
        # mb_border_width = 20 # 10磅 ≈ 13像素
        # blue_width = 8    # 6磅 ≈ 8像素
        
        normal_border_pixels = create_border_mask(edge_pixels, width, height, mb_border_width)
        cyan_border_pixels = create_border_mask(list(cyan_edges), width, height, blue_width)
        
        # 4. 绘制不同宽度的双色边框
        border_layer = draw_dual_width_border(white_image, normal_border_pixels, cyan_border_pixels)
        
        # 5. 合成结果
        result = Image.alpha_composite(white_image, border_layer)
        
        # 6. 最终清理
        result_data = result.getdata()
        final_data = []
        for item in result_data:
            if item[3] == 0:  # 透明
                final_data.append((0, 0, 0, 0))
            elif item[:3] == (rrn, ggn, bbn):  # 蓝色部分边框
                final_data.append((rrn, ggn, bbn, 255))
            elif item[:3] == (rrh,ggh,bbh):  # 普通边框
                final_data.append((rrh,ggh,bbh, 255))
            else:  # 白色
                final_data.append((255, 255, 255, 255))
        result.putdata(final_data)
        
        result.save(output_path, format='PNG')
        print(f"已添加不同宽度双色边框: {os.path.basename(input_path)}")

    # # 定义两种边框颜色
        # 黑色边框颜色# 灰色
    rrn,ggn,bbn=ccn,ccn,ccn
    # 花纹边框颜色# 灰色
    rrh,ggh,bbh=cchw,cchw,cchw  
    # # 蓝色部分(原(0,255,255)区域)边框颜色 (6磅宽)
    # rrn, ggn, bbn = 255, 0, 0  # 红色
    # # 其他部分边框颜色 (10磅宽)
    # cch, cch, cch = 0, 0, 0  # 黑色

    # 处理所有透明背景图片
    for file_name in os.listdir(transparent_folder):
        if file_name.lower().endswith('.png'):
            input_path = os.path.join(transparent_folder, file_name)
            output_path = os.path.join(output_folder, file_name)
            add_dual_width_border(input_path, output_path)
            
    print("\n所有处理完成!")



    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 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

阿夏reasonsummer

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

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

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

打赏作者

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

抵扣说明:

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

余额充值