You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Python实现圆形二维码:如何填充图形线条间的颜色?

Fixing the Blank Filling Issue for Your Circular QR Code in Python

Hey there! I totally get how frustrating it is to nail the outline but hit a wall with filling those gaps. Let's break this down and get your circular QR code looking perfect.

First: Let's Talk Library Choices

Matplotlib is great for data plotting, but it's not the most intuitive tool for building and modifying QR codes. For this task, combining the qrcode library (to generate core QR data) with Pillow (PIL) (for image manipulation) will make your life way easier. That said, if you're set on using Matplotlib, we'll cover that too.

Option 1: The Easier Route with Pillow & qrcode

This method generates a standard QR code first, then converts its modules to circles and adds a circular border—no more struggling with path filling!

First, install the required packages:

pip install qrcode[pil]

Then use this code to generate your circular QR code:

import qrcode
from PIL import Image, ImageDraw

def create_circular_qr(scan_data, output_size=350):
    # Step 1: Generate a standard QR code
    qr_generator = qrcode.QRCode(
        version=2,  # Adjust based on how much data you need to store
        error_correction=qrcode.constants.ERROR_CORRECT_M,  # Balances error correction and space
        box_size=12,
        border=4,
    )
    qr_generator.add_data(scan_data)
    qr_generator.make(fit=True)
    base_qr = qr_generator.make_image(fill_color="black", back_color="white").convert("RGBA")

    # Step 2: Create a circular mask for the entire QR code
    circular_mask = Image.new("L", base_qr.size, 0)
    mask_drawer = ImageDraw.Draw(circular_mask)
    mask_drawer.ellipse((0, 0, base_qr.size[0], base_qr.size[1]), fill=255)

    # Step 3: Apply the mask to get a circular outer shape
    circular_qr = Image.new("RGBA", base_qr.size)
    circular_qr.paste(base_qr, mask=circular_mask)

    # Step 4: Replace square modules with circular ones (optional but polished)
    qr_drawer = ImageDraw.Draw(circular_qr)
    box_size = qr_generator.box_size
    border_offset = qr_generator.border * box_size

    for row_idx, row in enumerate(qr_generator.modules):
        for col_idx, is_filled in enumerate(row):
            if is_filled:
                # Calculate center of the module
                center_x = border_offset + col_idx * box_size + box_size // 2
                center_y = border_offset + row_idx * box_size + box_size // 2
                # Draw a circle instead of a square
                qr_drawer.ellipse(
                    (
                        center_x - box_size//2,
                        center_y - box_size//2,
                        center_x + box_size//2,
                        center_y + box_size//2
                    ),
                    fill="black"
                )

    # Save or display your QR code
    circular_qr.save("my_circular_qr.png")
    circular_qr.show()

# Test it out!
create_circular_qr("Your Custom Data Here")

Option 2: Fixing Matplotlib Path Filling

If you want to stick with Matplotlib, the problem is almost certainly that your contour paths aren't closed (start and end points don't meet), or you're using line drawing instead of filled patches.

Here's a quick example of how to draw and fill a closed circular path (adapt this to your QR modules):

import matplotlib.pyplot as plt
from matplotlib.patches import PathPatch
from matplotlib.path import Path

fig, ax = plt.subplots(figsize=(5,5))

# Example closed circular path (replace with your QR module contours)
circle_vertices = [
    (1, 0), (0.707, 0.707), (0, 1), (-0.707, 0.707),
    (-1, 0), (-0.707, -0.707), (0, -1), (0.707, -0.707), (1, 0)  # Closing the path by repeating the start point
]
circle_codes = [Path.MOVETO] + [Path.LINETO]*7 + [Path.CLOSEPOLY]

qr_module_path = Path(circle_vertices, circle_codes)
filled_patch = PathPatch(qr_module_path, facecolor="black", edgecolor="black")
ax.add_patch(filled_patch)

# Clean up the plot
ax.set_xlim(-1.5, 1.5)
ax.set_ylim(-1.5, 1.5)
plt.axis("off")
plt.show()

Key points here:

  • Make sure every contour path ends with Path.CLOSEPOLY or repeats the starting vertex to close it.
  • Use PathPatch with facecolor set to your desired fill color instead of just plotting lines.

Final Tips

  • If you're drawing custom QR modules from scratch, double-check that each module's outline forms a closed loop—Matplotlib won't fill open shapes.
  • The Pillow method is more robust for QR codes because it directly manipulates image pixels, which aligns better with how QR codes are structured.

内容的提问来源于stack exchange,提问作者Fatih YILMAZ

火山引擎 最新活动