简体   繁体   English

Python / PDF创建使用ReportLab - 自制的网格打印带有图案但在屏幕上看起来很好

[英]Python/PDF Creation Using ReportLab - self-made grid prints with a pattern but looks fine on the screen

I am trying to make my own grid (that looks very much like this: http://tinyurl.com/cdyre6k - ECG paper that is in metric units of millimeters). 我正在尝试制作自己的网格(看起来非常像这样: http//tinyurl.com/cdyre6k-以公制单位为毫米的心电图纸)。

I am using ReportLab/Python (opensource) to make these reports. 我正在使用ReportLab / Python(opensource)来制作这些报告。 Below is a snippet of my code. 下面是我的代码片段。

On the screen, it looks GREAT!: 在屏幕上,它看起来很棒!:

>我在屏幕上看到的内容<

However, when I send this to a printer (and yes, I've also tinkered with printer settings) it prints some lines, and not others (sometimes it's methodical and prints a pattern-esque plaid, other times it is thicker/thinner lines; keep in mind, the output at the printer is consistent depending on strokewidths I set). 然而,当我将它发送到打印机时(是的,我也用打印机设置修改)它会打印一些线条,而不是其他线条(有时它是有条不紊的并且打印出图案式格子图案,有时则是更粗/更细的线条;请记住,打印机的输出是一致的,取决于我设置的笔画宽度。

>我在打印机上看到的内容!<

I have tried all sorts of strokewidth combinations, and all sorts of printer setting combinations... I can't get it to print correctly! 我尝试了各种笔画宽度组合,以及各种打印机设置组合...我无法正确打印! I have tried an alternative printer and gotten MUCH better results, but I have to set the printer settings to over 1200 dpi (CAD level printing). 我尝试了另一种打印机并获得了更好的结果,但我必须将打印机设置设置为超过1200 dpi(CAD级别打印)。 The other printer is set to 600dpi. 另一台打印机设置为600dpi。 On that SAME PRINTER (600dpi) I print a document made by a former coworker and it print's just fine (please note, he was not using ReportLab so I cannot use his code/solution). 在那台相同的打印机(600dpi)上,我打印了一个由前同事制作的文件,打印就好了(请注意,他没有使用ReportLab,所以我不能使用他的代码/解决方案)。

What is going on? 到底是怎么回事? Is this an aliasing issue at the printer? 这是打印机上的别名问题吗? Would it help me if I coverted my grids to bitmaps (or some other format)? 如果我将网格转换为位图(或其他格式),它会对我有帮助吗? How can I fix this (my only options are to use Python and ReportLab)? 我该如何解决这个问题(我唯一的选择是使用Python和ReportLab)? ReportLab manual didn't help, "Google" didn't help, and previous StackExchange questions didn't seem to cover this specific topic. ReportLab手册没有帮助,“谷歌”没有帮助,而之前的StackExchange问​​题似乎没有涵盖这一特定主题。 I can get the grid to print all the lines if I set the strokewidth to "1", but then the minor grid lines are too thick. 如果我将笔画宽度设置为“1”,我可以让网格打印所有行,但是后面的网格线太粗了。

The end result is for a line chart I am working on, and I know ReportLab has chart functions, but reportlabs charts/grid function(s) don't give me what I need for my project, so I have been forced to make my own grid with major/minor lines (maybe I missed something and open to alternative techniques, but currently it looks fine in PDF form, just not at the printer). 最终结果是我正在处理的折线图,我知道ReportLab有图表功能,但reportlabs图表/网格功能不能给我我的项目所需,所以我被迫让我拥有主要/次要线的自己的网格(也许我错过了一些东西,并开放替代技术,但目前看起来很好的PDF形式,只是不在打印机)。

ANY advice is appreciated! 任何建议表示赞赏!

TIA, TIA,

-J -J

    for i in decimal_range(0, _time, 1):
        if (i % 5.0 == 0):
            if (i % 25.0 == 0):
                grid_pattern.add(shapes.Line(_temp_x, 
                                             (_temp_y + _height_of_box), 
                                             _temp_x,
                                             (_temp_y + _height_of_box+4),
                                             strokeWidth=1,
                                             strokeColor=colors.black))
            else:
                pass

            grid_pattern.add(shapes.Line(_temp_x, _temp_y, _temp_x,
                                         (_temp_y + _height_of_box),
                                         strokeWidth=.12,
                                         strokeColor=colors.pink))
        else:
            grid_pattern.add(shapes.Line(_temp_x, _temp_y, _temp_x,
                                         (_temp_y + _height_of_box),
                                         strokeWidth=.12,
                                         strokeColor=colors.pink))
        _temp_x += 1 * mm

    _temp_x = xorigin

    for i in range(0, _mv, 1):
        if (i % 5.0 == 0):
            grid_pattern.add(shapes.Line(_temp_x, _temp_y,
                                         _temp_x + _width_of_box,
                                         _temp_y, strokeWidth=.12,
                                         strokeColor=colors.pink))
        else:
            grid_pattern.add(shapes.Line(_temp_x, _temp_y,
                                         _temp_x + _width_of_box,
                                         _temp_y, strokeWidth=.12,
                                         strokeColor=colors.pink))    
        _temp_y += 1 * mm

UPDATE1 UPDATE1

I have tried setting the stroke width to "0" as recommended by several posters (and the ReportLab community/mailing list) as follows: 我已经尝试按照几个海报(以及ReportLab社区/邮件列表)的建议将笔划宽度设置为“0”,如下所示:

grid_pattern.add(shapes.Line(_temp_x, _temp_y, _temp_x,
                            (_temp_y + _height_of_box),
                            strokeWidth=0,
                            strokeColor=colors.pink))

This does make a single pixel-wide line, which again, looks great on the PC, but still prints with a funky pattern in PDF. 这确实产生了一条像素宽的线,再次在PC上看起来很棒,但仍然以PDF的时髦图案打印。

UPDATE2 + SOLUTION UPDATE2 +解决方案

After LOTS of tantrums and arguments with ReportLab and my computer it turns out it wasn't my PC or ReportLab. 经过大量的发脾气和ReportLab与我的计算机的争论后,结果发现它不是我的PC或ReportLab。 It was the printers (I was using two totally different printers Canon and HP - models notwithstanding) - I felt that I had enough coverage to rule out the printer, but there is more to this problem! 这是打印机(我使用两种完全不同的打印机佳能和惠普 - 虽然模型) - 我觉得我有足够的覆盖率来排除打印机,但这个问题还有更多! Continue reading... 继续阅读...

ReportLab doesn't actually draw the line, it just adds a postscript line that tells the render to draw the line. ReportLab实际上并没有绘制直线,只是添加了一个postscript线,告诉渲染器绘制直线。

Part of my initial debugging included changing the colors I was using to see if that was an issue - well - I changed the colors from pink to red (not much of a change, I know, but again, I assumed I changed it enough to rule out colors as an issue). 我的初步调试的一部分包括改变我正在使用的颜色,看看这是否是一个问题 - 好吧 - 我把颜色从粉红色改为红色(没有太大的变化,我知道,但是再次,我认为我改变了它足够排除颜色作为一个问题)。

Well from what I have recently, and painfully learned, is that the printers convert colors to grayscale using a formula and that formula has a tendency to produce antialiasing side-effects (like what I was seeing). 从我最近所获得的,并且痛苦地了解到,打印机使用公式将颜色转换为灰度,并且该公式具有产生抗锯齿副作用的倾向(就像我所看到的那样)。

THE SOLUTION: was to change the colors of the grid. 解决方案:改变网格的颜色。 Certain colors perform better than others. 某些颜色比其他颜色表现更好。 So, to test this, I wrote a simple script which you can download here that will generate a PDF document using all of the colors stored in reportlabs colors dictionary - print a sample grid that was causing me the problems and provide the RGB values. 所以,为了测试这个,我写了一个简单的脚本,你可以在这里下载 ,使用存储在reportlabs颜色字典中的所有颜色生成PDF文档 - 打印导致我出现问题并提供RGB值的样本网格。 As it turns out, alllllllll sorts of colors don't print well across several printers (all different) - it's not just reds/pinks... some "red-like" colors print fine, some printers handle the grayscale conversion better than another. 事实证明,alllllllll的各种颜色在几台打印机上都不能很好地打印(全部不同) - 它不仅仅是红色/粉红色......一些“红色”颜色打印得很好,有些打印机比另一种更好地处理灰度转换。

So now, our task is to use this PDF document I created to find a color that looks fine in print (both color and grayscale) and on the screen. 所以现在,我们的任务是使用我创建的PDF文档来查找打印(彩色和灰度)和屏幕上看起来很好的颜色。

If you don't want to download the script for fear I'm evil - at least check out the PDF and print your own samples to see if you can recreate the problem I was having (I was printing at 600dpi - standard - nothing fancy... remember, if I turned up the DPI/quality settings, it printed fine, but the standard settings were causing me grief!). 如果你不想下载脚本因为害怕我是邪恶的 - 至少检查PDF并打印你自己的样品,看看你是否可以重现我遇到的问题(我是以600dpi打印 - 标准 - 没什么特别的...记住,如果我打开DPI /质量设置,它打印得很好,但标准设置让我感到悲伤!)。

Script 脚本

or 要么

PDF PDF

If I understand how ReportLab handles lines correctly, you're asking it to create lines with respectively 1 and 0.12 user space units. 如果我理解ReportLab如何正确处理行,则要求它创建分别具有1和0.12用户空间单位的行。 In PDF, one "user space unit" is effectively 1/72 of an inch. 在PDF中,一个“用户空间单元”实际上是1/72英寸。

This means the lines you're drawing will be respectively 0.014 and 0.0017 inch wide. 这意味着您绘制的线条分别为0.014和0.0017英寸宽。 That's really not much. 那真的不多。 Depending on the resolution of your output device and where on the page the line happens to be (so, depending on whether it happens to be aligned with the pixel grid of your screen or printer or not) you'll probably get different results. 根据输出设备的分辨率和页面上的位置(因此,取决于它是否恰好与屏幕或打印机的像素网格对齐),您可能会得到不同的结果。

Your printer likely will try to optimise output by anti-aliasing which will make the final result even more uncertain. 您的打印机可能会尝试通过抗锯齿来优化输出,这将使最终结果更加不确定。

The alignment effect with your printer's pixel grid is probably why you see some lines and don't see others. 打印机像素网格的对齐效果可能是您看到某些线条并且看不到其他线条的原因。

A couple of things to try / play with. 尝试/玩的几件事。

1) Output your lines with 0 line width. 1)输出0行宽的行。 This is a special case in PDF and it means "output a line of exactly one pixel wide". 这是PDF中的特殊情况,它意味着“输出一行恰好一个像素宽”。 Keep in mind that such a line should be visible on your screen (which is only 72 or 96 dpi) but might not be on your printer (which will now print a dot that is 1/1200 of an inch). 请记住,这样的线应该在屏幕上可见(仅为72或96 dpi),但可能不在您的打印机上(现在将打印一个1/1200英寸的点)。 But if your printer obeys the rules, it should always print that one dot. 但是,如果您的打印机遵守规则,它应该始终打印一个点。

