iTextSharp watermark multiline text - itext

I have seen answers to question of how to add text watermark to an existing PDF document using iTextSharp. My question is how can we do multiline text. Is there a way to do this without having multiple PdfContentByte defined. I have tried to insert a newline character with no luck.
Here is the code from the internet. I just added
pdfData.ShowTextAligned(Element.ALIGN_CENTER, editDate, (pageRectangle.Width / 2) + 100, (pageRectangle.Height / 2) - 100, 45);
as the second line to get the second line of the watermark, it works but uses same parameters (color, size, etc.) as the first.
iTextSharp.text.Rectangle pageRectangle = PDFreader.GetPageSizeWithRotation(1);
//pdfcontentbyte object contains graphics and text content of page returned by pdfstamper
PdfContentByte pdfData = stamper.GetOverContent(1);
//create fontsize for watermark
pdfData.SetFontAndSize(BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED), 120);
//create new graphics state and assign opacity
PdfGState graphicsState = new PdfGState();
graphicsState.FillOpacity = 0.2F;
//set graphics state to pdfcontentbyte
pdfData.SetGState(graphicsState);
//set color of watermark
pdfData.SetColorFill(iTextSharp.text.Color.BLUE);
//indicates start of writing of text
pdfData.BeginText();
//show text as per position and rotation
pdfData.ShowTextAligned(Element.ALIGN_CENTER, "E D I T E D" , (pageRectangle.Width / 2), (pageRectangle.Height / 2), 45);
pdfData.ShowTextAligned(Element.ALIGN_CENTER, editDate, (pageRectangle.Width / 2) + 100, (pageRectangle.Height / 2) - 100, 45);
//call endText to invalid font set
pdfData.EndText();

Related

Append Multiple Images to a PDF Page with LEADTOOLS

