I am using the WPF PrintVisual method in order to print an object. Check my code below.
PrintDialog dialog = new PrintDialog();
System.Printing.PrintCapabilities capabilities = dialog.PrintQueue.GetPrintCapabilities(dialog.PrintTicket);
Double height = dialog.PrintableAreaHeight;
Double width = dialog.PrintableAreaWidth;
myObj.Measure(new Size(width, height));
myObj.Arrange(new Rect(new Point((capabilities.PageImageableArea.OriginWidth), (capabilities.PageImageableArea.OriginHeight)), new Size(width, height)));
dialog.PrintVisual(myObj, "Print in WPF with fit to printing page");
If I print this in xps, it works very well. But when I print on paper (A4 => 8.5 x 11 inches) then the object gets clipped from the right as it generates the margin at the left side of the paper. Can anyone tell me how I can avoid this margin on the paper and print the object full length?
Thanks
It is very suspicious that you are using dialog.PrintableAreaHeight and dialog.PrintableAreaWidth for the printable size, but capabilities.PageImageableArea for the printable origin. These are unrelated measurements; try using
new Size(capabilities.PageImageableArea.ExtentWidth, capabilities.PageImageableArea.ExtentHeight)
in myObj.Measure and myObj.Arrange.
Related
I have some code used to watermark PDFs using iTextSharp. The code works fine for most PDFs, but there has been one test case where the watermark is not visible on a PDF of a scanned document. (I have other scanned documents where it does appear though).
I am using the GetOverContent() method.
This is my code for adding the watermark;
using (PdfReader reader = new PdfReader(this.inputFilename))
{
// Set transparent - 1
PdfGState gstate = new PdfGState();
gstate.FillOpacity = 0.4f;
gstate.StrokeOpacity = 0.5f;
// 2
BaseFont baseFont = BaseFont.CreateFont(BaseFont.HELVETICA_BOLD, Encoding.ASCII.EncodingName, false);
using (var stream = new MemoryStream())
{
var pdfStamper = new PdfStamper(reader, stream);
// Must start at 1 because 0 is not an actual page.
for (int i = 1; i <= reader.NumberOfPages; i++)
{
Rectangle pageSize = reader.GetPageSizeWithRotation(i);
// Gets the content ABOVE the PDF, Another option is GetUnderContent(...)
// which will place the text below the PDF content.
PdfContentByte pdfPageContents = pdfStamper.GetOverContent(i);
pdfPageContents.BeginText(); // Start working with text.
// 1
pdfPageContents.SaveState();
pdfPageContents.SetGState(gstate);
float hypotenuse = (float)Math.Sqrt(Math.Pow(pageSize.Width, 2) + Math.Pow(pageSize.Height, 2));
float glyphWidth = baseFont.GetWidth("My watermark text");
float fontSize = 1000 * (hypotenuse * 0.8f) / glyphWidth;
float angle = (float)(Math.Atan(pageSize.Height / pageSize.Width) * (180 / Math.PI));
// Create a font to work with
pdfPageContents.SetFontAndSize(baseFont, fontSize);
pdfPageContents.SetRGBColorFill(128, 128, 128); // Sets the color of the font, GRAY in this instance
// Note: The x,y of the Pdf Matrix is from bottom left corner.
// This command tells iTextSharp to write the text at a certain location with a certain angle.
// Again, this will angle the text from bottom left corner to top right corner and it will
// place the text in the middle of the page.
pdfPageContents.ShowTextAligned(PdfContentByte.ALIGN_CENTER, "My watermark text", pageSize.Width / 2, pageSize.Height / 2, angle);
pdfPageContents.EndText(); // Done working with text
pdfPageContents.RestoreState();
}
pdfStamper.FormFlattening = true; // enable this if you want the PDF flattened.
pdfStamper.FreeTextFlattening = true; // enable this if you want the PDF flattened.
pdfStamper.Close(); // Always close the stamper or you'll have a 0 byte stream.
return stream.ToArray();
}
}
Does anyone have any ideas as to why the watermark may not be appearing and what I can try to fix it?
Kind regards.
The code is based on an assumption it even documents as a fact:
// Note: The x,y of the Pdf Matrix is from bottom left corner.
// This command tells iTextSharp to write the text at a certain location with a certain angle.
// Again, this will angle the text from bottom left corner to top right corner and it will
// place the text in the middle of the page.
pdfPageContents.ShowTextAligned(PdfContentByte.ALIGN_CENTER, "My watermark text", pageSize.Width / 2, pageSize.Height / 2, angle);
The assumption that the x,y of the Pdf Matrix is from bottom left corner unfortunately is wrong: While it indeed is very often the case that the origin of the PDF coordinate system (the default user space coordinate system, to be more precise) is in the lower left corner of the page, this is not required, the origin actually can be literally anywhere (within reasonable limits).
Thus, one has to take the lower left coordinates of the Rectangle pageSize into consideration, too.
The OP meanwhile has confirmed:
I had assumed that the bottom left of the page would have co-ordinates of (0,0) but for this document the co-ordinates were (0, 7022).
Good Evening,
I am working on a small WPF app in VS2017 which uses c#. Its essentially just to make calculations for my workers in the field. I have everything built and tested, however, I am running into an issue when it comes to printing the results. I have scoured the corners of the internet and have gotten as far as getting the print dialog box to open and even print to PDF. The issue i am having is that when it prints, it is in full scale. I just need to be able to scale the app window to 80-90% of its size and then print. i will add the code and see if i am just overlooking something.
private void InvokePrint(object sender, RoutedEventArgs e)
{
PrintDialog printDlg = new System.Windows.Controls.PrintDialog();
if (printDlg.ShowDialog() == true)
{
//get selected printer capabilities
System.Printing.PrintCapabilities capabilities = printDlg.PrintQueue.GetPrintCapabilities(printDlg.PrintTicket);
//get scale of the print wrt to screen of WPF visual
double scale = Math.Min((ActualWidth*.9),ActualHeight);
//get the size of the printer page
Size sz = new Size((Width*.9), ActualHeight);
//update the layout of the visual to the printer page size.
this.Measure(sz);
this.Arrange(new Rect(new Point(0,0), sz));
//now print the visual to printer to fit on the one page.
printDlg.PrintVisual(this, "Offset Calculations");
What it is printing
What I want to print
add reference to ReachFramework.dll 4.0
PrintDialog dlg = new PrintDialog();
if ((bool)dlg.ShowDialog().GetValueOrDefault()) {
//switch landscape
dlg.PrintTicket.PageOrientation = System.Printing.PageOrientation.Landscape;
//get selected printer capabilities
System.Printing.PrintCapabilities capabilities = dlg.PrintQueue.GetPrintCapabilities(dlg.PrintTicket);
//get scale of the print wrt to screen of WPF visual
double scale = Math.Min(capabilities.PageImageableArea.ExtentWidth / this.ActualWidth, capabilities.PageImageableArea.ExtentHeight / this.ActualHeight);
//Transform the Visual to scale
this.LayoutTransform = new ScaleTransform(scale, scale);
//get the size of the printer page
Size sz = new Size(capabilities.PageImageableArea.ExtentWidth, capabilities.PageImageableArea.ExtentHeight);
//update the layout of the visual to the printer page size.
this.Measure(sz);
this.Arrange(new Rect(new System.Windows.Point((int)capabilities.PageImageableArea.OriginWidth, (int)capabilities.PageImageableArea.OriginHeight), sz));
//show the print dialog
dlg.PrintVisual(this, "MyDoc_" + DateTime.Now.ToString("yyyyMMdd_HHmmss"));
}
I am trying to insert a text watermark underneath a TIFF image in my windows form and would definitely appreciate anyone's help. I have a print button that retrieves the image, scales it down, then based on my margins, places the image accordingly to print. I'd like to add an additional piece where just before the image prints, I add in a text watermark (in this case a date stamp) that is just below the image.
I've tried adjusting the margin but that just increases (or decreases depending on the number setting) the image scale but does not add the additional room I want to add the watermark. Below is code of what I have so far:
protected void PrintPage(object sender, PrintPageEventArgs e)
{
if (this.Image == null)
{
e.Cancel = true;
return;
}
//ADD TIME STAMP WATERMARK
string watermark = "DATE ISSUED: " + String.Format("{0:MM/dd/yyyy}", System.DateTime.Now.Date);
System.Drawing.Graphics gpr = Graphics.FromImage(Image);
System.Drawing.Brush brush = new SolidBrush(System.Drawing.Color.Black);
Font font = new System.Drawing.Font("Arial", 55, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel);
SizeF size = e.Graphics.MeasureString(watermark, font);
float x = 0;
float y = Image.Height-size.Height;
RectangleF printArea = new RectangleF(x, y, size.Width, size.Height);
gpr.DrawString(watermark, font, brush, printArea);
e.Graphics.DrawImage(this.Image, e.MarginBounds);
}
The value of e.MarginBounds I have set in my App.config and include the following values: Left=70, Right=90, Top=190; Bottom=475. All the printouts are going to be printed portrait style on Letter 8 1/2 by 11 size paper.
I am able to display the watermark anywhere on top of the image, but I am hoping to place it underneath. When I adjust the y coordinate, and it so happens to be below the image, when I print, I assume that it is outside the print area and therefore, the watermark does not get printed on the page (it only shows the image).
I appreciate anyone's help in this as I have been racking my brain on this and have had no luck.
Aren't you printing your text beneath the image. I think you want to start printing at y=Image.Height + e.MarginBounds.Top, and x=e.MarginBounds.Left
That will print a your label left justified below the image in the margin.
Update: This works:
y=-size.Height + e.MarginBounds.Bottom;
x = e.MarginBounds.Left;
e.Graphics.DrawImage(Image, e.MarginBounds);
// note the change. Using e.graphics instead of gpr below
e.Graphics.DrawString(watermark, font, brush, printArea);
C# WPF windows application screen has multiple grids and textboxs, now I need to show all the content of the page into printable format, then print, here each grid is having more then some 500 records, I have to print all the data, before print I have to show in printable view of all data.
Is any open source already available for this?
Or any other approach to achieve this?
Or is any way to export the data to HTML format?
The code below lets you get an image of FrameworkElement(your window):
You can use the image and print the image:
(I am not sure what the image will look like as you have more than 500 records though)
Transform transform = element.LayoutTransform;
element.LayoutTransform = null;
double width = element.ActualWidth;
double height = element.ActualHeight;
// fix margin offset as well
Thickness margin = element.Margin;
element.Margin = new Thickness(0, 0, margin.Right - margin.Left, margin.Bottom - margin.Top);
// Get the size of canvas
Size size = new Size(width, height);
// force control to Update
element.Measure(size);
element.Arrange(new Rect(size));
RenderTargetBitmap bmp = new RenderTargetBitmap((int)width, (int)height, 96, 96, PixelFormats.Pbgra32);
bmp.Render(element);
// return values as they were before
element.LayoutTransform = transform;
element.Margin = margin;
Clipboard.SetImage(bmpCopied);
I have an image that I'm trying to print to legal size. However, there are a few challenges to this.
The image will vary in size. This is because I'm using a control that has limited print options but can export to an image.
I want to maximize the print area on the page. Smallest margin possible
The user needs to be able to select a printer and set options
Here's the code I'm using:
PrintDocument pd = new PrintDocument();
pd.PrintPage += (sender, args) =>
{
Image i = Image.FromFile(Globals.TempDirectory + #"\temp.jpg");
Point p = new Point(100, 100);
Margins margins = new Margins(50, 50, 50, 50);
pd.DefaultPageSettings.Margins = margins;
args.Graphics.DrawImage(i, p);
};
pd.Print();
I've been having trouble with this because I can't set margins and can't seem to get the print out right. I want it to print in legal but when I print the image, it's not rotated properly and it just prints to a default printer. I'm up for anything to get this to work.
Printing in C# sucks
try a
printdialog()
to allow the user to select a printer and settings. once you get that to work the rest of it might click for you.
Edit: Showing you where and how to use it.
PrintDialog pDialog = new PrintDialog();
if (pDialog.ShowDialog() == DialogResult.OK)
{
pd.PrinterSettings = pDialog.PrinterSettings;
pd.Print();
}