2013-07-08 4 views
7

używam C# i iTextSharp dodać znak wodny do moich plików PDF:Jak dodać znak wodny do pliku PDF?

Document document = new Document(); 
PdfReader pdfReader = new PdfReader(strFileLocation); 
PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileStream(strFileLocationOut, FileMode.Create, FileAccess.Write, FileShare.None)); 
iTextSharp.text.Image img = iTextSharp.text.Image.GetInstance(WatermarkLocation); 
img.SetAbsolutePosition(100, 300); 
PdfContentByte waterMark; 
//  
for (int pageIndex = 1; pageIndex <= pdfReader.NumberOfPages; pageIndex++) 
{ 
    waterMark = pdfStamper.GetOverContent(pageIndex); 
    waterMark.AddImage(img); 
} 
// 
pdfStamper.FormFlattening = true; 
pdfStamper.Close(); 

To działa dobrze, ale moim problemem jest to, że w niektórych plików PDF bez znaku wodnego dodaje chociaż rozmiar pliku wzrosła, jakiś pomysł ?

+0

Czy wszystkie pliki PDF mają te same mediabox i cropbox? Czy to możliwe, że pozycja '(100, 300)' znajduje się poza tymi polami? –

+0

pozycja jest poprawna, testuję ją. – Abady

+0

Jakie są współrzędne pól mediów/przycinania, gdy znak wodny nie jest widoczny? –

Odpowiedz

7

Fakt, że zwiększa się rozmiar pliku to dobre wskazanie, że znak wodny dodaje. Głównym problemem jest to, że dodajesz znak wodny poza widocznym obszarem strony. Zobacz How to position text relative to page using iText?

Trzeba coś takiego:

Rectangle pagesize = reader.GetCropBox(pageIndex); 
if (pagesize == null) 
    pagesize = reader.GetMediaBox(pageIndex); 
img.SetAbsolutePosition(
    pagesize.GetLeft(), 
    pagesize.GetBottom()); 

czyli: jeśli chcesz dodać obraz w lewym dolnym rogu strony. Możesz dodać przesunięcie, ale upewnij się, że przesunięcie w kierunku X nie przekracza szerokości strony, a przesunięcie w kierunku y nie przekracza wysokości strony.

+1

W iText LGPL ver 4.1.6 w Nuget, nie ma 'pdfReader.GetMediaBox (pageNumber)', zamiast tego istnieje 'pdfReader.GetPageSize (pageNumber)'. Również 'pageIndex' daje wrażenie, że zaczyna się od' 0'. Ponieważ zaczyna się od '1',' pageNumber' byłoby lepsze. –

+0

@RosdiKasim natomiast nie zgadzam się, że PageIndex zakłada indeksowanie 0 oparte, masz rację, że GetMediaBox() jest niewłaściwy sposób .... należy dodać tę zmianę do odpowiedzi tak będzie bardziej poprawne. GetCropBox jest również poprawną obudową getCropBox – Arkaine55

0

Mimo że nie znam specyfiki iTextSharp, prawdopodobnie na stronach, na których obraz nie jest wyświetlany, poprzednia treść PDF zmodyfikowała bieżącą macierz transformacji tak, że wszystko, co umieścisz na stronie, zostało przeniesione poza stronę.

ta może być ustalona przez emisję operatora gsave przed zawartości strony pierwotnej i emitowania operatora grestore po stronie pierwotnej zawartości (ale przed twoich). To jednak może nie naprawić wszystkich przypadków z dokumentem PDF, który modyfikuje WZT ma gsave i bez grestore. To nie powinno się zdarzać w teorii, zgodnie ze specyfikacją PDF:

Wystąpienie operatorów q i Q musi być zrównoważone w danym strumieniu treści (lub w sekwencji strumieni określonych w tablicy Contents słownika strony).

ale mogę powiedzieć z doświadczenia, że ​​tak nie jest w praktyce.

+0

OP używa 'pdfStamper.GetOverContent', co oznacza, że ​​iText otacza istniejący strumień treści w ** q ** i ** Q ** i dodaje dodatki OP później, poza ** q ... Q ** i w związku z tym nie podlega żadnym zmianom WZT. Zakładam, że @Alexis ma rację w swoim założeniu. – mkl