[Teaching-34-05] Jigsaw Puzzle (Digital Student Number 0X-Long Square Puzzle-Two-color Dark Gray and Light Gray) 3*3 grids (The theme of the middle class “Individualized Puzzle” is partial to art-art)

Portfolio

Background requirements

Difficulty: How to make the generated image have two colored numbers?

In the last “Student Number Puzzle 3*3” learning activity, it was found that puzzles 03, 04, 05, 06, 08, 09, 23, 26, and 28 had difficulties , teacher help. The ten-digit numbers all contain multiple arc structures, and children are at a loss for the multiple combinations of a large number of arc fragments (two numbers are both arc structures) and have no sticking. Finally, after the teacher pointed out or placed it correctly, the children glued it on. (This arc and this arc can be put together, but they are not actually in the correct position)

Therefore, the author hopes to express the two numbers of the student number in different grayscale colors (office printers do not have color ink)

Use dark gray for tens digits, and light gray for ones digits, so there is a clear distinction.

Difficulty: How to make the generated image have two colored numbers?

Refer to CSDN, modify the code, and realize the requirements

1. Imitate the source code of the Douyin short video system, and make a color verification code_Cloud Leopard Network Technology Blog-CSDN Blog

2. Use python to generate verification code pictures_Python generates verification code pictures_Heart of Wudaokou Blog-CSDN Blog

Code settings:

'''
Purpose: The two numbers of the student number puzzle have different colors (dark gray\light gray)
Author: Asha
Date: 2023-05-23 22:17'''


import random
import string
from random import choice, randint, randrange

from PIL import Image, ImageDraw, ImageFont


colour1=int(input('The color of the ten-digit number (100 dark gray)\
'))
colour2=int(input('the color of single-digit numbers (170 gray)\
'))
# 28 student numbers
num=[]
for x in range(1,29):
    num.append('d'%x)
