Find SSRS Report Design in Ax

Find SSRS Report Design in Ax

Description:-

In this example we will see how to find ssrs report design through code or using x++ in dynamics ax. Here is the demo example to find ssrs report design using X++.

Code:-

static void FindSRSReportDesign(Args _args)
{
    #AOT
    TreeNode rootNode;
    TreeNode reportNode, designsNode, designNode;
    TreeNodeIterator it;
    TreeNodeName nodeName;
    TreeNodeType nodeType;
    ;
    rootNode = TreeNode::findNode(#SSRSReportsPath);
    if(rootNode)
    {
        reportNode = rootNode.AOTfindChild('VendBaseData');
        if(reportNode)
        {
            designsNode = reportNode.AOTfindChild('Designs');
            if(designsNode)
            {
                it = designsNode.AOTiterator();
                designNode = it.next();
                while(designNode)
                {
                    nodeName = designNode.treeNodeName();
                    nodeType = designNode.treeNodeType();
                    info('name: ' + nodeName + ' type: ' + nodeType.toString());
                    designNode = it.next();
                }
            }
        }
    }
}
 
Get Infolog details from code in Ax

Get Infolog details from code in Ax

Description:-

The infolog class has a "copy" and a "cut" method that return the contents of the infolog, in container form. The elements in the container are containers themselves, each one corresponding to a line in the infolog. So you get the container, loop over it, and for each iteration you can grab the sub-container and extract the details like the exception type, action class, helptext, etc.

Example:-

static void InfologParse12(Args _args)
{
    container   infologCon, infoline;
    Exception   exception;
    int         i;
    str         message;
    str         helpURL;
    ClassName   actionClassName;
    container   actionClassOptions;
    ;

    // Put test data in infolog
    setPrefix("First Prefix");
    error("test error");
    warning("test warning");
    
    setPrefix("One more level");
    info("infolog!");
    
    // Get the infolog data and clear the messages (cut)
    infologCon = infolog.cut();

    for(i=1; i<=conLen(infologCon); i++)
    {
        infoline = conPeek(infologCon, i);

        exception = conPeek(infoline, 1);
        message = conPeek(infoline, 2);
        helpURL = conLen(infoline) > 2 ? conPeek(infoline, 3) : '';
        if(conLen(infoline) > 3 && conPeek(infoline, 4))
        {
            actionClassName    = classId2Name(conPeek(infoline, 4));
            actionClassOptions = conPeek(infoline, 5);
        }

        info(strFmt("Type: %1; Prefix: %2; Message: %3",
            exception,
            // replace the \t by / so we can see all prefixes
            strReplace(message, '\t', '/'),
            // copy the message from the last occurance of the \t to the end
            subStr(message,
                strScan(message, '\t',
                strLen(message),
                -strLen(message)) + 1,
                strLen(message))));
    }
}

iTextSharp - Page Layout with Columns in Asp.Net

Description:-

Most often, when working with columns you will want to add multiple columns for text layout, similar to a newspaper. ITextSharp has a MultiColumnText object which makes this pretty simple. All you need to tell it is where the leftmost column should start from along the X-axis, where that rightmost column should end, what space you would like between the columns and how many columns you want. The following adds 2 columns to a page, and then adds a paragraph 8 times:  

string pdfpath = Server.MapPath("PDFs");
string imagepath = Server.MapPath("Columns");
Document doc = newDocument();
try
{
  PdfWriter.GetInstance(doc, newFileStream(pdfpath + "/Columns.pdf", FileMode.Create));
  doc.Open();
  Paragraph heading = newParagraph("Page Heading", newFont(Font.HELVETICA, 28f, Font.BOLD));
  heading.SpacingAfter = 18f;
  doc.Add(heading);
  string text = @"Loremipsum dolor sit amet, consectetueradipiscingelit. Suspendisseblanditblanditturpis.Nam in lectusut dolor consectetuerbibendum.Morbinequeipsum, laoreet id; dignissimet, viverra id, mauris. Nullamauriselit, consectetuer sit amet, accumsaneget, congue ac, libero. Vivamussuscipit.Nuncdignissimconsectetuerlectus.Fusceelit nisi; commodonon, facilisisquis, hendreriteu, dolor? Suspendisseeleifend nisi ut magna.Phasellus id lectus! Vivamuslaoreetenimet dolor. Integer arcumauris, ultriciesvel, portaquis, venenatis at, libero.Donecnibhest, adipiscing et, ullamcorper vitae, placerat at, diam. Integer ac turpisvel ligula rutrumauctor! Morbiegestaserat sit amet diam. Ututipsum? Aliquam non sem. Nullarisuseros, mollisquis, blanditut; luctuseget, urna.Vestibulumvestibulumdapibuserat.Proinegestasleo a metus?";
  MultiColumnText columns = newMultiColumnText();

  //float left, float right, float gutterwidth, int numcolumns
  columns.AddRegularColumns(36f, doc.PageSize.Width - 36f, 24f, 2);
 
  Paragraphpara = newParagraph(text, newFont(Font.HELVETICA, 8f));
  para.SpacingAfter = 9f;
  para.Alignment = Element.ALIGN_JUSTIFIED;
  for (int i = 0; i < 8; i++)
  {
    columns.AddElement(para);
  }
 
  doc.Add(columns);
}
catch (Exception ex)
{
  //Log(ex.Message);
}
finally
{
  doc.Close();
}  

The result shows how the text just flowed from one column to another once the first column was filled.

AddRegularColumns() will set each column at exactly the same width. AddSimpleColumn() allows you to specify the width of individual columns, which means that you can work with irregularly sized columns:  

columns.AddSimpleColumn(36f, 170f);
columns.AddSimpleColumn(194f, doc.PageSize.Width - 36f);  

The code above replaces the AddRegularColumn() call in the preceding block and creates two separate column objects. The first starts at the left margin (36 points in from the left edge) and is 2 inches wide (170 - 36 = 144 points). The second column starts 24 points (1/3 of an inch) further over and butts up against the right hand margin.


Adding other elements such as images and tables is straightforward: 

string pdfpath = Server.MapPath("PDFs");
string pdfpath = Server.MapPath("PDFs");
string imagepath = Server.MapPath("Images");
Document doc = new Document();
try
{
  PdfWriter.GetInstance(doc, new FileStream(pdfpath + "/Columns1.pdf", FileMode.Create));
  doc.Open();
  Paragraph heading = new Paragraph("Page Heading", newFont(Font.HELVETICA, 28f, Font.BOLD));
  heading.SpacingAfter = 18f;
  doc.Add(heading);
  string text = @"Loremipsum dolor sit amet, consectetueradipiscingelit. Suspendisseblanditblanditturpis.Nam in lectusut dolor consectetuerbibendum.Morbinequeipsum, laoreet id; dignissimet, viverra id, mauris. Nullamauriselit, consectetuer sit amet, accumsaneget, congue ac, libero. Vivamussuscipit.Nuncdignissimconsectetuerlectus.Fusceelit nisi; commodonon, facilisisquis, hendreriteu, dolor? Suspendisseeleifend nisi ut magna.Phasellus id lectus! Vivamuslaoreetenimet dolor. Integer arcumauris, ultriciesvel, portaquis, venenatis at, libero.Donecnibhest, adipiscing et, ullamcorper vitae, placerat at, diam. Integer ac turpisvel ligula rutrumauctor! Morbiegestaserat sit amet diam. Ututipsum? Aliquam non sem. Nullarisuseros, mollisquis, blanditut; luctuseget, urna.Vestibulumvestibulumdapibuserat.Proinegestasleo a metus?";
  MultiColumnText columns = new MultiColumnText();
  columns.AddSimpleColumn(36f, 336f);
  columns.AddSimpleColumn(360f, doc.PageSize.Width - 36f);

  Paragraphpara = new Paragraph(text, new Font(Font.HELVETICA, 8f));
  para.SpacingAfter = 9f;
  para.Alignment = Element.ALIGN_JUSTIFIED;

  PdfPTable table = new PdfPTable(3);
  float[] widths = new float[] { 1f, 1f, 1f };
  table.TotalWidth = 300f;
  table.LockedWidth = true;
  table.SetWidths(widths);
  PdfPCell cell = new PdfPCell(newPhrase("Header spanning 3 columns"));
  cell.Colspan = 3;
  cell.HorizontalAlignment = 0;
  table.AddCell(cell);
  table.AddCell("Col 1 Row 1");
  table.AddCell("Col 2 Row 1");
  table.AddCell("Col 3 Row 1");
  table.AddCell("Col 1 Row 2");
  table.AddCell("Col 2 Row 2");
  table.AddCell("Col 3 Row 2");

  iTextSharp.text.Image jpg = iTextSharp.text.Image.GetInstance(imagepath + "/Jellyfish.jpg");
  jpg.ScaleToFit(300f, 300f);
  jpg.SpacingAfter = 12f;
  jpg.SpacingBefore = 12f;

  columns.AddElement(para);
  columns.AddElement(table);
  columns.AddElement(jpg);
  columns.AddElement(para);
  columns.AddElement(para);
  columns.AddElement(para);
  columns.AddElement(para);
  doc.Add(columns);
}
catch (Exception ex)
{
  //Log(ex.Message);
}
finally
{
  doc.Close();
} 

The example above takes a table and images from previous tutorials, and adds them together with the paragraph to the columns. the first column is 300 points wide, and the second one takes up the remainder of the page width.

MultiColumnText is great for creating columns without too much code, but it lacks an element of control. ColumnText provides much more, but requires more code. The following sample shows ColumnText being used to create irregular columns, in that the first one has chunk taken from the top left corner to accommodate an image which is shown here in the resulting PDF:


string pdfpath = Server.MapPath("PDFs");
string imagepath = Server.MapPath("Images");
FontFactory.RegisterDirectory("C:\\WINDOWS\\Fonts");

Document doc = new Document();
Font font1 = new Font(FontFactory.GetFont("adobe garamond pro", 36f, Color.GRAY));
Font font2 = new Font(Font.TIMES_ROMAN, 9f);
doc.SetMargins(45f, 45f, 60f, 60f);
try
{
  FileStream output = new FileStream(pdfpath + "/IrregularColumns.pdf", FileMode.Create);
  PdfWriter writer = PdfWriter.GetInstance(doc, output);
  doc.Open();
  PdfContentBytecb = writer.DirectContent;
  ColumnTextct = new ColumnText(cb);
  ct.Alignment = Element.ALIGN_JUSTIFIED;

  Paragraph heading = new Paragraph("Chapter 1", font1);
  heading.Leading = 40f;
  doc.Add(heading);
  iTextSharp.text.Image L = iTextSharp.text.Image.GetInstance(imagepath + "/ajax-loader(1).gif");
  L.SetAbsolutePosition(doc.Left, doc.Top - 180);
  doc.Add(L);

  ct.AddText(new Phrase("oremipsum dolor sit amet, consectetueradipiscingelit. Suspendisseblanditblanditturpis.Nam in lectusut dolor consectetuerbibendum.Morbinequeipsum, laoreet id; dignissimet, viverra id, mauris. Nullamauriselit, consectetuer sit amet, accumsaneget, congue ac, libero. Vivamussuscipit.Nuncdignissimconsectetuerlectus.Fusceelit nisi; commodonon, facilisisquis, hendreriteu, dolor? Suspendisseeleifend nisi ut magna.Phasellus id lectus! Vivamuslaoreetenimet dolor. Integer arcumauris, ultriciesvel, portaquis, venenatis at, libero.Donecnibhest, adipiscing et, ullamcorper vitae, placerat at, diam. Integer ac turpisvel ligula rutrumauctor! Morbiegestaserat sit amet diam. Ututipsum? Aliquam non sem. Nullarisuseros, mollisquis, blanditut; luctuseget, urna.Vestibulumvestibulumdapibuserat.Proinegestasleo a metus?\n\n", font2));
  
  ct.AddText(new Phrase("Vivamusenim nisi, mollis in, sodalesvel, convallis a, augue? Proin non enim.Nullamelementumeuismoderat.Aliquammalesuadaeleifend quam! Nullafacilisi.Aeneanutturpis ac esttempormalesuada. Maecenas scelerisqueorci sit ametauguelaoreet tempus. Duisinterdumestuteros. Fusce dictum dignissimelit.Morbi at dolor.Fusce magna.Nullatellusturpis, mattisut, eleifend a, adipiscing vitae, mauris.Pellentesquemattislobortis mi.\n\n", font2));

  ct.AddText(new Phrase("Nullam sit ametmetusscelerisquediamhendreritporttitor. Aeneanpellentesque, lorem a consectetuerconsectetuer, nuncmetushendrerit quam, mattisultricesloremtelluslaciniamassa. Aliquam sit ametodio. Proinmauris.Integer dictum quam a quam accumsanlacinia.Pellentesquepulvinarfeugiateros.Suspendisserhoncus.Sedconsectetuerleoeu nisi. Suspendissemassa! Sedsuscipit lacus sit ametelit! Aliquamsollicitudincondimentumturpis.Nuncutaugue! Maecenas eueros.Morbi in urnaconsectetueripsumvehiculatristique.\n\n", font2));
  
  ct.AddText(new Phrase("Donecimperdietpurusvel ligula. Vestibulumtempor, odioutscelerisqueeleifend, nullasapienlaoreet dui; velaliquamarculiberoeu ante.Curabiturrutrumtristique mi. Sedlobortisiaculisarcu.Suspendissemauris.Aliquammetus lacus, elementumquis, mollis non, consequatnec, tortor.\n", font2));

  ct.AddText(new Phrase("Quisque id diam. Utegestasleo a elit. Nulla in metus.Aliquamiaculisturpis non augue.Donec a nunc?Phaselluseueros.Nam luctus.Duiseu mi. Utmollis.Nullafacilisi.Loremipsumdolor sitamet, consectetueradipiscingelit. Class aptenttacitisociosquadlitoratorquent per conubia nostra, per inceptoshimenaeos.Aeneanpede.Nullafacilisi.Vestibulummattisadipiscingnulla.Praesentorci ante, mattis in, cursuseget, posueresed, mauris.\n\n", font2));

  ct.AddText(new Phrase("Nullafacilisi. Nuncaccumsanrisusaliquet quam. Nam pellentesque! Aeneanporttitor.Aeneancongueullamcorpervelit.Phasellussuscipitplacerattellus.Vivamusdiamodio, tempus quis, suscipit a, dictum eu; lectus.Sedvelnisl.Utinterdumurnaeunibh.Praesentvehicula, orci id venenatisultrices, maurisurnamollis lacus, etblanditodio magna at enim. Pellentesqueloremfelis, ultricesquis, gravidased, pharetra vitae, quam.Maurisliberoipsum, pharetra a, faucibusaliquet, pellentesque in, mauris.Cras magna neque, interdumvel, variusnec; vulputate at, erat. Quisque vitae urna.Suspendissepotenti.Nullaluctuspurus at turpis! Vestibulum vitae dui.Nullamodio.\n\n", font2));
  
  ct.AddText(new Phrase("Vestibulum ante ipsumprimis in faucibusorciluctus et ultricesposuerecubiliaCurae; Sedeget mi at semiaculishendrerit. Nullafacilisi.Etiamsedelit.In viverradapibussapien.Aliquam nisi justo, ornarenon, ultricies vitae, aliquam sit amet, risus! Cum sociisnatoquepenatibusetmagnis dis parturient montes, nasceturridiculus mus. Phasellusrisus. Vestibulumpretiumaugue non mi. Sed magna.In hachabitasseplateadictumst.Quisquemassa. Etiamviverradiampharetra ante.Phasellusfringillavelitutodio! Nam necnulla.\n\n", font2));

  ct.AddText(new Phrase("Integer augue. Morbiorci.Sedquisnibh.Nullam ac magna id leofaucibusornare. Vestibulumegetlectus sit ametnuncfacilisisbibendum. Donecadipiscingconvallis mi. Cumsociisnatoquepenatibus et magnis dis parturient montes, nasceturridiculus mus. Vivamusenim. Mauris ligula lorem, pellentesquequis, semper sed, tristique sit amet, justo.Suspendissepotenti.Proin vitae enim.Morbi et nisi sit ametsapienve.\n\n", font2));

  float gutter = 15f;
  float colwidth = (doc.Right - doc.Left - gutter) / 2;
  float[] left = { doc.Left + 90f , doc.Top - 80f,
  doc.Left + 90f, doc.Top - 170f,
  doc.Left, doc.Top - 170f,
  doc.Left ,doc.Bottom };

  float[] right = { doc.Left + colwidth, doc.Top - 80f,
  doc.Left + colwidth, doc.Bottom };

  float[] left2 = { doc.Right - colwidth, doc.Top - 80f,
  doc.Right - colwidth, doc.Bottom };

  float[] right2 = {doc.Right, doc.Top - 80f,
  doc.Right, doc.Bottom };

  int status = 0;
  int i = 0;
  //Checks the value of status to determine if there is more text
  //If there is, status is 2, which is the value of NO_MORE_COLUMN
  while (ColumnText.HasMoreText(status))
  {
    if (i == 0)
    {
      //Writing the first column
      ct.SetColumns(left, right);
      i++;
    }
    else
    {
      //write the second column
      ct.SetColumns(left2, right2);
    }
    //Needs to be here to prevent app from hanging
    ct.YLine = doc.Top - 80f;
    //Commit the content of the ColumnText to the document
    //ColumnText.Go() returns NO_MORE_TEXT (1) and/or NO_MORE_COLUMN (2)
    //In other words, it fills the column until it has either run out of column, or text, or both
    status = ct.Go();
  }
}
catch (Exception ex)
{
  //Log(ex.Message);
}
finally
{
  doc.Close();
}

ColumnText requires that you need a PDFContentByte object. This is nearly always the case when you want to place stuff at fixed positions. The code above starts by defining a document object, and then creating some fonts to work with, as well as setting the margins of the document (which needs to be done before the document is opened to take effect). A PdfWriter object is created so that the PDFContentByte object can be instantiated from its DirectContent property. Then a ColumnText object is created using the PDFContentByte. A heading is added, followed by the illustrated capital "L", which starts the Chapter. This is followed by a number of Phrases, set out as paragraphs.

So, now the ColumnText object has its text content, but nowhere to put it yet, so the two columns are created. The first array of floats defines the irregular shape of the left hand side fo the first column which has to the top corner chopped out of it to make way for the image. The second array defines the straight right hand edge. The third and fourth arrays take care of the regularly shaped second column. Two int variables are created to hold the value of the status of the column with regard to whether there is any more text to be added (status), and then the number of the column that is currently being worked on (i).

ColumnText.HasMoreText(status) is a convenience method that takes an int as a parameter. It examines the value of the parameter to see if there is any more text to be added and returns true if there is. The value that returns false is 1. It is initialised at 0 to start, so HasMoreText returns true. Since i is also 0, the code executes to add the first column, then the YLine is set to the top of the column. This must be done, otherwise the application will just spin until the execution timeout occurs. Finally, the ColumnText.Go() method is called. This actually commits the contents of the ColumnText to the document, and also returns a value to the variable status. It returns either NO_MORE_TEXT, which is 1, and/or NO_MORE_COLUMN (2). If NO_MORE_TEXT is returned, everything has been written, otherwise the second column is created and the text added to that. Once ColumnText.HasMoreText returns false, the page is written.

Building on this, if the amount of text spans more than one page, the routine can be rewritten to call Document.NewPage(), and if Go() is called after each Phrase is added to the ColumnText object, it is possible to obtain the current Y position on the page to establish how much room there is left. this enables you to manage widows and orphans - single lines of text that are belong to a paragraph that appear at the end of the preceding page or column (orphans) or appear at the top of a new page or column (widows). It is also possible to pass the parameter "false" into Go(), which does not commit the text to the column, but still allows you to obtain the position as if it was to allow you much finer control over layout.

Capture Screen Shots Using ASP.Net Without JavaScript


Description:-

In this article I will explain how to capture a screenshot (snapshot) of a Website web page using ASP.Net using C#.

I have seen many articles using a lot of scripting code to capture the screen shots but the .Net Framework capable of doing this type of thin in a few lines of code. So by considering that requirement in this article especially focusing on beginners and those who want to learn how to capture the screen using ASP.Net and C# without using any scripting language.

We are using the Screen class of Windows Forms to get our requirement that contains the many methods related to screen shots, so we need to add the reference for Windows Forms in our project.

Default.aspx:-
<div>
  <br />
  <h2 style="font-size: x-large; font-weight: bolder;">by Umesh Patel</h2>
  <br />
  <asp:Label ID="Label1" runat="server" Text="Taking ScreenShot"></asp:Label>
  <br />
</div>

Default.aspx.cs:-
protected void Page_Load(object sender, EventArgs e)
{
    Label1.Text = "This Screen Shot Taken at " + DateTime.Now.ToString();
    //System.Threading.Thread.Sleep(5000);
    Screnshot();
}

protected void Screnshot()
{
    Capture(@"C:\Users\UmesH\Desktop\ScreenShot.jpg");//path to Save Captured files
}

public static void Capture(string CapturedFilePath)
{
    Bitmap bitmap = new Bitmap
    (Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);

    Graphics graphics = Graphics.FromImage(bitmap as System.Drawing.Image);
    graphics.CopyFromScreen(25, 25, 25, 25, bitmap.Size);

    bitmap.Save(CapturedFilePath, ImageFormat.Bmp);
}

Itextsharp - Working with images in asp.net

Itextsharp - Working with images in asp.net

Description:-

iTextSharp supports all the main image types: jpg, tif, gif, bmp, png and wmf. There are a number of ways to create images with iTextSharp using the Image.GetInstance() method. Probably the most used option will be to pass a filesystem path and file name into the method: 

string pdfpath = Server.MapPath("PDFs");
string imagepath = Server.MapPath("Images");
Document doc = newDocument();
try
{
  PdfWriter.GetInstance(doc, newFileStream(pdfpath + "/Images.pdf", FileMode.Create));
  doc.Open();
  //New
  doc.Add(newParagraph("GIF"));
  iTextSharp.text.Image gif = iTextSharp.text.Image.GetInstance(imagepath + "/ajax-loader(1).gif");
  doc.Add(gif);
}
catch (Exception ex)
{
  //Log error;
}
finally
{
  doc.Close();
}

Alternative constructors that you may use include passing a URL or a System.Drawing.Image object (as opposed to an iTextSharp.text.Image). Note - the following snippet that System.Drawing.Image.FromStream() method shows the use of namespace aliasing again (sd.Image.FromStream(fs)), as was highlighted to avoid clashes with the two different types of Image object: 

doc.Add(newParagraph("JPG"));
string url = @"D:\Done\AnimationChart\AnimationChart\Images\Jellyfish.jpg";
iTextSharp.text.Image jpg = iTextSharp.text.Image.GetInstance(newUri(url));
jpg.ScaleToFit(250f, 100f);
doc.Add(jpg);
doc.Add(newParagraph("PNG"));
using (FileStreamfs = new FileStream(imagepath + "/vuserpic_1.png", FileMode.Open))
{
  iTextSharp.text.Imagepng = iTextSharp.text.Image.GetInstance(System.Drawing.Image.FromStream(fs), ImageFormat.Png);
  doc.Add(png);
}

It's difficult to tell from the images I have provided so far, but the resolution of the resulting images in the PDF file is not that great. By default, images are embedded at 72 dpi (Dots Per Inch) which coincidentally, matches the number of points in an inch. If this file was being prepared for printing, the final job would be a bit nasty. Generally, commercial printers require that colour images for printing have a resolution of 300 dpi. To achieve this, you can scale the image to 24%. What you are actually trying to do is squeeze 300 pixels into the space that 72 normally occupies. 72/300 * 100 = 24%. The image stays the same in terms of file size but occupies less space in the document. 

doc.Add(newParagraph("TIF Scaled to 300dpi"));
iTextSharp.text.Imagetif = iTextSharp.text.Image.GetInstance(imagepath + "/WelcomeFax.tif");
tif.ScalePercent(24f);
doc.Add(tif);

Now, I have a large tif file that I want to use as a logo on an A4 letterhead. It measures 300 x 890 pixels. So at the default 72 dpi, it will measure 4.17 inches wide by12.36 inches deep. Increasing the resolution to 300 dpi will reduce the width to 1 inch, and the depth to 2.97 inches (72 points by 213.6 points). That part is fine. We can do that using the code above. Now I want to place the 300 dpi image in a particular position on the page. I have in mind the top right hand corner. The SetAbsolutePosition() method will do this, but I need to get a calculator out.

SetAbsolutePosition() accepts 2 floats as parameters. The first represents the co-ordinate along the X-axis, which starts at the left hand edge of the document and finishes at the right hand edge of the document. The second represents the Y-axis co-ordinate which starts from the bottom of the document and goes to the top. An A4 document is 595 points wide and 842 pixels high with a 36 point margin all around by default.

The actual co-ordinate that needs to be passed in is the bottom left of the image position. This image will butt right up to the right-hand margin. The image is 72 points wide (1 inch) + the margin at 36 points (total 108 points) from the right hand edge of the document, or 595 - 108 = 487 points along the X-axis. The Y-axis co-ordinate is the height of the image + the margin away from the top of the document, or 842 - (213.6 + 36) = 592.4 points from the bottom. Cripes. I don't really want to have to remember all the various sizes of different documents and do these calculations every time I want to set the absolute position of an element. And fortunately, I don't have to. I can use the 
Document.PageSize object to do the work for me.

iTextSharp.text.Image tif1 = iTextSharp.text.Image.GetInstance(imagepath + "/NewFile.tif");
tif1.ScalePercent(24f);
tif1.SetAbsolutePosition(doc.PageSize.Width - 36f - 72f,
doc.PageSize.Height - 36f - 216.6f);
doc.Add(tif1);

doc.PageSize.Width gives me the width in points of the document, and I just remove the margin (36 points) and the width of the image (72 points) for the X-axis co-ordinate, and the margin and height of the image from the total height of the document for the Y-axis co-ordinate.
Another scenario that might need to be catered for is to fit a user-supplied image into a fixed size box somewhere on a form. I've pinched the Sunset image that I found in the Sample Images folder in My Pictures that comes as part of the default install of WindowsXP to illustrate how to use the ScaleToFit() method to achieve this. The following code takes an image of 800 x 600 and forces it to resize, maintaining its aspect ratio, into a rectangle measuring 250 points square.

iTextSharp.text.Image jpg1 = iTextSharp.text.Image.GetInstance(imagepath + "/Desert.jpg");
jpg1.ScaleToFit(250f, 250f);
jpg1.Border = Rectangle.BOX;
jpg1.BorderColor = Color.YELLOW;
jpg1.BorderWidth = 5f;
doc.Add(jpg1);
doc.Add(new Paragraph("Original Width: " + jpg1.Width.ToString()));
doc.Add(new Paragraph("Original Height " + jpg1.Height.ToString()));
doc.Add(new Paragraph("Scaled Width: " + jpg1.ScaledWidth.ToString()));
doc.Add(new Paragraph("Scaled Height " + jpg1.ScaledHeight.ToString()));
float Resolution = jpg1.Width / jpg1.ScaledWidth * 72f;
doc.Add(new Paragraph("Resolution: " + Resolution)); 

I have also taken the opportunity to add a yellow border to the embedded image, which is 5 points wide, and then shown the original dimensions, followed by the scaled dimensions, and the resulting resolution of the image.

If you use SetAbsolutePosition() you end up with the same effect as if you had set the Alignment property of the image to Image.UNDERLYING, in that text added to the document will run over the top of it. Unless you want to achieve this kind of watermark effect, you need to use Image.TEXTWRAP instead. 

iTextSharp.text.Image jpg2 = iTextSharp.text.Image.GetInstance(imagepath + "/Desert.jpg");
Paragraphparagraph = newParagraph(@"Loremipsum dolor sit amet, consectetueradipiscingelit. Suspendisseblanditblanditturpis.Nam in lectusut dolor consectetuerbibendum.Morbinequeipsum, laoreet id; dignissimet, viverra id, mauris. Nullamauriselit, consectetuer sit amet, accumsaneget, congue ac, libero. Vivamussuscipit.Nuncdignissimconsectetuerlectus.Fusceelit nisi; commodonon, facilisisquis, hendreriteu, dolor? Suspendisseeleifend nisi ut magna.Phasellus id lectus! Vivamuslaoreetenimet dolor. Integer arcumauris, ultriciesvel, portaquis, venenatis at, libero.Donecnibhest, adipiscing et, ullamcorper vitae, placerat at, diam. Integer ac turpisvel ligula rutrumauctor! Morbiegestaserat sit amet diam. Ututipsum? Aliquam non sem. Nullarisuseros, mollisquis, blanditut; luctuseget, urna.Vestibulumvestibulumdapibuserat.Proinegestasleo a metus?");
paragraph.Alignment = Element.ALIGN_JUSTIFIED;
jpg2.ScaleToFit(250f, 250f);
jpg2.Alignment = iTextSharp.text.Image.TEXTWRAP | iTextSharp.text.Image.ALIGN_RIGHT;
jpg2.IndentationLeft = 9f;
jpg2.SpacingAfter = 9f;
jpg2.BorderWidthTop = 36f;
jpg2.BorderColorTop = Color.WHITE;
doc.Add(jpg2);
doc.Add(paragraph);

In this instance, I added a white border to the image to align it with the top of the text, and a bit of padding to the left and bottom of the image to stop the text running right up to its edge. Left and Right padding can be added using the IndentationLeft and IndentationRight properties, while SpacingBefore and SpacingAfter is used to pad the top and bottom. You may ask why I didn't use SapcingBefore instead of adding a white border, and that's a good question. The fact is that whatever I set the value to for SpacingBefore, it seemed to have no effect whatsover in this instance. I have no idea why this should be, but if anyone does, I'll be pleased to hear from them.

One final thing with images - you can rotate them if you need to. One way to do this is to set the Rotation property, which takes a float. The float value represents an angle measured in Radians. If you did more Mathematics than I did at school, you may be comfortable with this, but if you are like me and ask "What??". you can either work out that a quarter turn (90°) is Pi / 2, or simply set the RotationDegrees property instead. Rotation by default is anti-clockwise. The following are equally valid and equivalent: 

jpg2.Rotation = (float)Math.PI / 2;
jpg2.RotationDegrees = 90f;

Capture Screenshot Image of Website in ASP.Net.

Capture Screenshot Image of Website in ASP.Net.

Description:-

In this article I will explain how to capture a screenshot (snapshot) of a Website web page using ASP.Net using C#.  the WebBrowser is a Windows Forms controls, in order to use it in ASP.Net Web Projects, we will have to add reference to the following libraries.

When the Button is clicked the following event handler is raised, here a new Thread is initiated and the WebBrowser control is initialized within the Thread. For the WebBrowser I have attached aDocumentCompleted event handler which will be raised when the Web Page is loaded inside the browser.

Note: Since ASP.Net applications work in Multi-Threaded Apartments (MTA) we need to start a new Thread for the WebBrowser control and execute the Thread in Single-Threaded Apartments (STA).

Inside the DocumentCompleted event handler, the Web Page loaded inside the WebBrowser control is drawn to a Bitmap which is then converted to a Byte Array and then to Base64 string so that it can be displayed in the Image control.

Default.aspx:-
<div>
  <asp:TextBox ID="txtUrl" runat="server" Text="" />
  <asp:Button ID="Button1" Text="Capture" runat="server" OnClick="Capture" />
  <br />
  <asp:Image ID="imgScreenShot" runat="server" Height="300" Width="400" Visible="false" />
</div>

Default.aspx.cs:-
protected void Capture(object sender, EventArgs e)
{
    string url = txtUrl.Text.Trim();
    Thread thread = new Thread(delegate()
    {
        using (WebBrowser browser = new WebBrowser())
        {
            browser.ScrollBarsEnabled = false;
            browser.AllowNavigation = true;
            browser.Navigate(url);
            browser.Width = 1024;
            browser.Height = 768;
            browser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(DocumentCompleted);
            while (browser.ReadyState != WebBrowserReadyState.Complete)
            {
                System.Windows.Forms.Application.DoEvents();
            }
        }
    });
    thread.SetApartmentState(ApartmentState.STA);
    thread.Start();
    thread.Join();
}

private void DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
    WebBrowser browser = sender as WebBrowser;
    using (Bitmap bitmap = new Bitmap(browser.Width, browser.Height))
    {
        browser.DrawToBitmap(bitmap, new Rectangle(0, 0, browser.Width, browser.Height));
        using (MemoryStream stream = new MemoryStream())
        {
            bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
            byte[] bytes = stream.ToArray();
            imgScreenShot.Visible = true;
            imgScreenShot.ImageUrl = "data:image/png;base64," + Convert.ToBase64String(bytes);
        }
    }
}

