背景需求:
制作儿童简易立体书贺卡
【教学类-83-01】20241215立体书三角嘴1.0——小鸡(正菱形嘴)-CSDN博客文章浏览阅读1k次,点赞24次,收藏18次。【教学类-83-01】20241215立体书三角嘴1.0——小鸡(正菱形嘴)https://blog.csdn.net/reasonsummer/article/details/143987230【教学类-83-02】20241214立体书三角嘴2.0——青蛙(扁菱形嘴)-CSDN博客文章浏览阅读672次,点赞30次,收藏14次。【教学类-83-02】20241214立体书三角嘴2.0——青蛙(长扁菱形)https://blog.csdn.net/reasonsummer/article/details/144510078
2025年是蛇年,制作一款立体书盘旋蛇
网上下载蚊香图
PS修图
蛇身体正面,添加图案和黏贴位置
变透明色PNG
蛇身体反面,水平翻转透明
去掉白边最大化,保留黑线和透明部分,然后统一大小(PS可能两图会有细微高度差异)
#
'''
小蛇。去边,(保留黑线和透明部分)
星火讯飞、阿夏
20240817
'''
import os
from PIL import Image
import logging
# 配置日志记录
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
path = r'D:\20241122青蛙小鸡\03小蛇'
folder_path = os.path.join(path, '00修图')
output_folder = os.path.join(path, '01切边图')
os.makedirs(output_folder, exist_ok=True)
# 留一点白边
white_edge = 0 # 设置一个合适的白边值,例如10像素
def find_non_white_pixel(image):
width, height = image.size
left, right, top, bottom = width, 0, height, 0
for y in range(height):
for x in range(width):
r, g, b, a = image.getpixel((x, y))[:4] # 确保只取前四个值
if r != 255 or g != 255 or b != 255 :
if x < left:
left = x
if x > right:
right = x
if y < top:
top = y
if y > bottom:
bottom = y
return left, right, top, bottom
def crop_image(image, left, right, top, bottom):
# 确保裁剪区域不超出图像边界
left = max(0, left - white_edge)
right = min(image.width - 1, right + white_edge)
top = max(0, top - white_edge)
bottom = min(image.height - 1, bottom + white_edge)
return image.crop((left, top, right, bottom))
for file_name in os.listdir(folder_path):
if file_name.endswith(".png"):
input_path = os.path.join(folder_path, file_name)
try:
with Image.open(input_path).convert('RGBA') as image: # 确保图像以RGBA模式打开
left, right, top, bottom = find_non_white_pixel(image)
cropped_image = crop_image(image, left, right, top, bottom)
output_path = os.path.join(output_folder, file_name)
cropped_image.save(output_path)
logging.info(f"Processed {file_name} successfully.")
except Exception as e:
logging.error(f"Failed to process {file_name}: {e}")
# 提取最大宽度的那张图片的尺寸
def get_max_width_and_height(fold_path):
max_width = 0
max_height = 0
for file_name in os.listdir(fold_path):
if file_name.endswith(".png") or file_name.endswith(".jpg") or file_name.endswith(".jpeg"):
file_path = os.path.join(fold_path, file_name)
img = Image.open(file_path)
width, height = img.size
if width > max_width:
max_width = width
max_height = height
return max_width, max_height
fold_path = output_folder
max_width, max_height = get_max_width_and_height(fold_path)
print("最大宽度:", max_width)
print("最大高度:", max_height)
# 最大宽度: 769
# 最大高度: 803
# 自定义长宽
# 统一所有图片大小
def resize_image(image_path, output_folder, new_image_name):
img = Image.open(image_path).convert('RGBA')
new_img = Image.new('RGBA', (max_width, max_height), (255, 255, 255, 0)) # 创建一个全透明的背景
new_img.paste(img, (0, 0), img) # 粘贴原图到新图上,保持透明部分
new_img.save(os.path.join(output_folder, new_image_name))
for file in os.listdir(output_folder):
if file.endswith('.png'):
input_image_path = os.path.join(output_folder, file)
new_image_name = f"{file[:-4]}.png" # 避免覆盖原文件
resize_image(input_image_path, output_folder, new_image_name)
# ```
# ### 主要改动点:
# 1. **确保裁剪区域不超出图像边界**:在`crop_image`函数中添加了对裁剪区域的边界检查,确保不会超出图像的实际尺寸。
# 2. **日志信息**:增加了更多的日志信息,以便更好地调试和跟踪处理过程。
# 3. **避免覆盖原文件**:在重命名重设大小的图片时,使用不同的文件名以避免覆盖原文件。
二、制作斑点纹理
本来我希望用AI生成蛇的花纹图案,但是画了半天,并没有适合的圆形、线条纹样,所以我还是想用AI制作花纹图纸。
# 制作小蛇的斑点-行列(单独测试))
# 星火讯飞,阿夏
# 2024年12月18日
from PIL import Image, ImageDraw
import math
# 画布尺寸
canvas_size = (769,803)
# 用户输入的圆的数量和间距
num_circles_per_row = 10
# int(input("请输入每行圆的数量: "))
num_circles_per_col = 11
# int(input("请输入每列圆的数量: "))
spacing = 5
# int(input("请输入圆的间距: "))
width, height = canvas_size
# 计算最大可能的直径
max_diameter = min((width - (num_circles_per_row - 1) * spacing) // num_circles_per_row,
(height - (num_circles_per_col - 1) * spacing) // num_circles_per_col)
print(f"最大直径: {max_diameter}")
# 圆圈线条宽度
w=5
# 创建一个白色背景的图像
image = Image.new('RGB', canvas_size, 'white')
draw = ImageDraw.Draw(image)
# 计算起始位置,使圆在画布中居中
start_x = (canvas_size[0] - (num_circles_per_row * max_diameter + (num_circles_per_row - 1) * spacing)) // 2
start_y = (canvas_size[1] - (num_circles_per_col * max_diameter + (num_circles_per_col - 1) * spacing)) // 2
# 绘制圆形
for i in range(num_circles_per_row):
for j in range(num_circles_per_col):
x = start_x + i * (max_diameter + spacing)
y = start_y + j * (max_diameter + spacing)
draw.ellipse([(x, y), (x + max_diameter, y + max_diameter)], outline='black', width=w)
path = r'D:\20241122青蛙小鸡\03小蛇'
# 保存图像
image.save(path + r'\123.png')
# 这个脚本会逐步增加间距,直到每行和每列的圆的数量都至少为10个。最终的间距、每行和每列的圆的数量以及总圆的数量都会打印出来。
感觉花纹黑色与蛇的黑色很相近,我想把花纹圆形变成灰色的
做一个参数遍历(颜色改成lightgray浅灰)
# 制作小蛇的斑点-行列(遍历测试)
# 星火讯飞,阿夏
# 2024年12月18日
from PIL import Image, ImageDraw
import math,os
# (单独测试))
# # 用户输入的圆的数量和间距
# num_circles_per_row = 10
# # int(input("请输入每行圆的数量: "))
# num_circles_per_col = 11
# # int(input("请输入每列圆的数量: "))
# spacing = 5
# # int(input("请输入圆的间距: "))
# 遍历测试
for num_circles_per_row in range(5,20):
num_circles_per_col =num_circles_per_row # 行5个,列也是5个
for spacing in range(5,50,5):
# 画布尺寸
canvas_size = (769,803)
width, height = canvas_size
# 计算最大可能的直径
max_diameter = min((width - (num_circles_per_row - 1) * spacing) // num_circles_per_row,
(height - (num_circles_per_col - 1) * spacing) // num_circles_per_col)
print(f"最大直径: {max_diameter}")
# 圆圈线条宽度
w=5
# 创建一个白色背景的图像
image = Image.new('RGB', canvas_size, 'white')
draw = ImageDraw.Draw(image)
# 计算起始位置,使圆在画布中居中
start_x = (canvas_size[0] - (num_circles_per_row * max_diameter + (num_circles_per_row - 1) * spacing)) // 2
start_y = (canvas_size[1] - (num_circles_per_col * max_diameter + (num_circles_per_col - 1) * spacing)) // 2
# 绘制圆形
for i in range(num_circles_per_row):
for j in range(num_circles_per_col):
x = start_x + i * (max_diameter + spacing)
y = start_y + j * (max_diameter + spacing)
draw.ellipse([(x, y), (x + max_diameter, y + max_diameter)], outline='lightgray', width=w)
path = r'D:\20241122青蛙小鸡\03小蛇'
t_folder=path+r'\02圆点图'
os.makedirs(t_folder,exist_ok=True)
# 保存图像
image.save(t_folder + fr'\行{num_circles_per_row}_列{num_circles_per_col}_行距{spacing}.png')
然后制作左右对称两图
'''
# 目的:小蛇的两张图与点子拼图(正反图)
# 作者:阿夏
# 时间:2024年12月18日17:27
'''
from PIL import Image
import os
# 定义路径
path = r'D:\20241122青蛙小鸡\03小蛇'
folder1 = path + r'\01切边图'
folder2 = path + r'\02圆点图'
c=['正','反']
for i in range(len(c)):
folder3 = path + fr'\03小蛇合并图{c[i]}面'
# 确保输出文件夹存在
os.makedirs(folder3, exist_ok=True)
# 从folder1读取第一张图片
first_image_path = os.path.join(folder1, os.listdir(folder1)[i])
first_image = Image.open(first_image_path).convert("RGBA")
# 获取第一张图片的中心点
width, height = first_image.size
center_x, center_y = width // 2, height // 2
# 遍历folder2中的每张图片
for image_name in os.listdir(folder2):
second_image_path = os.path.join(folder2, image_name)
second_image = Image.open(second_image_path).convert("RGBA")
# 创建一个足够大的新空白图像来容纳两张图片
new_width = max(width, second_image.width)
new_height = max(height, second_image.height)
combined_image = Image.new('RGBA', (new_width, new_height))
# 将第二张图片粘贴到新图像的中心
combined_image.paste(second_image, ((new_width - second_image.width) // 2, (new_height - second_image.height) // 2), mask=second_image)
# 使用其alpha通道作为掩码,将第一张图片粘贴到新图像的中心
combined_image.paste(first_image, ((new_width - width) // 2, (new_height - height) // 2), mask=first_image)
# 将组合后的图像保存到folder3
combined_image.save(os.path.join(folder3, f"{image_name}"))
print("Images have been combined and saved to folder3.")
# # 移动到一起
# # Python,读取123文件下所有子文件夹里面的图片,合并在234文件内,如果有重名的,在文件名后面添加数字(递增)
# import os
# import shutil
# # 源目录和目标目录
# folder5 = folder3+fr'\02合并'
# # 确保目标目录存在
# if not os.path.exists(folder5):
# os.makedirs(folder5)
# # 遍历源目录下的所有子目录和文件
# for root, dirs, files in os.walk(folder3):
# for file in files:
# # 检查文件是否为图片
# if file.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp', '.gif')):
# src_file_path = os.path.join(root, file)
# dest_file_path = os.path.join(folder5, file)
# # 如果目标文件已存在,添加数字后缀
# counter = 1
# while os.path.exists(dest_file_path):
# name, ext = os.path.splitext(file)
# new_file_name = f"{name}_{counter:03}{ext}"
# dest_file_path = os.path.join(folder5, new_file_name)
# counter += 1
# # 复制文件到目标目录
# # shutil.copy2(src_file_path, dest_file_path)
# # 剪切移动文件到目标目录
# shutil.move(src_file_path, dest_file_path)
# print(f"Copied {src_file_path} to {dest_file_path}")
# shutil.rmtree(folder3 +fr'\01分类')
超过15个点子,间距大于35就会让点子变得很小。没法点子涂色。所以把,圆点数量改成5个到14个(原来是5-19个)
这下只有90图
第1次,正图
第2次,正图
正面图布局一样.
第1次,反面图(与正面图相同)
第2次,反面图(正面图左右翻转)
因为是圆形,而且圆点图本身就是中心点对撑,
所以第二套图片的圆点是否水平翻转都不明显(如果是其他的图非对称图案,需要考虑水平翻转。)
为了能够拉长,动物进行了290度旋转
再用PS提取两图中的灰色,反选填充白色,把黏贴底位置左右翻转
最后一步图片拼合
WORD模版
初步效果
代码展示
# '''
# 蛇身体、蛇背景打包PDF
# 作者:阿夏
# 时间:2024年12月18日17:27
# '''
import os
import time
import shutil
from docx import Document
from docx.shared import Cm, Pt, Inches, RGBColor
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
from docx.oxml.ns import qn
from PyPDF2 import PdfFileMerger, PdfFileReader
from docxtpl import DocxTemplate
import pandas as pd
import os,random
from docx import Document
from docx.shared import Cm
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
import time
from PIL import Image
print('----------第1步:提取所有的幼儿照片的路径------------')
# 读取123文件夹下的所有图片
path = r'D:\20241122青蛙小鸡'
path1=path+r'\03小蛇'
folder1= os.path.join(path1, '03小蛇合并图反面') # 封面
folder2= os.path.join(path1, '03小蛇合并图正面') # 青蛙与池塘合并图
folder3= os.path.join(path1, '04黏贴位置') # 封面
folder_files1 = [os.path.join(folder1, f) for f in os.listdir(folder1) if f.endswith('.jpg') or f.endswith('.png')]
folder_files2 = [os.path.join(folder2, f) for f in os.listdir(folder2) if f.endswith('.jpg') or f.endswith('.png')]
folder_files3 = [os.path.join(folder3, f) for f in os.listdir(folder3) if f.endswith('.jpg') or f.endswith('.png')]
# folder_files = random.sample(folder_files, len(folder_files))
# print(folder_files)
# 创建临时文件夹
new_folder = path+r'\零时文件夹'
os.makedirs(new_folder, exist_ok=True)
# print('----------第3步:一张大茶壶,2个小茶杯 ------------')
for nn in range(0,int(len(folder_files1))): # 读取图片的全路径 的数量 31张
doc = Document(path+r'\立体书盘旋蛇.docx')
table = doc.tables[0] # 4567(8)行
f1=folder_files1[nn] # 封面的图片
# # 读取图片并垂直翻转
# image = Image.open(face)
# flipped_image = image.transpose(Image.FLIP_TOP_BOTTOM) # 垂直翻转
# # 保存翻转后的图片到临时文件
# temp_image_path = path + r'\temp_image.png'
# flipped_image.save(temp_image_path)
# 写入1张小图封面
run = doc.tables[0].cell(0, 0).paragraphs[0].add_run() # 图片位置 第一个表格的0 3 插入照片
run.add_picture(r'{}'.format(f1), width=Cm(9.8))# 以宽度为标准,确定高度,图片宽度(人工宽度,图案小一点,可以写文字)
table.cell(0, 0).paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER # 居中
f2=folder_files2[nn] # 青蛙的图片
# 写入1张大图-青蛙
run = doc.tables[0].cell(0,1).paragraphs[0].add_run() # 图片位置 第一个表格的0 3 插入照片
run.add_picture(r'{}'.format(f2), height=Cm(9.8)) # 图片高度(单元格高度)因为青蛙与背景合并成最大了,就用最高尺寸
table.cell(0,1).paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER # 居中
f3=folder_files3[0]
# 写入1张大图-青蛙
run = doc.tables[0].cell(1,0).paragraphs[0].add_run() # 图片位置 第一个表格的0 3 插入照片
run.add_picture(r'{}'.format(f3), height=Cm(9.8)) # 图片高度(单元格高度)因为青蛙与背景合并成最大了,就用最高尺寸
table.cell(1, 0).paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER # 居中
f4=folder_files3[1]
# 写入1张大图-青蛙
run = doc.tables[0].cell(1,1).paragraphs[0].add_run() # 图片位置 第一个表格的0 3 插入照片
run.add_picture(r'{}'.format(f4), height=Cm(9.8)) # 图片高度(单元格高度)因为青蛙与背景合并成最大了,就用最高尺寸
table.cell(1, 1).paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER # 居中
doc.save(new_folder+fr'\{nn:03d}.docx')
time.sleep(3)
print('----------第4步:把都有PDF合并为一个打印用PDF------------')
# 将10个docx转为PDF
import os
from docx2pdf import convert
from PyPDF2 import PdfFileMerger
pdf_output_path = path+fr"\盘旋蛇立体书封面({len(folder_files1)}人共{len(folder_files1)}份).pdf"
# 将所有DOCX文件转换为PDF
for docx_file in os.listdir(new_folder):
if docx_file.endswith('.docx'):
docx_path = os.path.join(new_folder, docx_file)
convert(docx_path, docx_path.replace('.docx', '.pdf'))
# 合并零时文件里所有PDF文件
merger = PdfFileMerger()
for pdf_file in os.listdir(new_folder):
if pdf_file.endswith('.pdf'):
pdf_path = os.path.join(new_folder, pdf_file)
merger.append(pdf_path)
time.sleep(2)
# 保存合并后的PDF文件
merger.write(pdf_output_path)
merger.close()
# 删除输出文件夹
shutil.rmtree(new_folder)
time.sleep(10)
第一款矩阵圆形的盘旋蛇就做好了,这一款主要用的图案是行列的空心圆
先打印测试能不能使用
制作封面小蛇(虽然图纸上看不到)
纯白色背景,卡通简笔画,蛇,正面,可爱,萌,涂色书,简单笔画,卡通,黑白轮廓线,黑白轮廓线、黑白轮廓线、未着色,幼儿插图,线条画,没有背景,没有颜色,黑白漫画线条艺术:,线描,空背景,粗轮廓,清晰的线条,矢量线。简单,大,