print(num)

  
# Loop through 28 images
n=1
for x in range(len(num)):
    # Read each number in num
    res1="{}". format(num[x])
    print(res1)
    #25
    #26
    #27
    #28

    # Image size, number of numbers (for coordinates) background color
    size=[600,400] # image size
    characterNumber=2 # Several numbers randomly draw 2 numbers
    bgcolor=(255,255,255) # background color white
    imageTemp = Image.new('RGB', size, bgcolor)
    draw = ImageDraw.Draw(imageTemp)
    # text = selectedCharacters(characterNumber)

    # Text format
    text = res1
    font = ImageFont.truetype('c:\windows\fonts\arial.TTF', 350)
    width, height = draw. textsize(text, font)

    # # random character position (make sure the number is in the center)
    startX = -90
    widthEachCharater = width//characterNumber

    a=[colour1,colour2] # dark gray, medium gray
    for i in range(characterNumber):
        startX += widthEachCharater + 1
        # position = (startX, (size[1]-height)//2 + randint(-5,5))
        position = (startX,(size[1]-height)//7)
        g=b=r=a[i] # The first number RGB color is equal to dark gray# The second number RGB color is equal to the final meeting
        draw.text(xy=position, text=text[i], font=font, fill= (r,g,b)) # fill color
        

    # Fine-tune the pixel position to achieve the distorted effect
    imageFinal = Image.new('RGB', size, bgcolor)
    pixelsFinal = imageFinal. load()
    pixelsTemp = imageTemp. load()
    for y in range(size[1]):
        offset = randint(-1,0)
        for x in range(size[0]):
            newx = x + offset
            if newx>=size[0]:
                newx = size[0]-1
            elif newx<0:
                newx = 0
            pixelsFinal[newx,y] = pixelsTemp[x,y]

    imageFinal.save(r"C:\Users\jg2yXRZ\OneDrive\Desktop\Color Number\Student Number{}.jpg".format(' d'%n))
        
    n + =1

The effect of different gray levels

The first number RGB (100 100 100)

The second number RGB (170 170 170)

Sentiment:

On the basis of not being able to use color printing, make numbers, characters, and patterns of different grayscales to improve the efficiency of children’s puzzles

Code to directly generate student number puzzle – all codes

1. Path + create a folder and word template in advance

2. The format of the word template

Format of word template (QR code download)

3. After the three folders are completed (internal empty), you can also write an automatic new folder in the code

4. All codes (randomly scrambled) – (generate Chinese colorful cloud font)

'''
Item: 3*3-grid jigsaw puzzle of the student ID digital vector map, 1 page, 2 copies, horizontal version
Author: Asha
Date: April 20, 2023 at 21:47
'''

num=int(input('How many people are generated (28 people)\
'))
Number=int(input('randomly select several pictures (9)\
'))


print('----------Step 1: 19 PNG images of capital letters * cut 12 for each image----------------')
# Source code: https://blog.csdn.net/qq_34777982/article/details/125019068?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-1-125019068-blog-12962229 4.235^ v29^pc_relevant_default_base3 &spm=1001.2101.3001.4242.2 &utm_relevant_index=4
# Python cropping Jiugongge picture - the road to dream
import sys
import os
import random
import string
from random import choice, randint, randrange
from PIL import Image, ImageDraw, ImageFont

# Generate a two-digit number

xh=[]
for i in range(1,num + 1):
    xh.append('d'%i)
print(xh)
# ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25 ', '26', '27', '28']

colour1=int(input('The color of the ten-digit number (100 dark gray)\
'))
colour2=int(input('the color of single-digit numbers (170 gray)\
'))
# 28 student numbers


  
# Loop through 28 images
n=0
for x in range(len(xh)):
    # Read each number in num
    res1="{}". format(xh[x])
    print(res1)
    #25
    #26
    #27
    #28

    # Image size, number of numbers (for coordinates) background color
    size=[600,402] # image size
    characterNumber=2 # Several numbers randomly draw 2 numbers
    bgcolor=(255,255,255) # background color white
    imageTemp = Image.new('RGB', size, bgcolor)
    draw = ImageDraw.Draw(imageTemp)
    # text = selectedCharacters(characterNumber)

    # Text format
    text = res1
    font = ImageFont.truetype('c:\windows\fonts\STHUPO.TTF', 350) # Chinese amber
    # font = ImageFont.truetype('c:\windows\fonts\msyhbd.TTC', 350) # Microsoft Yahei
    width, height = draw. textsize(text, font)

    # # random character position (make sure the number is in the center)
    # Serial number of Chinese amber
    # startX = -105
    # widthEachCharater = width//characterNumber
    # Microsoft Yahei
    startX = -100
    widthEachCharater = width//characterNumber

    a=[colour1,colour2] # dark gray, medium gray
    for i in range(characterNumber):
        startX += widthEachCharater + 1
        # position = (startX, (size[1]-height)//2 + randint(-5,5))
        position = (startX,(size[1]-height)//3)
        g=b=r=a[i] # The first number RGB color is equal to dark gray# The second number RGB color is equal to the final meeting
        draw.text(xy=position, text=text[i], font=font, fill= (r,g,b)) # fill color
        

    # Fine-tune the pixel position to achieve the distorted effect
    imageFinal = Image.new('RGB', size, bgcolor)
    pixelsFinal = imageFinal. load()
    pixelsTemp = imageTemp. load()
    for y in range(size[1]):
        offset = randint(-1,0)
        for x in range(size[0]):
            newx = x + offset
            if newx>=size[0]:
                newx = size[0]-1
            elif newx<0:
                newx = 0
            pixelsFinal[newx,y] = pixelsTemp[x,y]

    imageFinal.save(r"C:\Users\jg2yXRZ\OneDrive\Desktop\Student Number Number Puzzle\Student Number Number Puzzle 0\{}.jpg".format(' d'%(n + 1)))
        
    n + =1

# Batch resize images
#Generate the image size in 0# 1146 # Change 687 to 600*400
from PIL import Image
import os

# Original folder path
original_folder = "C:/Users/jg2yXRZ/OneDrive/Desktop/Student Number Number Puzzle/Student Number Number Puzzle 0"
# save the new folder path
new_folder = "C:/Users/jg2yXRZ/OneDrive/Desktop/Student Number Number Puzzle/Student Number Number Puzzle"

# Loop through the images in the original folder
for filename in os.listdir(original_folder):
    img = Image.open(os.path.join(original_folder, filename))
    # change size
    img_resized = img.resize((600, 402)) #Here is the size you want to convert Two numbers can be divisible by 3
    # save to new folder
    img_resized.save(os.path.join(new_folder, filename))




file_root = r"C:\Users\jg2yXRZ\OneDrive\Desktop\Student Number Number Puzzle\Student Number Number Puzzle" #The file to put the picture to be cut
fileList = []
n = 0
# read file list
def read_bmp_file_list(path):
     for root, dirs, files in os. walk(path, topdown=False):
            for file in files:
                fileList.append(os.path.join(root, file))
#Start cutting picture 9 grids
def qie_tu(file_path):
    global
    im = Image.open(file_path)
    # Width and height of the image (original image size 1280 720)
    img_size = im.size
    print("The width and height of the small image are {}".format(img_size))
    # cut into 512X512
    x = 0
    y = 0
    w = 200 # How many items are listed? 600/3
    h = 134 # How many lines? 402/3
    for j in range(0,3):
        for i in range(0,3):
            #region = im.crop((x, y, x + w*i, y + h*j))
            print(x + w*i, y + h*j, x + w*i + w, y + h*j + h)
            region = im.crop((x + w*i, y + h*j,x + w*i + w, y + h*j + h))
            # file output location
            region.save(r"C:\Users\jg2yXRZ\OneDrive\Desktop\Student Number Number Puzzle\Student Number Number Puzzle 1\{name}.jpg".format(name=' d'%n))
            n=n+1
 
if __name__ == '__main__':
    read_bmp_file_list(file_root)
    for f in fileList:
        qie_tu(f)


# print('----------Step 2: Read the picture, write the template ----------------')
import os
from PIL import Image




print('----------Step 1: Extract image path ------------')

path=[]
pr="C:\Users\jg2yXRZ\OneDrive\Desktop\Student Number Number Puzzle\Student Number Number Puzzle 1"
# Filter: only keep images ending in png
imgs1 = os.listdir(pr)
for img1 in imgs1:
    if img1.endswith(".jpg"):
        path.append(pr + '' + img1)
# path to all images
print(path)
# 216 paths (18*12 images)
print(imgs1)



print('----------Step 2: Create a new temporary folder ------------')
# Create a new folder with "N copies of word and PDF"
os.mkdir(r'C:\Users\jg2yXRZ\OneDrive\Desktop\Student ID Number Puzzle\Zero Hour Word')


print('----------Step 3: Randomly select 9 pictures ------------')

import docx
from docx import Document
from docx.shared import Pt
from docx.shared import RGBColor
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
from docx.oxml.ns import qn
import random

import os,time
import docx
from docx import Document
from docx.shared import Inches,Cm,Pt
from docx.shared import RGBColor
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
from docx.oxml.ns import qn

from docxtpl import DocxTemplate
import pandas as pd
from docx2pdf import convert
from docx.shared import RGBColor


for nn in range(0,int(num/2)): #28/2 0-14
    
    doc = Document(r'C:\Users\jg2yXRZ\OneDrive\Desktop\Student Number Number Puzzle\Student Number Number Puzzle Template.docx')
# # make list
    
    # Extract pictures from the left picture list and the right picture list (12 pictures, maybe 5 to the left and 7 to the right)
    # Among the 24 items, 0 and 12 are a group, 1 of the 2 is randomly selected, 1 and 13 are a group, and one of the 2 is randomly selected... After drawing 12 pictures

    r=[]
    c=[]
    r.append(path[nn*18:nn*18 + 18]) # The first copy on the left,
    
    # r.append(path[nn*24:nn*24 + 24]) # Insert 12 consecutive pictures and 2 letters into the same A4
    
    # print(r)
    # Then read 12 in random order
    for a in r:
        for b in a:
            c.append(b)
    # print(c)
    # figures1=c[0:9] # The first 9 pictures are not repeated and shuffled
    # figures2=c[9:18] # The last 9 pictures are not repeated and shuffled

    figures1=random.sample(c[0:9],Number) # The first 9 pictures are not repeated
    figures2=random.sample(c[9:18],Number) # The last 9 pictures are not repeated

    # figures3=random.sample(c[12:18],Number) # The last 6 pictures are not repeated
    # figures4=random.sample(c[18:24],Number) # The last 6 pictures are not repeated
    
    # 9 + 9 non-repetitive images merged
    figures=figures1 + figures2
    # figures=figures1 + figures2 + figures3 + figures4
    print(figures)

    # A list of 2 student numbers
    xh2=xh[nn*2:nn*2 + 2]
    print(xh2)

    for z in range(2): # 5-line combined loop 2 times, two tables per page
              

        # Cell position 3*3 cells
        bg=[]
        # Do not write in the first 1 + 3 + 1 line, move from 4
        for x in range(5,8): # 3 rows Index 5 rows 6 rows 7 rows
            for y in range(0,3): # 3 columns index 0 column 1 column 2 columns
                    ww='{}{}'.format(x,y)
                    bg.append(ww)
        print(bg)




        table = doc. tables[z]

        for t in range(len(bg)): # 02
            pp=int(bg[t][0:1])
            qq=int(bg[t][1:2])
            # print(p)
            k=figures[z*9:z*9 + 9][t]

            print(pp,qq,k)
        
            # write picture
            run=doc.tables[z].cell(pp,qq).paragraphs[0].add_run() # insert the national flag in the second cell of the first table
            run.add_picture('{}'.format(k),width=Cm(4.68),height=Cm(2.98))
            # cell width 4.7 3
            table.cell(pp,qq).paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.LEFT #Center
         
        # The header of the first table
        title='Student number _____________ class: middle ____ class digital puzzle ({} number)'.format(xh2[z])
         # Write the serial number and zodiac name
        run=table.cell(0,0).paragraphs[0].add_run(title) # Enter the 0th graph pattern in cell 0,0 (row 1, column 1)
        run.font.name = '黑体'#Default Chinese color cloud font when inputting
        # run.font.size = Pt(46) #Input font size defaults to 30 and line break (one big card per page
        run.font.size = Pt(15) #Input font size defaults to 30 in one line (two copies per page)
        run.font.bold= True #Whether to bold
        run.font.color.rgb = RGBColor(200,200,200) #The number is small, the color depth is 0-255
        # paragraph.paragraph_format.line_spacing = Pt(180) #Number paragraph spacing
        
        r = run._element
        r.rPr.rFonts.set(qn('w:eastAsia'), '黑体')# Change the font of the Chinese part in the input sentence to Chinese Xingkai
        table.cell(0,0).paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER #Center
    
    
           
            
        
    doc.save(r'C:\Users\jg2yXRZ\OneDrive\Desktop\Student ID Number Puzzle\Zero Hour Word\{}.docx'.format(' d'%nn))
    from docx2pdf import convert

    # Save the docx file as a PDF file
    inputFile = r"C:/Users/jg2yXRZ/OneDrive/Desktop/Student ID Number Puzzle/Zero Hour Word/{}.docx".format(' d'%nn) # File to convert: already exists
    outputFile = r"C:/Users/jg2yXRZ/OneDrive/Desktop/Student Number Digital Puzzle/Zero Hour Word/{}.pdf".format(' d'%nn) # File to be generated: does not exist
    # Create the non-existent file first
    f1 = open(outputFile, 'w')
    f1. close()
    # Then convert to write content in PDF
    convert(inputFile, outputFile)
    
print('----------Step 4: Merge all PDFs into one PDF for printing------------')
    
# Merge multiple PDFs (CSDN blogger "Red Little Crab", https://blog.csdn.net/yangcunbiao/article/details/125248205)
import os
from PyPDF2 import PdfFileMerger
target_path = 'C:/Users/jg2yXRZ/OneDrive/Desktop/Student ID Number Puzzle/Zero Hour Word'
pdf_lst = [f for f in os.listdir(target_path) if f.endswith('.pdf')]
pdf_lst = [os.path.join(target_path, filename) for filename in pdf_lst]
pdf_lst. sort()
file_merger = PdfFileMerger()
for pdf in pdf_lst:
    print(pdf)
    file_merger.append(pdf)
file_merger.write("C:/Users/jg2yXRZ/OneDrive/Desktop/Student ID Number Puzzle/(Print Collection) Student ID Number Puzzle A4, two copies per page (3 times 3 sheets){}persons, a total of {} copies).pdf ".format(num,int(num/2)))
file_merger. close()
# doc. Close()

# print('----------Step 5: Delete the temporary folder ------------')
import shut-off
shutil.rmtree('C:/Users/jg2yXRZ/OneDrive/Desktop/Student ID Number Puzzle/Zero Time Word') #Delete folders recursively, ie: delete non-empty folders

Code modification when verifying:

5. All codes (for verification) – (generate Chinese colorful cloud font)

Modify the code, write the pictures sequentially, and verify the correctness of the puzzle result.

Comparison of randomly shuffled puzzles + result pictures (for verification)

Academic tools for student number 01-09

Academic tools for student numbers 10-19

School tools for student numbers 20-28

At present, only Chinese colorful clouds have been tested (change the font to adjust the position of the number on the picture, it will take a long time to test)