iTextSharp - Drawing shapes and Graphics in Asp.Net


Description:-


Up till now, all content added to the PDF documents in previous articles have relied on Simple iText, which takes care of positioning content within the flow of a document. It also looks after creating new pages to accept overflow text etc. Working with graphics needs a slightly different approach, in that we now need to use a PdfContentByte() object explicitly. This is obtained from the PdfWriter object's DirectContent. This also means that instead of just invoking the GetInstance method of the PdfWriter, we actually need to instantiate a PdfWriter object. 

string pdfpath = Server.MapPath("PDFs");
Document doc = new Document();
try
{
  PdfWriter writer = PdfWriter.GetInstance(doc, newFileStream(pdfpath + "/Graphics.pdf", FileMode.Create));
  doc.Open();
  PdfContentByte cb = writer.DirectContent; 
  //Now that we have a working PdfContentByte object, we can use it to start drawing: 
  cb.MoveTo(doc.PageSize.Width / 2, doc.PageSize.Height / 2);
  cb.LineTo(doc.PageSize.Width / 2, doc.PageSize.Height);
  cb.Stroke();
  cb.MoveTo(0, doc.PageSize.Height / 2);
  cb.LineTo(doc.PageSize.Width, doc.PageSize.Height / 2);
  cb.Stroke();
}
catch (Exception ex)
{
  //Log error;
}
finally
{
  doc.Close();
} 