Is there some way to add multiple (2, 3 or 4) images to the same page of a PDF file using the LEADTOOLS C API?
The L_SaveBitmap() function takes a SAVEFILEOPTION parameter, where the PageNumber can be set, but setting this to a value greater than 1 causes a new page to be appended. Instead, a value of 1 or 0 causes the file to be overwritten.
The L_SaveFile() function performs similarly; setting the SAVEFILE_MULTIPAGE flag causes a new page to be always appended.
The L_PdfComp..() functions don't seem to be capable of handling pages at all.
Do the MRC functions support handling of pages, i.e. specify which page each image will be stored in? Also, is the file generated of standard PDF format, or it is LEAD-specific?
Any help would be highly appreciated.
To address the part about “is the file generated of standard PDF format, or it is LEAD-specific”, any PDF file saved by any and all LEADTOOLS functions is a standard PDF file, and it should be possible to open it using any standard PDF viewer.
However, if you wish to append or replace pages using L_SaveBitmap(), the existing PDF file must be a raster-based PDF similar to the output of L_SaveBitmap() itself.
To work with more general types of PDF, other LEADTOOLS functions can be used, such as the .NET PDFFile class and PDFDocument class.
The C/C++ code below performs overwriting (creating a new file), appending and replacing a specific page. It also shows how to place 2 images inside a single PDF page.
The code segments can be combined into one function to test them with any 4 input image files.
First, create a file with one page, overwriting it if it exists:
// Create file with first page
BITMAPHANDLE page1 = { 0 };
L_LoadBitmap(page1_file, &page1, sizeof BITMAPHANDLE, 24, ORDER_BGR, NULL, NULL);
page1.XResolution = page1.YResolution = BITMAPHEIGHT(&page1) / 11; //set the DPI to cause 11 inch height.
L_SaveBitmap(outputPdf_file, &page1, FILE_RAS_PDF_LZW, 24, 0, NULL);
L_FreeBitmap(&page1);
Next, load an image and append it as a second page to the same PDF file:
// Append second page
BITMAPHANDLE page2 = { 0 };
L_LoadBitmap(page2_file, &page2, sizeof BITMAPHANDLE, 24, ORDER_BGR, NULL, NULL);
SAVEFILEOPTION SaveOptions = { 0 };
L_GetDefaultSaveFileOption(&SaveOptions, sizeof SAVEFILEOPTION);
SaveOptions.PageNumber = 2;
page2.XResolution = page2.YResolution = BITMAPHEIGHT(&page2) / 11; //set the DPI to cause 11 inch height.
L_SaveBitmap(outputPdf_file, &page2, FILE_RAS_PDF_LZW, 24, 0, &SaveOptions);
L_FreeBitmap(&page2);
Finally, load 2 images, combine them into one image and replace the first page with the image combined from the newly-loaded 2 images:
BITMAPHANDLE page2_1 = { 0 }, page2_2 = { 0 };
// Load 2 iamges for one page
L_LoadBitmap(page2_1_file, &page2_1, sizeof BITMAPHANDLE, 24, ORDER_BGR, NULL, NULL);
L_LoadBitmap(page2_2_file, &page2_2, sizeof BITMAPHANDLE, 24, ORDER_BGR, NULL, NULL);
L_UINT w = max(BITMAPWIDTH(&page2_1), BITMAPWIDTH(&page2_2));
L_UINT h = BITMAPHEIGHT(&page2_1) + BITMAPHEIGHT(&page2_2);
BITMAPHANDLE combinedPage = { 0 };
// Create empty bitmap
L_CreateBitmap(&combinedPage, sizeof BITMAPHANDLE, TYPE_CONV, w, h, 24, ORDER_BGR, NULL, BOTTOM_LEFT, NULL, 0);
// Copy the first image into the empty bitmap
L_CombineBitmap(&combinedPage, 0, 0, BITMAPWIDTH(&page2_1), BITMAPHEIGHT(&page2_1), &page2_1, 0, 0, CB_DST_0 | CB_OP_ADD | CB_RAWCOMBINE, 0);
L_FreeBitmap(&page2_1);
// Copy the second image below the first image
L_CombineBitmap(&combinedPage, 0, BITMAPHEIGHT(&page2_1), BITMAPWIDTH(&page2_2), BITMAPHEIGHT(&page2_2), &page2_2, 0, 0, CB_DST_0 | CB_OP_ADD | CB_RAWCOMBINE, 0);
L_FreeBitmap(&page2_2);
SaveOptions.PageNumber = 1;
SaveOptions.Flags |= ESO_REPLACEPAGE; // add the replace flag to put the combined image instead of the old page1
combinedPage.XResolution = combinedPage.YResolution = BITMAPHEIGHT(&combinedPage) / 11; //set the DPI to cause 11 inch height.
L_SaveBitmap(outputPdf_file, &combinedPage, FILE_RAS_PDF_LZW, 24, 0, &SaveOptions);
L_FreeBitmap(&combinedPage);
The following part was added after the answer got accepted, to address a comment:
It is possible to insert multiple images into a single PDF page without combining them first, but not using the L_SaveBitmap() function. Instead, the Document Writer functions need to be used as shown in the following code sample.
The code below loads 2 images and puts them into an EMF memory file. It then draws an ellipse on top of them to show that any Windows GDI graphics object can be added (for example, you can add text using TextOut() or other GDI functions). After that, the EMF page is saved as PDF using LEADTOOLS Document Writer.
BITMAPHANDLE image1 = { 0 }, image2 = { 0 };
// Load 2 iamges for one page
L_LoadBitmap(image1_file, &image1, sizeof BITMAPHANDLE, 24, ORDER_BGR, NULL, NULL);
L_LoadBitmap(image2_file, &image2, sizeof BITMAPHANDLE, 24, ORDER_BGR, NULL, NULL);
L_UINT w = max(BITMAPWIDTH(&image1), BITMAPWIDTH(&image2));
L_UINT h = BITMAPHEIGHT(&image1) + BITMAPHEIGHT(&image2);
// Create a memory metafile and paint both bitmaps in it
HDC hdcEmf = CreateEnhMetaFile(NULL, NULL, NULL, NULL);
Rectangle(hdcEmf, 0, 0, w, h);
RECT rc1 = { 0, 0, BITMAPWIDTH(&image1), BITMAPHEIGHT(&image1) };
L_PaintDC(hdcEmf, &image1, NULL, NULL, &rc1, NULL, SRCCOPY);
L_FreeBitmap(&image1);
RECT rc2 = { 0, BITMAPHEIGHT(&image1), BITMAPWIDTH(&image2), BITMAPHEIGHT(&image1) + BITMAPHEIGHT(&image2) };
L_PaintDC(hdcEmf, &image2, NULL, NULL, &rc2, NULL, SRCCOPY);
L_FreeBitmap(&image2);
Ellipse(hdcEmf, w / 4, h / 4, w * 3 / 4, h * 3 / 4);
HENHMETAFILE hemf = CloseEnhMetaFile(hdcEmf);
DOCWRTPDFOPTIONS pdf = { 0 };
L_DOUBLE dTextScale = 0.5;
DOCUMENTWRITER_HANDLE hDocument = 0;
DOCWRTEMFPAGE Page = { 0 };
pdf.PdfProfile = DOCWRTPDFPROFILE_PDF;
pdf.Options.uStructSize = sizeof(pdf);
pdf.Options.nDocumentResolution = 300;
// Setup empty page size based on images size
pdf.Options.dEmptyPageWidth = w / 300.0;
pdf.Options.dEmptyPageHeight = h / 300.0;
pdf.Options.nEmptyPageResolution = 300;
L_DocWriterInit(&hDocument, outputPdf_file, DOCUMENTFORMAT_PDF, &pdf, NULL, NULL);
Page.hEmf = hemf;
Page.pdwTextScale = &dTextScale;
L_DocWriterAddPage(hDocument, DOCWRTPAGETYPE_EMF, (L_VOID*)&Page);
L_DocWriterFinish(hDocument);
DeleteEnhMetaFile(hemf);

