iText 图片调整大小

25

我有一个水印要放到我的pdf里面。这个水印是一个.bmp图像,大小为2290 x 3026。我尝试将其调整大小以适应页面,但遇到了很多问题,是否有人可以提供建议?

Document document = new Document(); 
PdfWriter.getInstance(document, new FileOutputStream("result.pdf")); 
document.open(); 
document.add(new Paragraph("hello")); 
document.close(); 
PdfReader reader = new PdfReader("result.pdf"); 
int number_of_pages = reader.getNumberOfPages(); 
PdfStamper pdfStamper = new PdfStamper(reader, new FileOutputStream("result_watermark.pdf")); 
// Get the PdfContentByte type by pdfStamper. 
Image watermark_image = Image.getInstance("abstract(0307).bmp"); 
int i = 0; 
watermark_image.setAbsolutePosition(0, 0);
watermark_image.scaleToFit(826, 1100);
System.out.println(watermark_image.getScaledWidth());
System.out.println(watermark_image.getScaledHeight()); 
PdfContentByte add_watermark; 
while (i < number_of_pages) { 
    i++; 
    add_watermark = pdfStamper.getUnderContent(i); 
    add_watermark.addImage(watermark_image); 
} 
pdfStamper.close();

这里是 getScaled() 方法的输出结果。

826.0 - Width
1091.4742 - Height

很抱歉,我无法与您分享pdf文件中的图片。

我是否应尝试使用.jpg格式呢?我不太清楚iText对不同图像扩展名的处理情况。


请将以下与编程有关的内容从英语翻译成中文。只返回翻译后的文本:您可以添加PDF截图。请参见http://meta.stackexchange.com/questions/75491/how-to-upload-an-image-to-a-post或http://meta.stackexchange.com/questions/57125/inserting-an-image-in-a-pre-tag - Ritesh
那不是问题。我正在添加的水印是公司的水印,我不能随便传播它。无论如何,我被告知不要这样做。 - Failsafe
1
你尝试手动缩放图像,而不是在程序中进行缩放,并在代码中使用手动缩放后的图像吗?由于您似乎硬编码了缩放尺寸,这样做可以节省每次给PDF文档加水印时的一些处理时间。 - Alexis Pigeon
@AlexisPigeon - 没有,但我会尝试并回复你。 - Failsafe
@AlexisPigeon - 手动调整大小可以运行,有点模糊,但我可以应对。把你的评论作为答案添加,我会给你打勾。 - Failsafe
@Failsafe 现在回答可能已经太晚了,但是您可以使用 scaleAbsolute(float x, float y) 方法。请查看我下面的回答。 - MGDroid
7个回答

64
我这样做:

我是这样做的:

//if you would have a chapter indentation
int indentation = 0;
//whatever
Image image = coolPic;

float scaler = ((document.getPageSize().getWidth() - document.leftMargin()
               - document.rightMargin() - indentation) / image.getWidth()) * 100;

image.scalePercent(scaler);

你能准确描述一下你的问题吗?缩放功能不起作用,好的,但是你使用的缩放器在此时的输出是什么? - Franz Ebner
4
这个方法对我来说比Alexis提出的想法更有效,因为默认缩放具有相当低的分辨率,所以如果您调整原始图像大小以适合PDF文档,您将得到一个模糊的低分辨率图像,可能相当于72 dpi。但是通过缩放,您可以使用一个更大的图像,重新调整大小以适合文档,同时保留高分辨率。 - Ted
运行得非常好,谢谢。 - Magno C
这个解决方案对我有用。虽然我会说这只是一个变通方法,可能有一种正确的方法来设置图像以适应宽度。 - Markiian Benovskyi
1
无法处理高度较大的图像。 - Siddharth Shakya
显示剩余2条评论

24

使用

watermark_image.scaleAbsolute(826, 1100);

取代

watermark_image.scaleToFit(826, 1100);

1
这两种方法有什么区别? - Fred
从iText in Action第2版中: scaleToFit()的宽度和高度参数定义图像的最大尺寸。如果宽度/高度比与图像的纵横比不同,则宽度或高度将小于此方法的相应参数。使用scaleAbsolute()时,将尊重宽度和高度参数。如果您不明智地选择参数,则生成的图像可能在X或Y方向上被拉伸。您还可以使用ScaleAbsoluteWidth()和scaleAbsoluteHeight()。 - alrts