The first line moves to the x, y coordinates specified in the parameters passed in, which in this case is halfway across the document, and halfway up (or the center point). The next line draws a line from this point to the position specified in the LineTo() method, which is still halfway across the document, but at the top of it. Actually, it doesn't "draw" it, but really only describes our intention. The line is only actually committed to the document when Stroke() is called. The second line is drawn from the lefthand edge, at a position halfway up the document to the righthand edge at the same height - so we end up with the top two quarters of the document outlined.

Using the same methodology, we can add a square to the top left quarter: 

cb.MoveTo(100f, 700f);
cb.LineTo(200f, 700f);
cb.LineTo(200f, 600f);
cb.LineTo(100f, 600f);
cb.ClosePath();
cb.Stroke(); 

We didn't need to explicitly specify the coordinates for the final side of the square. ClosePath() automatically provides a line from the current position that we are at to the original coordinates. However, there is a quicker way of delivering a square (or rectangle) using one of the convenience shapes provided by iTextSharp. The next bit shows that is action, placing a square in the top right quarter of the document: 

cb.Rectangle(doc.PageSize.Width - 200f, 600f, 100f, 100f);
cb.Stroke();

Four more squares are added to the page, each one illustrating the results of different methods other than Stroke(), used to consign them to the document. But first, the Stroke colour and the Fill colour are set. If you have worked with any graphics packages, such as PhotoShop or FireWorks, you will probably know that Stroke is the outline of an object, and Fill represents its internals bounded by the Stroke. I have used CMYK as the colour space, setting the Stroke colour to Cyan and the Fill colour to Yellow: 

