python - 使用 Pycairo 创建包含(调整大小的)PNG 图像的 PDF - 重新缩放 Surface 问题

标签 python pdf resize cairo geometry-surface

我有一些 PNG 图像链接,我想下​​载、“转换为缩略图”并使用 Python 和 Cairo 保存为 PDF。

现在,我有一个工作代码,但我不知道如何控制纸张上的图像大小。有没有办法将 PyCairo Surface 的大小调整为我想要的尺寸(恰好比原始尺寸小)?我希望原始像素“缩小”到更高分辨率(在纸上)。

另外,我尝试了 PIL 中的 Image.rescale() 函数,但它给了我一个 20x20 像素的输出(来自 200x200 像素的原始图像,这不是代码上的横幅示例) )。我想要的是在纸上的 20x20 毫米正方形内绘制 200x200 像素图像(而不是我现在得到的 200x200 毫米正方形)

我当前的代码是:

#!/usr/bin/python

import cairo, urllib, StringIO, Image   # could I do it without Image module?

paper_width = 210
paper_height = 297
margin = 20

point_to_milimeter = 72/25.4

pdfname = "out.pdf" 
pdf = cairo.PDFSurface(pdfname , paper_width*point_to_milimeter, paper_height*point_to_milimeter)
cr = cairo.Context(pdf)
cr.scale(point_to_milimeter, point_to_milimeter)

f=urllib.urlopen("http://cairographics.org/cairo-banner.png")
i=StringIO.StringIO(f.read())
im=Image.open(i)

# are these StringIO operations really necessary?

imagebuffer = StringIO.StringIO()  
im.save(imagebuffer, format="PNG")
imagebuffer.seek(0)
imagesurface = cairo.ImageSurface.create_from_png(imagebuffer)


### EDIT: best answer from Jeremy, and an alternate answer from mine:
best_answer = True      # put false to use my own alternate answer
if best_answer:
    cr.save()
    cr.scale(0.5, 0.5)
    cr.set_source_surface(imagesurface, margin, margin)
    cr.paint()
    cr.restore()
else:
    cr.set_source_surface(imagesurface, margin, margin)
    pattern = cr.get_source()
    scalematrix = cairo.Matrix()    # this can also be used to shear, rotate, etc.
    scalematrix.scale(2,2)          # matrix numbers seem to be the opposite - the greater the number, the smaller the source
    scalematrix.translate(-margin,-margin)  # this is necessary, don't ask me why - negative values!!
    pattern.set_matrix(scalematrix)  
    cr.paint()  

pdf.show_page()

请注意,美丽的开罗横幅甚至不适合页面...... 理想的结果是我可以以用户空间单位(在本例中为毫米)控制该图像的宽度和高度,例如创建一个漂亮的标题图像。

感谢您的阅读以及任何帮助或评论!!

最佳答案

绘制图像时尝试缩放上下文。

例如

cr.save()    # push a new context onto the stack
cr.scale(0.5, 0.5)    # scale the context by (x, y)
cr.set_source_surface(imagesurface, margin, margin)
cr.paint()
cr.restore()    # pop the context

参见:http://cairographics.org/documentation/pycairo/2/reference/context.html了解更多详情。

关于python - 使用 Pycairo 创建包含(调整大小的)PNG 图像的 PDF - 重新缩放 Surface 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7099630/

相关文章:

python - 带有列表和元组参数的 np.c_ 的行为

python - 如果测试通过,pytest fixture 可以清理吗?

python - 类型错误 : Field 'id' expected a number but got <django. contrib.auth.models.AnonymousUser 对象在 0x048C7E90>

ffmpeg-normalize 以 OSError : [WinError 193] %1 is not a valid Win32 application 退出

iphone - iPhone/iPad 上的 PDF 超链接

jquery - 使用 css 和/或 jquery 智能调整图像大小

python - 如何在 Python 中填写 PDF 表单?

java - 如何使用princeXML自动拆分表

jQuery 调整丢失边框的大小

javascript - 函数比较宽度元素