为什么在生成的 PDF 中使用的像素比在源 html 中使用的更多?
Why are more Pixel used in resulting PDF than in source html?
我使用此代码在 css 文件中下载带有图像的网页,但它在 pdf 文件中缩放得太大了。
图片的宽度为 120 像素,显示为 185 像素宽度。
对于 Camparison,我构建了一条 10 像素的线,显示为 12 像素。
但是为什么呢?我该如何解决?
我不能 post 这个问题没有进一步的细节,但我什么都不知道,这对你来说很有用,但也许它有帮助:
我在存档部门工作,负责存档可在其网页中访问的信息,但最终,外观并不是创作者想要的样子。
我尝试改用本地 CSS 文件,但意识到这不是我想要的。
我必须更频繁地使用我的工作流程,并且必须使用他们提供的 css 文件并将 html 页面正确转换为 PDF。
提前感谢您的阅读,
我试图让准则包含所有重要的知识,但仅此而已。
项目的依赖项是:
- com.itextpdf 内核 7.1.7
- com.itextpdf 样式化-xml-解析器 7.1.7
- com.itextpdf svg 7.1.7
- com.itextpdf pdfa 7.1.7
- org.slf4j-简单 1.6.1
package ueberordnungen;
import java.io.IOException;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import com.itextpdf.html2pdf.ConverterProperties;
import com.itextpdf.html2pdf.HtmlConverter;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
public class Worker3 {
public static void main(String[] args) throws IOException {
//eine spezielle URL heraus picken
String kongressURL = "https://www.egms.de/dynamic/de/meetings/vnda2019/index.htm";
Document doc = Jsoup.connect(kongressURL).get();
System.out.println("-----Titel: "+ doc.title());
Element content = doc.child(0);
content.getElementById("navigation_language").remove();
content.getElementById("navigation").remove();
content.getElementsByAttributeValue("href", "/static/css/gms-framework.css").first().remove();
content.getElementsByClass("hidden_navigation").first().remove();
content.getElementById("page").before(content.getElementById("header"));
content.getElementsByTag("script").remove();
content.getElementById("owner_links_container").attr("style", "border-top:10px solid #060");
ConverterProperties properties = new ConverterProperties();
properties.setBaseUri(kongressURL);
PdfWriter writer = new PdfWriter("content.pdf");
HtmlConverter.convertToPdf(content.html(), new PdfDocument(writer), properties);
}
}
iText 7 以每点一个图像像素的比例添加背景图像,参见 AbstractRenderer.drawBackground
:
PdfXObject backgroundXObject = backgroundImage.getImage();
...
Rectangle imageRectangle = new Rectangle(backgroundArea.getX(), backgroundArea.getTop() - backgroundXObject.getHeight(),
backgroundXObject.getWidth(), backgroundXObject.getHeight());
...
drawContext.getCanvas().addXObject(backgroundXObject, imageRectangle);
如您在代码中所见,图像的宽度和高度值(包含位图图像的水平和垂直像素数)按原样用作图像的宽度和高度图像最终被缩放到的矩形。由于 canvas 绘图操作中使用的单位是用户 space 单位,默认为 1/72in,图像以每英寸 72 个图像像素或每磅 1 个图像像素显示。
Web 浏览器通常默认以每像素 1 个图像像素或每英寸 96 个图像像素显示图像。
您的示例网页主要使用 px = 1/96in 中给出的绝对位置进行布局。因此,网络浏览器或 iText 绘制图像的不同比例会导致不同的外观,特别是在手头的情况下,iText 中的外观不是令人愉悦的:
在Chrome:
在 iText 中:
您可以通过将上面计算 imageRectangle
的中心代码行替换为
来使 iText 绘制背景图像更像浏览器
Rectangle imageRectangle = new Rectangle(backgroundArea.getX(), backgroundArea.getTop() - backgroundXObject.getHeight(),
backgroundXObject.getWidth() * .75f, backgroundXObject.getHeight() * .75f);
在 iText 中,按照上面的建议进行了修补:
实际上,此代码位置似乎是开始添加对 background-size
的支持的合适位置,目前此处不支持此功能。
注意:我不是很了解 iText 7 HTML 到 PDF 的转换代码,所以我无法确定这个补丁是否有不良副作用。
这是一个错误吗?
严格来说不是,至少就我浏览 CSS 规范而言:
HTML页面没有在这里设置background-size
。因此,应使用背景图像的固有尺寸。不幸的是,CSS 没有定义通常如何找到内在维度。 因此,网页基本上将背景图像的比例留给了 HTML 客户...
如果 iText 7 HTML 到 PDF 旨在生成与浏览器输出一致的结果,那么它最好在此处更改其默认比例以匹配那些浏览器。
我刚刚意识到我修补的 AbstractRenderer
不在 html2pdf 项目中,而是在核心 iText 7 布局项目中。
因此,在此处更改大小可能不是一个好主意,至少如果一个人不仅将 iText 7 用于 html2pdf,而且还直接将其使用。
尽管如此,该代码位置适合引入对某些背景大小属性的支持。 html2pdf 然后可以扩展 BackgroundApplierUtil
,以便它始终将新的核心属性设置为适合创建与浏览器显示内容一致的外观的值。
我使用此代码在 css 文件中下载带有图像的网页,但它在 pdf 文件中缩放得太大了。 图片的宽度为 120 像素,显示为 185 像素宽度。 对于 Camparison,我构建了一条 10 像素的线,显示为 12 像素。
但是为什么呢?我该如何解决?
我不能 post 这个问题没有进一步的细节,但我什么都不知道,这对你来说很有用,但也许它有帮助:
我在存档部门工作,负责存档可在其网页中访问的信息,但最终,外观并不是创作者想要的样子。 我尝试改用本地 CSS 文件,但意识到这不是我想要的。 我必须更频繁地使用我的工作流程,并且必须使用他们提供的 css 文件并将 html 页面正确转换为 PDF。
提前感谢您的阅读, 我试图让准则包含所有重要的知识,但仅此而已。
项目的依赖项是:
- com.itextpdf 内核 7.1.7
- com.itextpdf 样式化-xml-解析器 7.1.7
- com.itextpdf svg 7.1.7
- com.itextpdf pdfa 7.1.7
- org.slf4j-简单 1.6.1
package ueberordnungen;
import java.io.IOException;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import com.itextpdf.html2pdf.ConverterProperties;
import com.itextpdf.html2pdf.HtmlConverter;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
public class Worker3 {
public static void main(String[] args) throws IOException {
//eine spezielle URL heraus picken
String kongressURL = "https://www.egms.de/dynamic/de/meetings/vnda2019/index.htm";
Document doc = Jsoup.connect(kongressURL).get();
System.out.println("-----Titel: "+ doc.title());
Element content = doc.child(0);
content.getElementById("navigation_language").remove();
content.getElementById("navigation").remove();
content.getElementsByAttributeValue("href", "/static/css/gms-framework.css").first().remove();
content.getElementsByClass("hidden_navigation").first().remove();
content.getElementById("page").before(content.getElementById("header"));
content.getElementsByTag("script").remove();
content.getElementById("owner_links_container").attr("style", "border-top:10px solid #060");
ConverterProperties properties = new ConverterProperties();
properties.setBaseUri(kongressURL);
PdfWriter writer = new PdfWriter("content.pdf");
HtmlConverter.convertToPdf(content.html(), new PdfDocument(writer), properties);
}
}
iText 7 以每点一个图像像素的比例添加背景图像,参见 AbstractRenderer.drawBackground
:
PdfXObject backgroundXObject = backgroundImage.getImage();
...
Rectangle imageRectangle = new Rectangle(backgroundArea.getX(), backgroundArea.getTop() - backgroundXObject.getHeight(),
backgroundXObject.getWidth(), backgroundXObject.getHeight());
...
drawContext.getCanvas().addXObject(backgroundXObject, imageRectangle);
如您在代码中所见,图像的宽度和高度值(包含位图图像的水平和垂直像素数)按原样用作图像的宽度和高度图像最终被缩放到的矩形。由于 canvas 绘图操作中使用的单位是用户 space 单位,默认为 1/72in,图像以每英寸 72 个图像像素或每磅 1 个图像像素显示。
Web 浏览器通常默认以每像素 1 个图像像素或每英寸 96 个图像像素显示图像。
您的示例网页主要使用 px = 1/96in 中给出的绝对位置进行布局。因此,网络浏览器或 iText 绘制图像的不同比例会导致不同的外观,特别是在手头的情况下,iText 中的外观不是令人愉悦的:
在Chrome:
在 iText 中:
您可以通过将上面计算 imageRectangle
的中心代码行替换为
Rectangle imageRectangle = new Rectangle(backgroundArea.getX(), backgroundArea.getTop() - backgroundXObject.getHeight(),
backgroundXObject.getWidth() * .75f, backgroundXObject.getHeight() * .75f);
在 iText 中,按照上面的建议进行了修补:
实际上,此代码位置似乎是开始添加对 background-size
的支持的合适位置,目前此处不支持此功能。
注意:我不是很了解 iText 7 HTML 到 PDF 的转换代码,所以我无法确定这个补丁是否有不良副作用。
这是一个错误吗?
严格来说不是,至少就我浏览 CSS 规范而言:
HTML页面没有在这里设置background-size
。因此,应使用背景图像的固有尺寸。不幸的是,CSS 没有定义通常如何找到内在维度。 因此,网页基本上将背景图像的比例留给了 HTML 客户...
如果 iText 7 HTML 到 PDF 旨在生成与浏览器输出一致的结果,那么它最好在此处更改其默认比例以匹配那些浏览器。
我刚刚意识到我修补的 AbstractRenderer
不在 html2pdf 项目中,而是在核心 iText 7 布局项目中。
因此,在此处更改大小可能不是一个好主意,至少如果一个人不仅将 iText 7 用于 html2pdf,而且还直接将其使用。
尽管如此,该代码位置适合引入对某些背景大小属性的支持。 html2pdf 然后可以扩展 BackgroundApplierUtil
,以便它始终将新的核心属性设置为适合创建与浏览器显示内容一致的外观的值。