cb.SetColorStroke(newCMYKColor(1f, 0f, 0f, 0f));
cb.SetColorFill(newCMYKColor(0f, 0f, 1f, 0f));

cb.MoveTo(70, 200);
cb.LineTo(170, 200);
cb.LineTo(170, 300);
cb.LineTo(70, 300);
//Path closed and stroked
cb.ClosePathStroke();
cb.Stroke();

cb.MoveTo(190, 200);
cb.LineTo(290, 200);
cb.LineTo(290, 300);
cb.LineTo(190, 300);
//Filled, but not stroked or closed
cb.Fill();
cb.Stroke();

cb.MoveTo(310, 200);
cb.LineTo(410, 200);
cb.LineTo(410, 300);
cb.LineTo(310, 300);
//Filled, stroked, but path not closed
cb.FillStroke();
cb.Stroke();

cb.MoveTo(430, 200);
cb.LineTo(530, 200);
cb.LineTo(530, 300);
cb.LineTo(430, 300);
//Path closed, stroked and filled
cb.ClosePathFillStroke();
cb.Stroke(); 

When using a Rectangle object to represent a square or rectangle instead of drawing it, the first two parameters represent the x and y coordinates of the bottom right hand corner. The final two parameters are the width and height. Other preset shapes include the Circle, but the x and y coordinates that are passed in represent the center point of the shape, followed by a value representing the radius. Looking at the first of the 4 squares above, it is relatively easy to determine that the width and height is 100 points, and that the center point is at 120 x, 250 y. To add a circle to the square so that it fits nicely, the following code will do:

cb.SetCMYKColorStroke(255, 255, 0, 0);
cb.SetCMYKColorFill(0, 255, 255, 0);
cb.SetLineWidth(2f);
cb.Circle(120f, 250f, 50f);
cb.Fill();
cb.Stroke(); 

Rather irritatingly, I found you have to guess at the actual values required by the two methods concerning the use of CMYK colour I have used so far. Neither was intuitive, given that generally, CMYK colours are represented as a series of percentages. For example, Warm Red is referenced as C: 0%, M: 100%, Y: 100%, K: 100%. The constructor for CMYKColor() requires four floats. Providing values that represent the percentages works fine. But I have provided values of 1f and 0f. In fact, I can provide any value I want, so long as it is a valid float. The values are treated as being relative to eachother, so for 100% blue (Cyan) i could just have validly provided 3000f, 0f, 0f, 0f. Strange, but workable if you stick to the usual CMYK percentages, and don't accidentally type in an extra zero.

The SetCMYKColorFill() method used just above accepts ints, rather than floats. I thought maybe this method was working on percentages as I would expect with CMYK, so I originally supplied the value 0, 100, 100, 0 to represent Warm Red. All I got was a washy pinky colour. I thought perhaps there was a bug in there somewhere, and that something was being affected by the previous setting of the Fill colour, so I deployed the ResetCMYKColorFill() method in the hope that it did something. Nope. All it did was reset to the default colour of black. Eventually, I found out CMYKColor is built on the ExtendedColor class, and can accept ints up to 255 - which is reminiscent of the RGB colour values and really confusing unless you know. I applied the values you see above, and got my desired result. To build on the oddity of this approach, I also discovered that there is nothing to prevent you entering values above 255. If you do, it seems that iTextSharp subtracts 255 from whatever you supply, so 256 is the equivalent of 1, and 510 is the equivalent of 255 - or at least, that's the results I got when I tried it.
Anyway, enough of the digression. Here's my red circle with a mauve border (2 points in width) in the first square:

