【教学类-18-05】20241118正方形手工纸(蒙德里安-风格派-红黄蓝黑白)
背景需求:
制作世界风景名画手工纸时,遇到蒙德里安格子画无法生成的问题。
【教学类-70-01】20241118通义万相生成“世界风景名画”手工纸(4款图片3种尺寸)-CSDN博客文章浏览阅读711次,点赞20次,收藏5次。【教学类-70-01】20241118通义万相生成“世界风景名画”手工纸(4款图片3种尺寸)https://blog.csdn.net/reasonsummer/article/details/143864132?sharetype=blogdetail&sharerId=143864132&sharerefer=PC&sharesource=reasonsummer&spm=1011.2480.3001.8118
我想用通义万相生成“蒙德里安风格”的方形图纸(做手工纸用)
但是生成出来的是颜色符合的斜线条图案,效果不佳
我想起以前做过一套蒙德里安黑白格子画
【教学类-18-04】20240508《蒙德里安“黑白格子画” 七款图案挑选》-CSDN博客文章浏览阅读1.5k次,点赞23次,收藏20次。【教学类-18-04】20240508《蒙德里安“黑白格子画” 七款图案挑选》https://blog.csdn.net/reasonsummer/article/details/142612773
在代码里找了找。发现了三款,其中红色框就是黑白格子画的模版
黄色框是等距的格子画
蓝色框才是随机出现格子,并延长的效果,就修改这个代码然后制作我想要的艺术家风格的手工纸——蒙德里安红黄蓝黑格子画
代码展示
'''
目的:蒙德里安(大小不规律格子)三原色(但是数量多会卡死,要反复生成几次)
作者:AI对话大师
时间:2024年11月18日
'''
from PIL import Image, ImageDraw
import random,os
# 几张
z=2000
# 几个框
k=4
# 矩形数量,如果8,就是四种颜色每种2个
s=8
for xx in range(z):
# 创建一个新的空白图片
width, height = 1500, 1500
min_rect_size = 200
image = Image.new('RGB', (width, height), color=(255, 255, 255))
draw = ImageDraw.Draw(image)
# 已放置的矩形列表
placed_rects = []
# 尝试放置多个不重叠的矩形
num_rects = s # 尝试放置的矩形数量
# 控制3个红、3个黄、3个蓝、3个黑
colors = [(255, 0, 0), (255, 0, 0), # 红色 (3次)
(255, 255, 0), (255, 255, 0), # 黄色 (3次)
(0, 0, 255), (0, 0, 255), # 蓝色 (3次)
(0, 0, 0), (0, 0, 0)] # 黑色 (3次)
# colors = [(255, 0, 0), (255, 0, 0), (255, 0, 0), # 红色 (3次)
# (255, 255, 0), (255, 255, 0), (255, 255, 0), # 黄色 (3次)
# (0, 0, 255), (0, 0, 255), (0, 0, 255), # 蓝色 (3次)
# (0, 0, 0), (0, 0, 0), (0, 0, 0)] # 黑色 (3次)
# colors = [(255, 0, 0), (255, 255, 0), (0, 0, 255), (0, 0, 0),(255, 255, 255)] # 颜色列表
# 左上角向左 左下角向左
def extend_line_to_boundary_left(start_x, start_y, direction_x, stop_color):
x = start_x
y = start_y
while 0 <= x <= width and image.getpixel((x, y)) != stop_color:
x += direction_x
return x
# 右上角向右 右下角向右
def extend_line_to_boundary_right(start_x, start_y, direction_x, stop_color, width, image):
x = start_x
y = start_y
while 0 <= x < width and image.getpixel((x, y)) != stop_color:
x += direction_x
return x
# 左上角向上 右上角向上
def extend_line_to_boundary_up(start_x, start_y, direction_y, stop_color, height, draw):
x = start_x
y = start_y
while 0 <= y < height:
try:
if draw.getpixel((x, y)) == stop_color:
break
except IndexError:
break
y += direction_y
return y
# 左下角向下 右下角向下
def extend_line_to_boundary_down(start_x, start_y, direction_y, stop_color, height, draw):
x = start_x
y = start_y
while 0 <= y < height:
try:
if draw.getpixel((x, y)) == stop_color:
break
except IndexError:
break
y += direction_y
return y
for _ in range(num_rects):
success = False
while not success:
# 随机生成矩形位置和大小
left = random.randint(0, width - min_rect_size)
top = random.randint(0, height - min_rect_size)
right = left + random.randint(min_rect_size, width - left)
bottom = top + random.randint(min_rect_size, height - top)
# 检查新矩形是否与已放置的矩形重叠
for rect in placed_rects:
if left < rect[2] and right > rect[0] and top < rect[3] and bottom > rect[1]:
# 如果重叠,则重新生成新的矩形位置和大小
break
else:
# 如果没有重叠,则绘制矩形并添加到已放置的矩形列表
# color = random.choice(colors)
# color = random.sample(colors,1)
color = colors[_]
outline_color = (0, 0, 0) # 外框线颜色为黑色
outline_width = 30 # 外框线宽度
draw.rectangle([(left, top), (right, bottom)], fill=color, outline=(0, 0, 0),width=outline_width)
placed_rects.append((left, top, right, bottom))
success = True
# # 延长矩形边界至画布边框
# # 延长矩形边界至画布边框
# draw.line([(left, top), (0, top)], fill=outline_color, width=outline_width)
# draw.line([(right, top), (width, top)], fill=outline_color, width=outline_width)
# draw.line([(right, bottom), (width, bottom)], fill=outline_color, width=outline_width)
# draw.line([(left, bottom), (0, bottom)], fill=outline_color, width=outline_width)
# draw.line([(left, top), (left, 0)], fill=outline_color, width=outline_width)
# draw.line([(right, top), (right, 0)], fill=outline_color, width=outline_width)
# draw.line([(right, bottom), (right, height)], fill=outline_color, width=outline_width)
# draw.line([(left, bottom), (left, height)], fill=outline_color, width=outline_width)
# 检测矩形右上角的坐标(right+1、top+15),向右侧水平延伸画一根黑色线条
# 检测矩形左下角的坐标(left-1、bottom-15),向下垂直延伸画一根黑色线条
y = extend_line_to_boundary_down(left - 1, bottom - 15, 1, outline_color, height, image)
draw.line([(left + 15, bottom - 15), (left + 15, y)], fill=outline_color, width=outline_width)
# # 检测矩形左上角的坐标(left-1、top+15),向上垂直延伸画一根黑色线条
y = extend_line_to_boundary_up(left-1, top+15, -1, outline_color, height, image)
draw.line([(left +15, top + 15), (left +15, y)], fill=outline_color, width=outline_width)
# 检测矩形左上角的坐标(left-1、top+15),向左侧水平延伸画一根黑色线条
x = extend_line_to_boundary_left(left -1, top + 15, -1, outline_color)
draw.line([(left - 1, top + 15), (x, top + 15)], fill=outline_color, width=outline_width)
# 检测矩形右上角的坐标(right+1、top+15),向上垂直延伸画一根黑色线条
y = extend_line_to_boundary_up(right + 1, top + 15, -1, outline_color, height, image)
draw.line([(right -15, top + 15), (right -15, y)], fill=outline_color, width=outline_width)
# 检测矩形左下角的坐标(left-1、top+15),向左侧水平延伸画一根黑色线条
x = extend_line_to_boundary_left(left -1, bottom - 15, -1, outline_color)
draw.line([(left - 1, bottom - 15), (x, bottom - 15)], fill=outline_color, width=outline_width)
# 检测矩形右上角的坐标(right+1、top+15),向右侧水平延伸画一根黑色线条
# 检测矩形左下角的坐标(left-1、bottom-15),向下垂直延伸画一根黑色线条
y = extend_line_to_boundary_down(left - 1, bottom - 15, 1, outline_color, height, image)
draw.line([(left + 15, bottom - 15), (left + 15, y)], fill=outline_color, width=outline_width)
x = extend_line_to_boundary_right(right + 1, top + 15, 1, outline_color, width, image)
draw.line([(right + 1, top + 15), (x, top + 15)], fill=outline_color, width=outline_width)
# 检测矩形右下角的坐标(right+1、bottom-15),向下垂直延伸画一根黑色线条
y = extend_line_to_boundary_down(right + 1, bottom - 15, 1, outline_color, height, image)
draw.line([(right - 15, bottom - 15), (right - 15, y)], fill=outline_color, width=outline_width)
# 检测矩形右下角的坐标(right+1、top+15),向右侧水平延伸画一根黑色线条
x = extend_line_to_boundary_right(right + 1, bottom - 15, 1, outline_color, width, image)
draw.line([(right + 1, bottom - 15), (x, bottom - 15)], fill=outline_color, width=outline_width)
# 显示图片(如果你使用的是图形界面环境)
# image.show()
new_path=r'C:\Users\jg2yXRZ\OneDrive\桌面\蒙德里安大小\彩色'
os.makedirs(new_path,exist_ok=True)
image.save(new_path+fr'\{xx:03}.png')
代码介绍:
虽然我需要2000张,但有时候生成几张就卡死了。
第1次
第2次
第3次
因为是随机生成矩形的位置,所以遇到一次矩形碰在一起的情况,程序就卡死了。
也就是每次只能生成十几张,然后移动到一个文件里,关闭程序再次运行程序,再获得十几张
人工筛选(粗线条不要)
我生成了502张图,手动筛选了,只留36张没有“粗黑线”的图片
都是8色(2红2黄2蓝2黑),水平线条和垂直线条有交错线,
最后做成{PDF手工纸的样式
素材准备
代码展示
'''
名画折纸1页1图、2图、6图、图片数量必须是6的倍数
AI对话大师,阿夏
2024年11月17日
'''
import random
import math
from PIL import Image, ImageDraw, ImageFont
import os
# 制作word
# 制作word
import os
from docx import Document
import os,time
from docx import Document
from docx.shared import Cm
from docx2pdf import convert
from PyPDF2 import PdfMerger
import shutil
from datetime import datetime
from PIL import Image
# 测试图片59张
path=r'D:\20241117名画'
# 范例图纸
names='04红黄蓝黑-风格派-蒙德里安36'
# D:\20241117名画\01海浪-浮世绘-葛饰北斋
input_path=path+fr'\{names}'
file_paths = [os.path.join(input_path, file) for file in os.listdir(input_path) if file.endswith('.png')]
# print(len(file_paths))
# 16:9图只有51张,所以总部需要102张,4:3图需要102张
# 三种模版尺寸 (1页1图、2图、6图)
mb=['1', '2','6']
# 1页1图19.54(大)和8.8(小)、1页2图14.17(大)和5.35(小)、1页6图9.4(大)
bg=[['00'],['01','04'],['00','01','10','11','20','21']]
size =[[[19.54,19.54]],[[14.17,14.17],[14.17,14.17]],[[9.4,9.4],[9.4,9.4],[9.4,9.4],[9.4,9.4],[9.4,9.4],[9.4,9.4]]]
for m in range(len(mb)): # 3种 m=0、1、2
# print(m)
pic_list_six= [file_paths[i:i+int(mb[m])] for i in range(0, len(file_paths),int(mb[m]))]
print(pic_list_six)
print(len(pic_list_six))
imagePath = path + r'\ls'
os.makedirs(imagePath, exist_ok=True)
for z in range(len(pic_list_six)):
# 6,3、1
# for x in range(len(pic_list_six[z])):
print(pic_list_six[z])
# doc = Document(path + fr'\1页{mb[m]}张.docx')
doc = Document(path + fr'\1页{mb[m]}张.docx')
table = doc.tables[0]
for i in range(len(bg[m])):
pp = int(bg[m][i][0])
qq = int(bg[m][i][1])
k = str(pic_list_six[z][i])
print(pp, qq, k)
cell = table.cell(pp, qq)
cell_paragraph = cell.paragraphs[0]
cell_paragraph.clear()
run = cell_paragraph.add_run()
run.add_picture(k, width=Cm(float(size[m][i][0])), height=Cm(float(size[m][i][1])))
cell_paragraph.alignment = 1 # 设置单元格中的文本居中
# 保存修改后的.docx文件
doc.save(imagePath + fr'\{z:02d}页.docx')
# # docx 文件另存为PDF文件
inputFile = imagePath + fr'\{z:02d}页.docx' # 要转换的文件:已存在
outputFile = imagePath + fr'\{z:02d}页.pdf' # 要生成的文件:不存在
convert(inputFile, outputFile)
time.sleep(2)
pdf_lst = [f for f in os.listdir(imagePath) if f.endswith('.pdf')]
pdf_lst = [os.path.join(imagePath, filename) for filename in pdf_lst]
pdf_lst.sort()
file_merger = PdfMerger()
for pdf in pdf_lst:
print(pdf)
file_merger.append(pdf)
# file_merger.write("C:/Users/jg2yXRZ/OneDrive/桌面/描字帖/(打印合集)大班A整页描字帖2乘5加表格-4名字-({}人).pdf".format(num))
file_merger.write(path+fr"\{names[0:-2]}-1页{mb[m]}图-手工纸大小{str(float(size[m][0][0]))}CM-打印{len(pic_list_six)}张-图片共{len(file_paths)}图.pdf")
time.sleep(3)
file_merger.close()
# # print('----------第5步:删除临时文件夹------------')
import shutil
shutil.rmtree(imagePath) #递归删除文件夹,即:删除非空文件夹