Gmap.Net save image around selected marker

I have an application with GMap.Net showing various markers. I know how to take a screen shot of the current map and markers:
Dim sImageName As String = DateTime.Now.ToString(Format("yyyyMMdd-HHmmss")) & ".png"
Dim ThisMap As New Bitmap(Form2.myMap.Width, Form2.myMap.Height)
Form2.myMap.DrawToBitmap(ThisMap, New Rectangle(0, 0, Form2.myMap.Width, Form2.myMap.Height))
ThisMap.Save(sImagesFolder & sImageName)
What I would like to do is create an image for a selected marker. Instead of the image being the entire map shown on screen, it would center on the marker and show 100 pixels in each direction.
Does anyone know how to do that?
This is what I tried, but it gives me a blank image-- nothing shows up. I feel like this should be working...
Private Sub MyMap_OnMarkerClick(item As GMapMarker, e As Windows.Forms.MouseEventArgs) Handles myMap.OnMarkerClick
SelMarkerX = e.X
SelMarkerY = e.Y
Dim sImageName As String = DateTime.Now.ToString(Format("yyyyMMdd-HHmmss")) & ".png"
Dim ThisMap As New Bitmap(140,100)
myMap.DrawToBitmap(ThisMap, New Rectangle(SelMarkerX - 70, SelMarkerY - 50, 140, 100))
ThisMap.Save(sImagesFolder & sImageName)
End Sub
I just don't get it. If I write:
myMap.DrawToBitmap(ThisMap, New Rectangle(0, 0, 140, 100)
then I get what you might expect. I get the upper left corner of the existing map from 0 to 140 horizontally and 0 to 100 vertically. If I change it to this:
myMap.DrawToBitmap(ThisMap, New Rectangle(10, 0, 140, 100)
then I get 0 to 130 horizontally and not 10 to 140.
Well, I couldn't figure out how to do it with Gmap, so I wondered if I could crop it outside of Gmap and apparently that is common. Here is the code I used.
Dim ThisMap As New Bitmap(Form2.myMap.Width, Form2.myMap.Height)
Form2.myMap.DrawToBitmap(ThisMap, New Rectangle(0, 0, Form2.myMap.Width, Form2.myMap.Height))
ThisMap.Save(sImagesFolder & sImageName)
Dim LocX = SelMarkerX - 160 'x cord. of where crop starts
Dim LocY = SelMarkerY - 120 'y cord. of where crop starts
Dim CropW = 320 'Crop width
Dim CropH = 240 'Crop height
Dim CropRect As New Rectangle(LocX, LocY, CropW, CropH)
Dim OriginalImage = ThisMap
Dim CropImage = New Bitmap(CropRect.Width, CropRect.Height)
Using grp = Graphics.FromImage(CropImage)
grp.DrawImage(OriginalImage, New Rectangle(0, 0, CropRect.Width, CropRect.Height), CropRect, GraphicsUnit.Pixel)
CropImage.Save(sImagesFolder & sImageName)
End Using

Unable to create next pages based on content in PDF generation from Template itextsharp

I am using itextsharp for creating PDF . But when my content goes beyong 1 page it does not create and append text to next page. Below is my source code. Cannot identify whats goin wrong with this. Please guide.
Dim pdfTemplate As String = "C:\Program Files\mycrm\Documents\Client\Statement_.pdf"
Dim newFile As String = "D:\test.pdf"
Dim pdfReader As New PdfReader(pdfTemplate)
Dim pdfStamper As New PdfStamper(pdfReader, New FileStream(newFile, FileMode.Create))
Dim pdfFormFields As AcroFields = pdfStamper.AcroFields
pdfFormFields.SetField("[CLIENT NAME]", "siddhesh")
'For adding table
Dim PdfTable As New PdfPTable(2)
Dim PdfPCell As PdfPCell = Nothing
For column As Integer = 0 To 1
PdfPCell = New PdfPCell(New Phrase(New Chunk(column.ToString())))
PdfTable.AddCell(PdfPCell)
Next
For rows As Integer = 0 To 100
For column As Integer = 0 To 1
PdfPCell = New PdfPCell(New Phrase(New Chunk(rows.ToString() + column.ToString())))
PdfTable.AddCell(PdfPCell)
Next
Next
PdfTable.HeaderRows = 1
pdfStamper.FormFlattening = True
PdfTable.SetTotalWidth(New Single() {
(iTextSharp.text.PageSize.A4.Rotate().Height - 25) / 10,
(iTextSharp.text.PageSize.A4.Rotate().Height - 25) / 10
})
PdfTable.WriteSelectedRows(0, 50, 35, 460, pdfStamper.GetOverContent(1)) 'X Y départ en bas à gauche? plus yPos est au plus le texte est haut
PdfTable.CompleteRow()
pdfStamper.Close()
MsgBox("Exported")
PdfTable.WriteSelectedRows is documented as
/**
* Writes the selected rows to the document.
*
* #param rowStart the first row to be written, zero index
* #param rowEnd the last row to be written + 1. If it is -1 all the
* rows to the end are written
* #param xPos the x write coodinate
* #param yPos the y write coodinate
* #param canvas the <CODE>PdfContentByte</CODE> where the rows will
* be written to
* #return the y coordinate position of the bottom of the last row
*/
virtual public float WriteSelectedRows(int rowStart, int rowEnd, float xPos, float yPos, PdfContentByte canvas)
You use
PdfTable.WriteSelectedRows(0, 50, 35, 460, pdfStamper.GetOverContent(1)) 'X Y départ en bas à gauche? plus yPos est au plus le texte est haut
Thus, you explicitly only draw the first 50 rows of your table over page 1 and completely ignore the remaining rows.
Your observation, therefore,
when my content goes beyong 1 page it does not create and append text to next page.
is exactly what is to be expected.
To draw all the rows, you can iterate and draw rows 50..99 over page 2, 100..149 over page 3, etc. PdfPTable has a property Size returning the number of rows in the table; you can use this to determine how often you have to loop.
If the document you loaded into your PdfReader does not have enough pages, you can add extra blank pages using PdfStamper.InsertPage.

ItextSharp - Add text watermark on separate lines

I am trying to add a watermak on a pdf file with itextsharp 5.1.2.0 .
I want the watermark to be in the center of the page, with a 45° angle, with a border around these lines.
Here is my code :
for (int i = 1; i <= reader.NumberOfPages; i++)
{
iTextSharp.text.Rectangle pageSize = reader.GetPageSizeWithRotation(i);
PdfContentByte pdfPageContents;
pdfPageContents = pdfStamper.GetOverContent(i);
pdfPageContents.BeginText();
PdfGState gstate = new PdfGState();
gstate.FillOpacity = 0.4f;
gstate.StrokeOpacity = 0.4f;
pdfPageContents.SaveState();
pdfPageContents.SetGState(gstate);
BaseFont baseFont = BaseFont.CreateFont(BaseFont.HELVETICA_BOLD, Encoding.ASCII.EncodingName, false);
pdfPageContents.SetRGBColorFill(255, 0, 0);
double radians = Math.Atan2(pageSize.Height, pageSize.Width);
float textAngle = radians * (180 / Math.PI);
pdfPageContents.ShowTextAligned(PdfContentByte.ALIGN_CENTER, "Phrase 1 This is Phrase 2 and must be centered below phrase 1" , pageSize.Width / 2, pageSize.Height / 2, textAngle);
//pdfPageContents.ShowTextAligned(PdfContentByte.ALIGN_CENTER, "Phrase 1", pageSize.Width / 2, pageSize.Height / 2, textAngle);
//pdfPageContents.ShowTextAligned(PdfContentByte.ALIGN_CENTER, "This is Phrase 2 and must be centered below phrase 1", pageSize.Width / 2 + 20 , pageSize.Height / 2 - 20, textAngle);
}
This adds the watermark on one line.
I am able to have two lines with the commented code.
What i dont like are the hardcoded values for the position for the second line.
I am sure there must be a better way of achieving this.
Regarding the border i did not manage to add it around the lines.
If someone can help me with this case .
Thanks
basically what I do for my project is as under... here font_size and style are the variables... also llx, lly, urx,ury are variable for the the corrdinates position and size.. in alignment variable, you can set the alignment easily....
for opacity your code will work fine(you can add state options)
Dim Font = New Font(arial, FONT_SIZE, STYLE, iTextSharp.text.Color.BLACK )
dim text = GetRowValue(row, "CONTROL_MAP")
Dim ct As ColumnText = New ColumnText(pdf_cb)
ct.SetSimpleColumn(LLX, LLY, URX, URY, FONT_SIZE, ALIGNMENT)
ct.SetText(New Paragraph(0, text, Font))
ct.Go()

Changing the font color and size when using FontSelector

I am using iText5 (Java) to write a PDF which may contain Chinese characters. So I am using FontSelector to process the String and this works fine.
Now the problem is that if there are 2 strings
String str1 = "Hello Test1";
String str2 = "Hello Test2";
I need to write str1 witch Font Color = Blue and size = 10, whereas str2 with Font Color = Gray and size = 25.
I am not able to figure out how to achieve this using FontSelector.
Any help is appreciated.
That's easy. Here you have a code snippet that adds the Times Roman text in Blue and the Chinese text in Red:
FontSelector selector = new FontSelector();
Font f1 = FontFactory.getFont(FontFactory.TIMES_ROMAN, 12);
f1.setColor(BaseColor.BLUE);
Font f2 = FontFactory.getFont("MSung-Light",
"UniCNS-UCS2-H", BaseFont.NOT_EMBEDDED);
f2.setColor(BaseColor.RED);
selector.addFont(f1);
selector.addFont(f2);
Phrase ph = selector.process(TEXT);
In your case you need two FontSelectors.
FontSelector selector1 = new FontSelector();
Font f1 = FontFactory.getFont(FontFactory.TIMES_ROMAN, 12);
f1.setColor(BaseColor.BLUE);
selector1.addFont(f1);
Phrase ph = selector1.process(str1);//First one
FontSelector selector2 = new FontSelector();
Font f2 = FontFactory.getFont(FontFactory.TIMES_ROMAN, 12);
f2.setColor(BaseColor.GRAY);
selector2.addFont(f2);
Phrase ph = selector2.process(str2);//Second one
you can do it in another way in my case i use 14 for header and 10 for data in tabular report
private Font fHeader;
private Font f1;
BaseFont bf = BaseFont.createFont(Constants.Settings.ARIAL_FONT, BaseFont.IDENTITY_H, true);
f1 = new Font(bf, 10);
fHeader= new Font(bf,14);
PdfPCell cell = new PdfPCell();
//for report header
cell = new PdfPCell(new Phrase(reportKingdomData + "\n" + departmentData + " " + username + " \n " + reportHeader + " \n ", fHeader));
//and for background color
cell .setBackgroundColor(new GrayColor(0.40f));//if 0.10f will be closer to black