【问题标题】:How to properly create a new image with desired size and resolution (PNG, JPG, JPEG)?如何正确创建具有所需大小和分辨率(PNG、JPG、JPEG)的新图像?
【发布时间】:2020-10-22 17:20:07
【问题描述】:

我想使用 Pillow 创建一个 PNG。 PNG 后来用于标签打印。所以,我尝试使用PIL 创建一个新图像,添加一些文本、一个多边形和一个二维码。但是,我发现很难获得合适的图像尺寸(与标签尺寸相关,即 7.5 厘米 x 5.5 厘米)。我只能通过尝试和错误到达那里(大致是(275, 204))。保存时,PNG的分辨率很差,所以打印出来。

如何正确计算图像大小以及如何提高将图像保存为 PNG(或 JPG 或 JPEG)的分辨率。

到目前为止,这是我的代码:

import qrcode
from PIL import Image
from PIL import ImageFont
from PIL import ImageDraw 

# Create qr code instance
qr = qrcode.QRCode(
    version = 1,
    error_correction = qrcode.constants.ERROR_CORRECT_H,
    box_size = 4,
    border = .2,
)

text = "test"
# Create new image

img = Image.new('RGB', (275, 204), color = (220,220,220))

# Add data
qr.add_data(text)
qr.make(fit=True)

# Create an image from the QR Code instance
qrc = qr.make_image(fill_color='black', back_color='white')

draw = ImageDraw.Draw(img)

font1 = ImageFont.truetype("arial.ttf", 25)
font2 = ImageFont.truetype("arial.ttf", 60)

draw.text((65, 150),text,(0,0,0),font=font1)
draw.text((115, 120),text,(0,0,0),font=font2)
draw.polygon(((5, 20), (50, 34), (50, 6)), fill=0)
img.paste(qrc, (80,25))

img.show()

#img.save("image.png", dpi = (300,300))

【问题讨论】:

    标签: python image size python-imaging-library resolution


    【解决方案1】:

    您需要为所有要绘制的元素设置相对(标签)坐标和大小(以厘米为单位),然后计算相应的图像坐标和大小(以像素为单位)w.r.t。所需的分辨率。这会有点麻烦,但我想不出另一种独立于分辨率的方法。

    在下文中,我省略了整个 QR 码以使内容至少具有一点可读性。

    为了比较,您的代码原样(没有二维码)在我的机器上生成此图像:

    如果我在 Photoshop 中打开该图像,它会显示 9.7 cm x 7.2 cm at 72 dpi。如果我手动计算分辨率,我会得到以下结果:

    275 pixels / 7.5 cm * (2.54 cm/inch) = ca. 93 dpi
    204 pixels / 5.5 cm * (2.54 cm/inch) = ca. 94 dpi
    

    稍后我们将需要 94 dpi。

    我根据您的原始图像估算了相对(标签)坐标和大小。

    现在,首先让我们看看整个代码:

    from PIL import Image, ImageDraw, ImageFont
    
    # Set up parameters
    w_cm, h_cm = (7.5, 5.5)             # Real label size in cm
    res_x, res_y = (300, 300)           # Desired resolution
    res_y_old = 94                      # Old y resolution (204 / 5.5 * 2.54)
    
    # Inch-to-cm factor
    f = 2.54
    
    # Determine image size w.r.t. resolution
    w = int(w_cm / f * res_x)
    h = int(h_cm / f * res_y)
    
    # Create new image with proper size
    img = Image.new('RGB', (w, h), color=(220, 220, 220))
    
    # Draw elements
    draw = ImageDraw.Draw(img)
    
    
    def draw_text(x_cm, y_cm, font_size):
        font = ImageFont.truetype('arial.ttf', int(font_size / (res_y_old / res_y)))
        x, y = (int(x_cm / f * res_x), int(y_cm / f * res_y))
        draw.text((x, y), 'test', (0, 0, 0), font=font)
    
    
    # Draw texts
    draw_text(1.875, 4, 25)
    draw_text(3.15, 3.25, 60)
    
    # Polygon
    coords_cm = [(0.15, 0.5), (1.35, 0.9), (1.35, 0.1)]
    coords = [(int(c[0] / f * res_x), int(c[1] / f * res_y)) for c in coords_cm]
    draw.polygon(tuple(coords), fill=(0, 0, 0))
    
    # Save image
    img.save('image.png', dpi=(res_x, res_y))
    

    然后,让我们看看输出:

    如果我在 Photoshop 中打开该图像,它会显示 7.5 cm x 5.5 cm at 300 dpi,这正是我们想要的。

    关于字体大小:我猜,您手动设置这些字体大小以获得某种外观。不幸的是,以点为单位的字体大小已调整为在显示器上具有一定的高度,但它们不会缩放以进行打印(或“打印”图像)。这就是为什么,我们需要缩放字体 w.r.t。新旧分辨率,以保持原始图像中所需的文本外观。

    其他一切都是重复转换相对坐标和大小。如果需要进一步的解释,请不要犹豫!

    ----------------------------------------
    System information
    ----------------------------------------
    Platform:    Windows-10-10.0.16299-SP0
    Python:      3.8.5
    Pillow:      8.1.0
    ----------------------------------------
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多