۱۳۹۰/۰۴/۰۸

تبديل تعدادي تصوير به يك فايل PDF


صورت مساله:
تعدادي تصوير داريم، مي‌خواهيم اين‌ها را تبديل به فايل PDF كنيم به اين شرط كه هر تصوير در يك صفحه مجزا قرار داده شود.
در ادامه براي اين منظور از كتابخانه‌ي iTextSharp استفاده خواهيم كرد.

iTextSharp چيست؟
iTextSharp كتابخانه‌ي سورس باز و معروفي جهت توليد فايل‌هاي PDF ، توسط برنامه‌هاي مبتني بر دات نت است. آن را از آدرس زير مي‌توان دريافت كرد:


كتابخانه iTextSharp نيز جزو كتابخانه‌هايي است كه از جاوا به دات نت تبديل شده‌اند. نام كتابخانه اصلي iText است و اگر كمي جستجو كنيد مي‌توانيد كتاب 617 صفحه‌اي iText in Action از انتشارات MANNING را در اين مورد نيز بيابيد. هر چند اين كتاب براي برنامه نويس‌هاي جاوا نوشته شده اما نام كلاس‌ها و متدها در iTextSharp تفاوتي با iText اصلي ندارند و مطالب آن براي برنامه نويس‌‌هاي دات نت هم قابل استفاده است.

مجوز استفاده از iTextSharp كدام است؟
مجوز اين كتابخانه GNU Affero General Public License است. به اين معنا كه شما موظفيد، تغييري در قسمت تهيه كننده خواص فايل PDF توليدي كه به صورت خودكار به نام كتابخانه تنظيم مي‌شود، ندهيد. اگر مي‌خواهيد اين قسمت را تغيير دهيد بايد هزينه كنيد. همچنين با توجه به اينكه اين مجوز، GPL است يعني زمانيكه از آن استفاده كرديد بايد كار خود را به صورت سورس باز ارائه دهيد؛ درست خونديد! بله! مثل مجوز استفاده از نگارش عمومي و رايگان MySQL و اگر نمي‌خواهيد اينكار را انجام دهيد، در اينجا تاكيد شده كه بايد كتابخانه را خريداري كنيد.

نحوه استفاده از كتابخانه iTextSharp
در ابتدا كد تبديل تصاوير به فايل PDF را در ذيل مشاهده خواهيد كرد. فرض بر اين است كه ارجاعي را به اسمبلي itextsharp.dll اضافه كرده‌ايد:
using System.Collections.Generic;
using System.Drawing.Imaging;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;

namespace iTextSharpTests
{
public class ImageToPdf
{
public iTextSharp.text.Rectangle PdfPageSize { set; get; }
public ImageFormat ImageCompressionFormat { set; get; }
public bool FitImagesToPage { set; get; }

public void ExportToPdf(IList<string> imageFilesPath, string outPdfPath)
{
using (var pdfDoc = new Document(PdfPageSize))
{
PdfWriter.GetInstance(pdfDoc, new FileStream(outPdfPath, FileMode.Create));
pdfDoc.Open();

foreach (var file in imageFilesPath)
{
var pngImg = iTextSharp.text.Image.GetInstance(file);

if (FitImagesToPage)
{
pngImg.ScaleAbsolute(pdfDoc.PageSize.Width, pdfDoc.PageSize.Height);
}
pngImg.SetAbsolutePosition(0, 0);

//add to page
pdfDoc.Add(pngImg);
//start a new page
pdfDoc.NewPage();
}
}
}
}
}
توضيحات:
استفاده از كتابخانه‌ي iTextSharp هميشه شامل 5 مرحله است. ابتدا شيء Document ايجاد مي‌شود. سپس وهله‌اي از PdfWriter ساخته شده و Document جهت نوشتن در آن گشوده خواهد شد. در طي يك سري مرحله محتويات مورد نظر به Document اضافه شده و نهايتا اين شيء بسته خواهد شد. البته در اينجا چون كلاس Document اينترفيس IDisposable را پياده سازي كرده، بهترين روش استفاده از آن بكارگيري واژه كليدي using جهت مديريت منابع آن است. به اين ترتيب كامپايلر به صورت خودكار قطعه try/finally مرتبط را جهت پاكسازي منابع، تشكيل خواهد داد.
اندازه صفحات توسط سازنده‌ي شيء Document مشخص خواهند شد. اين شيء از نوع iTextSharp.text.Rectangle است؛ اما مقدار دهي آن توسط كلاس iTextSharp.text.PageSize صورت مي‌گيرد كه انواع و اقسام اندازه صفحات استاندارد در آن تعريف شده‌اند.
متد iTextSharp.text.Image.GetInstance كه در اين مثال جهت دريافت اطلاعات تصاوير مورد استفاده قرار گرفت، 15 overload دارد كه از آدرس مستقيم يك فايل تا استريم مربوطه تا Uri يك آدرس وب را نيز مي‌پذيرد و از اين لحاظ بسيار غني است.

مثالي در مورد نحوه استفاده از كلاس فوق:
using System.Collections.Generic;
using System.Drawing.Imaging;

namespace iTextSharpTests
{
class Program
{
static void Main(string[] args)
{
new ImageToPdf
{
FitImagesToPage = true,
ImageCompressionFormat = ImageFormat.Jpeg,
PdfPageSize = iTextSharp.text.PageSize.A4
}.ExportToPdf(
imageFilesPath: new List<string>
{
@"D:\3.jpg",
@"D:\4.jpg"
},
outPdfPath: @"D:\tst.pdf"
);
}
}
}