Python中用PIL与qrcode库实现二维码透明背景失败求助
问题:二维码透明背景显示为黑色的解决方法
我有一个Python脚本,可从CSV文件生成二维码并将其合成到PDF中。尝试将二维码的背景设置为透明,但它始终显示为黑色背景。试过使用fpdf库、将图像转为RGBA格式等方法,但都无效。以下是生成二维码的代码:
def generate_qr_code_with_text(data, text_row1, text_row2, text_row3, output_path, qr_size_pixels=227): try: qr = qrcode.QRCode( version=1, error_correction=qrcode.constants.ERROR_CORRECT_L, box_size=10, border=4, ) qr.add_data(data) qr.make(fit=True) img = qr.make_image(fill_color=(255,255,255), back_color=None) img = img.resize((qr_size_pixels, qr_size_pixels)) final_img = Image.new('RGBA', (img.width, img.height + 90), color=(255, 255, 255, 0)) final_img.paste(img, (0, 0)) draw = ImageDraw.Draw(final_img) font = ImageFont.load_default() text_row1_position = (final_img.size[0] // 2, img.size[1] + 10) draw.text(text_row1_position, f"Row 1: {text_row1}", fill="black", font=font, anchor="mm") text_row2_position = (final_img.size[0] // 2, img.size[1] + 30) draw.text(text_row2_position, f"Row 2: {text_row2}", fill="black", font=font, anchor="mm") text_row3_position = (final_img.size[0] // 2, img.size[1] + 50) draw.text(text_row3_position, f"Row 3: {text_row3}", fill="black", font=font, anchor="mm") final_img.save(output_path) return True except Exception as e: print(e) return False
解决步骤
1. 生成RGBA模式的二维码图像
默认的make_image方法生成的是调色板模式(P)图像,即使设置back_color=None也不会生成透明通道。需要显式指定使用PIL的RGBA图像工厂,并设置透明背景色:
# 替换原生成img的行 img = qr.make_image( fill_color=(255,255,255), # 二维码颜色(这里是白色) back_color=(255,255,255,0), # 透明背景(RGBA的alpha通道为0) image_factory=qrcode.image.pil.PilImage )
2. 粘贴时保留透明通道
将二维码粘贴到最终图像时,必须指定mask参数,否则透明区域会被填充为黑色:
# 替换原paste的行 final_img.paste(img, (0, 0), mask=img)
3. 确保保存为支持透明的格式
透明效果仅在PNG格式中有效,因此output_path必须以.png结尾。如果保存为JPEG等不支持透明的格式,透明区域会自动转为黑色。
修改后的完整代码
def generate_qr_code_with_text(data, text_row1, text_row2, text_row3, output_path, qr_size_pixels=227): try: qr = qrcode.QRCode( version=1, error_correction=qrcode.constants.ERROR_CORRECT_L, box_size=10, border=4, ) qr.add_data(data) qr.make(fit=True) # 生成带透明背景的RGBA二维码图像 img = qr.make_image( fill_color=(255,255,255), back_color=(255,255,255,0), image_factory=qrcode.image.pil.PilImage ) img = img.resize((qr_size_pixels, qr_size_pixels)) final_img = Image.new('RGBA', (img.width, img.height + 90), color=(255, 255, 255, 0)) # 粘贴时保留透明通道 final_img.paste(img, (0, 0), mask=img) draw = ImageDraw.Draw(final_img) font = ImageFont.load_default() text_row1_position = (final_img.size[0] // 2, img.size[1] + 10) draw.text(text_row1_position, f"Row 1: {text_row1}", fill="black", font=font, anchor="mm") text_row2_position = (final_img.size[0] // 2, img.size[1] + 30) draw.text(text_row2_position, f"Row 2: {text_row2}", fill="black", font=font, anchor="mm") text_row3_position = (final_img.size[0] // 2, img.size[1] + 50) draw.text(text_row3_position, f"Row 3: {text_row3}", fill="black", font=font, anchor="mm") final_img.save(output_path) return True except Exception as e: print(e) return False
内容的提问来源于stack exchange,提问作者Santyhritz
相关产品推荐
相关产品推荐

