iTextSharp-PDF-调整文档大小以适应大图像
本文关键字:图像 调整 文档 iTextSharp-PDF- | 更新日期: 2023-09-27 18:19:31
我正在使用iTextSharp将大型图像转换为PDF文档。
这是可行的,但图像看起来是裁剪的,因为它们超出了生成文档的边界。
所以问题是——如何使文档与插入其中的图像大小相同?
我使用以下代码:
Document doc = new Document(PageSize.LETTER.Rotate());
try
{
PdfWriter.GetInstance(doc, new FileStream(saveFileDialog1.FileName,FileMode.Create));
doc.Open();
doc.Add(new Paragraph());
iTextSharp.text.Image img = iTextSharp.text.Image.GetInstance(imagePath);
doc.Add(img);
}
catch
{
// add some code here incase you have an exception
}
finally
{
//Free the instance of the created doc as well
doc.Close();
}
iText和iTextSharp中的Document
对象是一个抽象,可以自动处理各种间距、填充和边距。不幸的是,这也意味着当您调用doc.Add()
时,它会考虑文档的现有边距。(此外,如果你碰巧添加了其他任何东西,图像也会被添加。)
一个解决方案是只去除利润:
doc.SetMargins(0, 0, 0, 0);
相反,可以更容易地将图像直接添加到PdfWriter
对象中,这是通过调用PdfWriter.GetInstance()
获得的。你目前正在扔掉并没有存储该对象,但你可以很容易地将你的行更改为:
PdfWriter writer = PdfWriter.GetInstance(doc, new FileStream(saveFileDialog1.FileName,FileMode.Create));
然后您可以访问PdfWriter
的DirectContent
属性,并调用其AddImage()
方法:
writer.DirectContent.AddImage(img);
在进行此操作之前,您还必须通过调用来绝对定位图像
img.SetAbsolutePosition(0, 0);
下面是一个完整的C#2010 WinForms应用程序,目标是iTextSharp 5.1.1.0,它显示了上面的DirectContent
方法。它动态地创建了两个不同大小的图像,两个红色箭头垂直和水平延伸。您的代码显然只使用标准的图像加载,因此可以省略很多内容,但我想提供一个完整的工作示例。有关更多详细信息,请参阅代码中的注释。
using System;
using System.Drawing;
using System.Windows.Forms;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;
namespace WindowsFormsApplication1 {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e) {
//File to write out
string outputFilename = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Images.pdf");
//Standard PDF creation
using (FileStream fs = new FileStream(outputFilename, FileMode.Create, FileAccess.Write, FileShare.None)) {
//NOTE, we are not setting a document size here at all, we'll do that later
using (Document doc = new Document()) {
using (PdfWriter writer = PdfWriter.GetInstance(doc, fs)) {
doc.Open();
//Create a simple bitmap with two red arrows stretching across it
using (Bitmap b1 = new Bitmap(100, 400)) {
using (Graphics g1 = Graphics.FromImage(b1)) {
using(Pen p1 = new Pen(Color.Red,10)){
p1.StartCap = System.Drawing.Drawing2D.LineCap.ArrowAnchor;
p1.EndCap = System.Drawing.Drawing2D.LineCap.ArrowAnchor;
g1.DrawLine(p1, 0, b1.Height / 2, b1.Width, b1.Height / 2);
g1.DrawLine(p1, b1.Width / 2, 0, b1.Width / 2, b1.Height);
//Create an iTextSharp image from the bitmap (we need to specify a background color, I think it has to do with transparency)
iTextSharp.text.Image img1 = iTextSharp.text.Image.GetInstance(b1, BaseColor.WHITE);
//Absolutely position the image
img1.SetAbsolutePosition(0, 0);
//Change the page size for the next page added to match the source image
doc.SetPageSize(new iTextSharp.text.Rectangle(0, 0, b1.Width, b1.Height, 0));
//Add a new page
doc.NewPage();
//Add the image directly to the writer
writer.DirectContent.AddImage(img1);
}
}
}
//Repeat the above but with a larger and wider image
using (Bitmap b2 = new Bitmap(4000, 1000)) {
using (Graphics g2 = Graphics.FromImage(b2)) {
using (Pen p2 = new Pen(Color.Red, 10)) {
p2.StartCap = System.Drawing.Drawing2D.LineCap.ArrowAnchor;
p2.EndCap = System.Drawing.Drawing2D.LineCap.ArrowAnchor;
g2.DrawLine(p2, 0, b2.Height / 2, b2.Width, b2.Height / 2);
g2.DrawLine(p2, b2.Width / 2, 0, b2.Width / 2, b2.Height);
iTextSharp.text.Image img2 = iTextSharp.text.Image.GetInstance(b2, BaseColor.WHITE);
img2.SetAbsolutePosition(0, 0);
doc.SetPageSize(new iTextSharp.text.Rectangle(0, 0, b2.Width, b2.Height, 0));
doc.NewPage();
writer.DirectContent.AddImage(img2);
}
}
}
doc.Close();
}
}
}
this.Close();
}
}
}
尝试这样的方法来纠正您的问题
foreach (var image in images)
{
iTextSharp.text.Image pic = iTextSharp.text.Image.GetInstance(image, System.Drawing.Imaging.ImageFormat.Jpeg);
if (pic.Height > pic.Width)
{
//Maximum height is 800 pixels.
float percentage = 0.0f;
percentage = 700 / pic.Height;
pic.ScalePercent(percentage * 100);
}
else
{
//Maximum width is 600 pixels.
float percentage = 0.0f;
percentage = 540 / pic.Width;
pic.ScalePercent(percentage * 100);
}
pic.Border = iTextSharp.text.Rectangle.BOX;
pic.BorderColor = iTextSharp.text.BaseColor.BLACK;
pic.BorderWidth = 3f;
document.Add(pic);
document.NewPage();
}
您没有说明是向文档中添加一个图像,还是添加多个以随时更改页面大小,但调用ONLY会在NEXT页面上生效。
换句话说,类似这样的东西:
<%@ WebHandler Language="C#" Class="scaleDocToImageSize" %>
using System;
using System.Web;
using iTextSharp.text;
using iTextSharp.text.pdf;
public class scaleDocToImageSize : IHttpHandler {
public void ProcessRequest (HttpContext context) {
HttpServerUtility Server = context.Server;
HttpResponse Response = context.Response;
Response.ContentType = "application/pdf";
string[] imagePaths = {"./Image15.png", "./Image19.png"};
using (Document document = new Document()) {
PdfWriter.GetInstance(document, Response.OutputStream);
document.Open();
document.Add(new Paragraph("Page 1"));
foreach (string path in imagePaths) {
string imagePath = Server.MapPath(path);
Image img = Image.GetInstance(imagePath);
var width = img.ScaledWidth
+ document.RightMargin
+ document.LeftMargin
;
var height = img.ScaledHeight
+ document.TopMargin
+ document.BottomMargin
;
Rectangle r = width > PageSize.A4.Width || height > PageSize.A4.Height
? new Rectangle(width, height)
: PageSize.A4
;
/*
* you __MUST__ call SetPageSize() __BEFORE__ calling NewPage()
* AND __BEFORE__ adding the image to the document
*/
document.SetPageSize(r);
document.NewPage();
document.Add(img);
}
}
}
public bool IsReusable { get { return false; } }
}
上面的工作示例是在web环境中(.ashx HTTP处理程序),因此您需要将上面的Response.OutputStream
替换为FileStream
(来自代码片段)。显然,您也需要替换文件路径。