Moving on, here's an example of using another preset shape, the ellipse. First, a rectangle is drawn, then an ellipse is added to fit neatly within it to illustrate how the positioning works through the parameters supplied to the constructor:

// x, y of bottom left corner, width, height
cb.Rectangle(100f, 200f, 300f, 100f);
cb.Stroke();
//Bottom left and top right coordinates
cb.Ellipse(100f, 200f, 400f, 300f);
cb.Stroke(); 

If the differences between the first and third parameter, and the second and fourth parameter are the same, you end up with a circle.
The next example shows another preset shape, the rounded rectangle. When one of these are drawn, the values passed in are the x and y coordinates for the bottom left hand corner, followed by the width and height, and finally the radius of the rounded corners. I have also added a circle in the corner with the same radius as the corner itself to show how the radius of the corner works. I've placed a cross at the center of the circle: 

//Bottom left coordinates followed by width, height and radius of corners
cb.RoundRectangle(100f, 500f, 200f, 200f, 20f);
cb.Stroke();

cb.Circle(120f, 520f, 20f);
cb.Stroke();

cb.MoveTo(118f, 520f);
cb.LineTo(122f, 520f);
cb.Stroke();
cb.MoveTo(120f, 518f);
cb.LineTo(120f, 522f);
cb.Stroke();

Triangles are relatively simple to do, just by drawing the three lines they require. Here's an example of a right-angled triangle with the right angle shown: 

cb.MoveTo(350f, 450f);
cb.LineTo(350f, 600f);
cb.LineTo(500f, 450f);
cb.ClosePathStroke();

cb.MoveTo(350f, 460f);
cb.LineTo(360f, 460f);
cb.LineTo(360f, 450f);
cb.Stroke(); 

Curves and Arcs

Bezier curves are important in Vector Graphics, where they are based on mathematical equations rather than each individual point being specified along the path of the curve. They work by specifying a start point, an end point, and two control points. The first control point is specified in reference to the start point, and the second one is related to the end point. The curve will begin at the start point, and head towards the end point in the direction of the 1st control point. How far it gets near the control point will depend on the distance between the start point and its control point, and the end point and its control point, and the distance between the start and end point themselves. The control points are used for directional purposes, and are rarely hit by the path. If you have ever used a Vector graphics package, like Photoshop or Fireworks, you will have seen these control points, usually with little "handles" on the end of them which you can move to bend the curve.
Here's an example of a curve, that starts at (200, 10), and ends at (350, 150).

//Start Point
cb.MoveTo(200f, 10f);
//Control Point 1, Control Point 2, End Point
cb.CurveTo(150f, 30f, 450f, 70f, 350f, 150f);
cb.Stroke(); 

