2012-01-03 428 views
4

我使用iTextSharp將大圖像轉換爲PDF文檔。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(); 
    } 

回答

4

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)); 

然後你就可以訪問PdfWriterDirectContent屬性並調用其AddImage()方法:

writer.DirectContent.AddImage(img); 

在這樣做之前,您還必須通過調用絕對定位圖像:

img.SetAbsolutePosition(0, 0); 

下面是一個完整的C#2010 Wi針對iTextSharp 5.1.1.0的nForms應用程序顯示上面的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(); 
     } 
    } 
} 
+0

謝謝 - 聽起來比原來的解決方案好得多。你有什麼想法這個方法可以處理的最大圖像大小是多少? – SharpAffair 2012-01-04 15:54:22

+0

根據PDF規範(附錄C第2節),符合1.6的PDF的最小尺寸爲3x3,最大尺寸爲14,400x14,4000。請注意,這些尺寸以「默認用戶空間中的單位」表示,如果您不更改,則爲1/72英寸。通常最好將單位看作像素。如果你想了解更多關於「用戶空間」和「單位」的信息,請參閱這篇文章:http://stackoverflow.com/a/8245450/231316 – 2012-01-04 16:15:15

+0

乍一看,似乎工作完美無缺。您的文章非常有幫助!謝謝! – SharpAffair 2012-01-04 20:23:14

3

嘗試像這樣以解決問題

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(); 
} 
+0

似乎並沒有工作 - 仍然裁剪 – SharpAffair 2012-01-03 15:16:08

+1

這裏是一篇文章,你可以嘗試..我不知道你正在嘗試或不嘗試,但是看看this..becasue認爲應該有工作。 .. http://www.mikesdotnetting.com/Article/87/iTextSharp-Working-with-images – MethodMan 2012-01-03 15:20:01

0

你沒有說,如果你要添加一個圖像的文件或多個圖像。但無論如何,更改Document.PageSize有點棘手。你可以隨時通過調用Document.SetPageSize()更改頁面大小,但撥打電話ONLY takes effect on the NEXT page

換句話說,這樣的事情:

<%@ 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; } } 
} 

上述工作的例子是在網絡環境中(.ashx的HTTP處理程序),所以你需要用FileStream更換Response.OutputStream以上(從您的代碼段)。顯然你也需要替換文件路徑。

相關問題