2) Make your lines wider - probably the only way to achieve consistent results. 2)让你的线条更宽 - 可能是获得一致结果的唯一方法。 If the smaller lines look too thick, consider printing a dotted line instead of a solid one (set a dash pattern). 如果较小的线条看起来太粗,请考虑打印虚线而不是实线(设置虚线图案)。

Not exactly sure how to apply this to what you're doing, but the traditional Postscript way is to round the device coordinates to integers. 不完全确定如何将此应用于您正在做的事情,但传统的Postscript方法是将设备坐标舍入为整数。

/roundpoint { % x y -> x' y'
    transform %convert user-space coords to device-space coords
    round
    itransform %convert device-space back to user-space
} def

...
x y roundpoint moveto
x y roundpoint lineto
...

If all your lines are placed consistently with respect to the device pixels, then they should be drawn consistently as well. 如果所有线条都相对于设备像素保持一致,那么它们也应该一致地绘制。

I think setting a stroke width of 0 is what you want. 我认为设置笔划宽度为0是你想要的。 This produces a special type of line that is often referred to as a hairline. 这会产生一种特殊类型的线,通常被称为发际线。 It basically tells the printer to print the thinnest possible line that it can (the width of a droplet from an ink jet printer or the width of the laser in a laser printer). 它基本上告诉打印机打印尽可能最细的线条(喷墨打印机的液滴宽度或激光打印机中激光的宽度)。 I'm not sure if all PDF viewers will display it as you expect but you should try printing it anyway. 我不确定所有PDF查看器是否会按预期显示它,但无论如何都应该尝试打印它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM