updating ui
This commit is contained in:
185
barcode_generator.py
Normal file
185
barcode_generator.py
Normal file
@@ -0,0 +1,185 @@
|
||||
import os
|
||||
import io
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
|
||||
# Try to import barcode libraries, provide fallback if not available
|
||||
try:
|
||||
import qrcode
|
||||
QRCODE_AVAILABLE = True
|
||||
except ImportError:
|
||||
QRCODE_AVAILABLE = False
|
||||
|
||||
try:
|
||||
from barcode import EAN13, Code128
|
||||
from barcode.writer import ImageWriter
|
||||
BARCODE_AVAILABLE = True
|
||||
except ImportError:
|
||||
BARCODE_AVAILABLE = False
|
||||
|
||||
class BarcodeGenerator:
|
||||
"""
|
||||
A utility class for generating QR codes and barcodes.
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def check_dependencies():
|
||||
"""
|
||||
Check if all required dependencies are installed.
|
||||
|
||||
Returns:
|
||||
dict: Status of each dependency
|
||||
"""
|
||||
return {
|
||||
'qrcode': QRCODE_AVAILABLE,
|
||||
'barcode': BARCODE_AVAILABLE,
|
||||
'pillow': True # PIL/Pillow is imported directly at the top level
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def generate_qr_code(data, size=10, border=4):
|
||||
"""
|
||||
Generates a QR code as a PIL Image object.
|
||||
|
||||
Args:
|
||||
data (str): The data to encode in the QR code
|
||||
size (int): The size of the QR code (1-40)
|
||||
border (int): The border size of the QR code
|
||||
|
||||
Returns:
|
||||
PIL.Image: The generated QR code image or a placeholder image if qrcode is not available
|
||||
"""
|
||||
if not QRCODE_AVAILABLE:
|
||||
return BarcodeGenerator._generate_placeholder("QR Code Unavailable\nPlease install 'qrcode' package")
|
||||
|
||||
qr = qrcode.QRCode(
|
||||
version=size,
|
||||
error_correction=qrcode.constants.ERROR_CORRECT_L,
|
||||
box_size=10,
|
||||
border=border,
|
||||
)
|
||||
qr.add_data(data)
|
||||
qr.make(fit=True)
|
||||
|
||||
img = qr.make_image(fill_color="black", back_color="white")
|
||||
return img
|
||||
|
||||
@staticmethod
|
||||
def generate_ean13_barcode(data):
|
||||
"""
|
||||
Generates an EAN-13 barcode as a PIL Image object.
|
||||
|
||||
Args:
|
||||
data (str): The data to encode in the barcode (must be 12 digits)
|
||||
|
||||
Returns:
|
||||
PIL.Image: The generated barcode image or a placeholder image if barcode is not available
|
||||
"""
|
||||
if not BARCODE_AVAILABLE:
|
||||
return BarcodeGenerator._generate_placeholder("EAN-13 Unavailable\nPlease install 'python-barcode' package")
|
||||
|
||||
# Pad data to 12 digits if needed
|
||||
if len(data) < 12:
|
||||
data = data.zfill(12)
|
||||
elif len(data) > 12:
|
||||
data = data[:12]
|
||||
|
||||
# Create a BytesIO object to temporarily store the image
|
||||
buffer = io.BytesIO()
|
||||
EAN13(data, writer=ImageWriter()).write(buffer)
|
||||
|
||||
# Create a PIL Image from the BytesIO object
|
||||
buffer.seek(0)
|
||||
image = Image.open(buffer)
|
||||
|
||||
return image
|
||||
|
||||
@staticmethod
|
||||
def generate_code128_barcode(data):
|
||||
"""
|
||||
Generates a Code 128 barcode as a PIL Image object.
|
||||
|
||||
Args:
|
||||
data (str): The data to encode in the barcode
|
||||
|
||||
Returns:
|
||||
PIL.Image: The generated barcode image or a placeholder image if barcode is not available
|
||||
"""
|
||||
if not BARCODE_AVAILABLE:
|
||||
return BarcodeGenerator._generate_placeholder("Code 128 Unavailable\nPlease install 'python-barcode' package")
|
||||
|
||||
# Create a BytesIO object to temporarily store the image
|
||||
buffer = io.BytesIO()
|
||||
Code128(data, writer=ImageWriter()).write(buffer)
|
||||
|
||||
# Create a PIL Image from the BytesIO object
|
||||
buffer.seek(0)
|
||||
image = Image.open(buffer)
|
||||
|
||||
return image
|
||||
|
||||
@staticmethod
|
||||
def _generate_placeholder(message):
|
||||
"""
|
||||
Generates a placeholder image with a message.
|
||||
|
||||
Args:
|
||||
message (str): Message to display on the placeholder
|
||||
|
||||
Returns:
|
||||
PIL.Image: The generated placeholder image
|
||||
"""
|
||||
# Create a placeholder image
|
||||
img = Image.new('RGB', (300, 150), color=(255, 255, 255))
|
||||
d = ImageDraw.Draw(img)
|
||||
|
||||
# Draw a border
|
||||
d.rectangle([0, 0, 299, 149], outline=(0, 0, 0), width=2)
|
||||
|
||||
# Add text
|
||||
try:
|
||||
# Try to use a default font
|
||||
font = ImageFont.truetype("arial.ttf", 20)
|
||||
except IOError:
|
||||
# Fallback to default font
|
||||
font = ImageFont.load_default()
|
||||
|
||||
# Center the text
|
||||
lines = message.split('\n')
|
||||
y_offset = 40
|
||||
for line in lines:
|
||||
text_width = d.textlength(line, font=font)
|
||||
d.text(((300 - text_width) // 2, y_offset), line, font=font, fill=(0, 0, 0))
|
||||
y_offset += 30
|
||||
|
||||
return img
|
||||
|
||||
@staticmethod
|
||||
def save_image(image, path):
|
||||
"""
|
||||
Saves a PIL Image to the specified path.
|
||||
|
||||
Args:
|
||||
image (PIL.Image): The image to save
|
||||
path (str): The path to save the image to
|
||||
|
||||
Returns:
|
||||
str: The path where the image was saved
|
||||
"""
|
||||
image.save(path)
|
||||
return path
|
||||
|
||||
@staticmethod
|
||||
def get_image_as_bytes(image, format='PNG'):
|
||||
"""
|
||||
Converts a PIL Image to bytes.
|
||||
|
||||
Args:
|
||||
image (PIL.Image): The image to convert
|
||||
format (str): The format to save the image as
|
||||
|
||||
Returns:
|
||||
bytes: The image as bytes
|
||||
"""
|
||||
buffer = io.BytesIO()
|
||||
image.save(buffer, format=format)
|
||||
return buffer.getvalue()
|
||||
Reference in New Issue
Block a user