17

以防万一图像高度超过文档高度:

float documentWidth = document.getPageSize().width() - document.leftMargin() - document.rightMargin();
float documentHeight = document.getPageSize().height() - document.topMargin() - document.bottomMargin();
image.scaleToFit(documentWidth, documentHeight);

1
这很好。仅仅写image.scaleToFit(PageSize.A4.getWidth(), PageSize.A4.getHeight());可能会导致更大的图像超出页面边界。 - Oleksandr Firsov
4
".height()和.width()似乎不是有效的方法名称。我不得不改为document.getPageSize().getWidth()和document.getPageSize().getHeight()才能使其工作。" - M.A.Naseer

15

你可以使用

imageInstance.scaleAbsolute(requiredWidth, requiredHeight);

7
你可以采用另一种方法:手动调整图像大小(即通过图像处理软件),而不是通过iText程序性地进行调整。
由于最终尺寸似乎是硬编码的,因此您可以使用已经缩小过的图像,并且每次为PDF文件加水印时都可以节省一些处理时间。

5
Document document = new Document();
PdfWriter.getInstance(document, new 
FileOutputStream("F:\\Directory1\\sample1.pdf"));
document.open();

Image img = 
Image.getInstance("F:\\Server\\Xyz\\WebContent\\ImageRestoring\\Rohit.jpg");
img.scaleToFit(200, 200);
document.add(new Paragraph("Sample 1: This is simple image demo."));
document.add(img);
document.close();
System.out.println("Done");

抱歉回答晚了,但我已经在这五个月内开始专业工作,并且从这个网站得到了很多帮助,所以我想我应该尽我所能回馈这个网站。 - Paresh Jain
1
@Failsafe,你至少应该尝试一下Paresh的解决方案,看看它是否更好。他确实花了很多心思来编写它。 - Sidney
@Sidney CS0246 类型或命名空间名称 'Document' 无法找到(是否缺少 using 指令或程序集引用?)求助!我该怎么解决? - Failsafe

4
有时,如果图像太大,只缩小而不放大会很有用。换句话说,只有当宽度或高度不适合可用的宽度或高度时,才会进行缩放。可以按照以下方式完成缩放:
float scaleRatio = calculateScaleRatio(doc, image);
if (scaleRatio < 1F) {
    image.scalePercent(scaleRatio * 100F);
}

使用这个calculateScaleRatio方法:
/**
 * Calculate scale ratio required to fit supplied image in the supplied PDF document.
 * @param doc    PDF to fit image in.
 * @param image  Image to be converted into a PDF.
 * @return       Scale ratio (0.0 - 1.0), or 1.0 if no scaling is required.
 */
private float calculateScaleRatio(Document doc, Image image) {
    float scaleRatio;
    float imageWidth = image.getWidth();
    float imageHeight = image.getHeight();
    if (imageWidth > 0 && imageHeight > 0) {
        // Firstly get the scale ratio required to fit the image width
        Rectangle pageSize = doc.getPageSize();
        float pageWidth = pageSize.getWidth() - doc.leftMargin() - doc.rightMargin();
        scaleRatio = pageWidth / imageWidth;

        // Get scale ratio required to fit image height - if smaller, use this instead
        float pageHeight = pageSize.getHeight() - doc.topMargin() - doc.bottomMargin();
        float heightScaleRatio = pageHeight / imageHeight;
        if (heightScaleRatio < scaleRatio) {
            scaleRatio = heightScaleRatio;
        }

        // Do not upscale - if the entire image can fit in the page, leave it unscaled.
        if (scaleRatio > 1F) {
            scaleRatio = 1F;
        }
    } else {
        // No scaling if the width or height is zero.
        scaleRatio = 1F;
    }
    return scaleRatio;
}

1
这对我帮助很大,谢谢!由于iText几乎从未按照你最初的尝试方式工作,因此这些模块可以节省时间,并为您提供更多时间来考虑实际问题。 - alrts

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接