The curve heads towards the first control point at (150, 30), then bends away towards the second control point at (450, 70), before arriving at the end point. It looks like this:

I'm not really sure that shows a lot, so I will add in some "handles" that show the control points:

cb.MoveTo(200f, 10f);
cb.LineTo(150f, 30f);
cb.Stroke();

cb.MoveTo(450f, 70f);
cb.LineTo(350f, 150f);
cb.Stroke();

cb.Circle(450f, 70f, 1f);
cb.Stroke();
cb.Circle(150f, 30f, 1f);
cb.Stroke(); 

The first control point has a relatively short handle, so the curve only begins to move towards it. The second control point has a longer handle, and this starts to exert its influence on the curve along with the ultimate destination at a relatively early point in its journey, which is reflected in the way the line is "pulled" towards it. This effect is probably best illustrated by changing the second control point so that it is further away, and the angle is altered: 

cb.SetColorStroke(Color.GREEN);
cb.SetColorStroke(Color.GREEN);
//start point (x,y)
cb.MoveTo(200f, 10f);
//control point 1 (x,y), control point 2 (x,y), end point (x,y)
cb.CurveTo(150f, 30f, 550f, 100f, 350f, 150f);
cb.Stroke();

cb.MoveTo(550f, 100f);
cb.LineTo(350f, 150f);
cb.Stroke();

cb.Circle(550f, 100f, 1f);
cb.Stroke();

cb.SetColorStroke(Color.LIGHT_GRAY);

//Bottom Left(x,y), Top Right(x,y), Start Angle, Extent
cb.Arc(350f, 70f, 550f, 130f, 270f, 90f);
cb.SetLineDash(3f, 3f);
cb.Stroke();

cb.SetLineDash(0f);
cb.MoveTo(550f, 100f);
cb.LineTo(535f, 95f);
cb.Stroke();
cb.MoveTo(550f, 100f);
cb.LineTo(552f, 88f);
cb.Stroke();

The original curve is shown in black, while the new one is shown in green. Now you can see that the increased length of the second "handle" has exerted its influence right from the start point, in that the green line starts just slightly beneath the original black one. Since the new second control point is further away from the end point, and is at a slightly more obtuse angle, the green line moves much further towards the second control point before finishing up at the end point.

There are a couple of other points to note about the code for the second curve. One is the Arc object, which has been used in this instance to create the curved arrow illustrating the movement of the original and new second control points. An Arc is part of an ellipse. In this case, the ellipse will fit into a rectangle that has a bottom left corner at (350, 70) and a top right corner at (550, 130). The default direction that an ellipse is drawn is counter-clockwise. The angle at which the arc is started is 270°, and only 90° of it are drawn. Secondly, the SetLineDash() method is shown for the first time in this series of articles, which allows me to draw the arrow as a dashed line.