From 04b1aa98745d617f6c09e12a453bdee6e6d32ca2 Mon Sep 17 00:00:00 2001 From: shouchih_chen Date: Fri, 27 Jun 2025 14:13:00 +0800 Subject: [PATCH] add barcode style --- generate_images.py | 58 +++++++++++++++++++++++++++++---------------- requirements.txt | 2 ++ resource/sample.csv | 2 +- 3 files changed, 40 insertions(+), 22 deletions(-) diff --git a/generate_images.py b/generate_images.py index d2f8af6..a9f955a 100644 --- a/generate_images.py +++ b/generate_images.py @@ -5,6 +5,9 @@ from PySide6.QtWidgets import QGraphicsScene, QGraphicsRectItem, QGraphicsPixmap from PySide6.QtGui import QPainter, QImage, QColor, QPixmap, QFont, QFontDatabase import CustomCircleItem import re +import barcode +from barcode.writer import ImageWriter +from PIL.ImageQt import ImageQt BG_WIDTH = 3508 BG_HEIGHT = 2480 @@ -16,6 +19,9 @@ Y_OFFSET = 650 CIRCLE_RADIUS = 617 CIRCLE_X_OFFSET = 750 +code39 = barcode.get('code39', '/6R9G1N2', writer=ImageWriter()) +code39.save('code39_barcode') + def is_chinese(text): # Returns True if any character is Chinese return any('\u4e00' <= char <= '\u9fff' for char in text) @@ -135,29 +141,39 @@ class ImageGenerator(QObject): circle_item = CustomCircleItem.CustomCircleItem(100+(CIRCLE_X_OFFSET*j), 25, CIRCLE_RADIUS, 600, QColor(r, g, b), is_circle=True,parent=rect_item) circle_item.setOpacity(1) - #draw head icon - head_icon_num = int(name[1]) if len(name) > 1 else 1 - head_icon = QGraphicsPixmapItem(QPixmap(HEAD_ICON_PREFIX % head_icon_num), circle_item) - head_icon.setPos(circle_item.boundingRect().x(), circle_item.boundingRect().y()) - - #name item - name_item = QGraphicsTextItem() - name_str = name[2 + j] if len(name) > 2 + j else "Unknown" - if is_chinese(name_str): - if len(name_str) == 2: - self.customFont.setLetterSpacing(QFont.AbsoluteSpacing, 30) # Adjust word spacing if needed - elif len(name_str) == 3: - self.customFont.setLetterSpacing(QFont.AbsoluteSpacing, 15) - elif len(name_str) == 4: - self.customFont.setLetterSpacing(QFont.AbsoluteSpacing, 0) + + is_draw_barcode = j == 1 and name_str[0] =='/' # Check if the second name starts with '/' + if is_draw_barcode: + # Draw barcode + barcode_img = code39.render({'module_width': 0.22, 'module_height': 12, 'font_size': 16, 'text_distance':7, 'quiet_zone':10,'background': 'white', 'foreground': 'black'}) + barcode_img = ImageQt(barcode_img) # Convert PIL image to Qt image + barcode_item = QGraphicsPixmapItem(QPixmap.fromImage(barcode_img), circle_item) + barcode_item.setPos(circle_item.boundingRect().x() + circle_item.boundingRect().width()/2 - barcode_item.boundingRect().width()/2, + circle_item.boundingRect().y() + circle_item.boundingRect().height()/2 - barcode_item.boundingRect().height()/2) else: - self.customFont.setLetterSpacing(QFont.AbsoluteSpacing, 0) - name_item.setFont(self.customFont) - name_item.setPlainText(name_str) - name_item.setDefaultTextColor(QColor(0, 0, 0)) - name_item.setPos((circle_item.boundingRect().x()+ circle_item.boundingRect().width()/2 - name_item.boundingRect().width()/2)+10, circle_item.boundingRect().y()+430) - self.scene.addItem(name_item) + if is_chinese(name_str): + if len(name_str) == 2: + self.customFont.setLetterSpacing(QFont.AbsoluteSpacing, 30) # Adjust word spacing if needed + elif len(name_str) == 3: + self.customFont.setLetterSpacing(QFont.AbsoluteSpacing, 15) + elif len(name_str) == 4: + self.customFont.setLetterSpacing(QFont.AbsoluteSpacing, 0) + else: + self.customFont.setLetterSpacing(QFont.AbsoluteSpacing, 0) + + #draw head icon + head_icon_num = int(name[1]) if len(name) > 1 else 1 + head_icon = QGraphicsPixmapItem(QPixmap(HEAD_ICON_PREFIX % head_icon_num), circle_item) + head_icon.setPos(circle_item.boundingRect().x(), circle_item.boundingRect().y()) + + #name item + name_item = QGraphicsTextItem() + name_item.setFont(self.customFont) + name_item.setPlainText(name_str) + name_item.setDefaultTextColor(QColor(0, 0, 0)) + name_item.setPos((circle_item.boundingRect().x()+ circle_item.boundingRect().width()/2 - name_item.boundingRect().width()/2)+10, circle_item.boundingRect().y()+430) + self.scene.addItem(name_item) if i > 0 and i % 6 == 5: # Save the current scene to an image file every 5 items diff --git a/requirements.txt b/requirements.txt index a447c25..930ae6b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,8 +5,10 @@ Flask==3.1.1 itsdangerous==2.2.0 Jinja2==3.1.6 MarkupSafe==3.0.2 +pillow==11.2.1 PySide6==6.9.1 PySide6_Addons==6.9.1 PySide6_Essentials==6.9.1 +python-barcode==0.15.1 shiboken6==6.9.1 Werkzeug==3.1.3 diff --git a/resource/sample.csv b/resource/sample.csv index c2ceea4..5f784d4 100644 --- a/resource/sample.csv +++ b/resource/sample.csv @@ -1,7 +1,7 @@ color_name,icon_type,name_1,name_2 海天藍,1,陳宣瑜,Shirley 桃花紅,1,王子,陳匹股 -菸灰綠,1,公主,公主 +菸灰綠,1,公主,/6R9G1N2 奶油色,1,吳佳鈴,吳佳鈴 湖水藍,5,陳守志,陳守志 奶茶色,6,陳宣瑜,陳宣瑜