I'm trying to print out some information from my wpf-application. I found some code to make what I want to print to fit one page and it does the job very well. The problem is that after I print what i want, the method downscale my wpf-control, which is a groupbox with a chart in it. How do i scale the size of the groupbox back to what it was before the scaling?
private void PrintUT_Click(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(capabilities.PageImageableArea.ExtentWidth / this.GBProsjektTimer.ActualWidth, capabilities.PageImageableArea.ExtentHeight /
this.GBProsjektTimer.ActualHeight);
//Transform the Visual to scale
this.GBProsjektTimer.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 Point(capabilities.PageImageableArea.OriginWidth, capabilities.PageImageableArea.OriginHeight), sz));
//now print the visual to printer to fit on the one page.
printDlg.PrintVisual(this.GBProsjektTimer, "First Fit to Page WPF Print");
}
}
Found the answer! Just replace objecToPrint with your object. In my case that would be this.GBProsjektTimer.Width = double.Nan
objectToPrint.Width = double.NaN;
objectToPrint.UpdateLayout();
objectToPrint.LayoutTransform = new ScaleTransform(1, 1);
Size size = new Size(capabilities.PageImageableArea.ExtentWidth,
capabilities.PageImageableArea.ExtentHeight);
objectToPrint.Measure(size);
objectToPrint.Arrange(new Rect(new Point(capabilities.PageImageableArea.OriginWidth,
capabilities.PageImageableArea.OriginHeight), size));
Related
I made a windows service that's runs in background service and listening for web app to order to print.
the web app send a pdf file and width and height of the printer paper with count of copies
I wrote the code this way
convert pdf to image
public Image ConverPdfToImage(IFormFile pdfFile)
{
if (pdfFile == null || pdfFile.Length==0)
{
return null;
}
var documemt = new Spire.Pdf.PdfDocument();
documemt.LoadFromStream(pdfFile.OpenReadStream());
Image image = documemt.SaveAsImage(0,PdfImageType.Bitmap);
return image;
}
then the event handler
private void PrintPage(object sender, PrintPageEventArgs ev,Image img)
{
Rectangle pageBounds = ev.PageBounds;
int x = pageBounds.Left - (int) ev.PageSettings.HardMarginX;
int y = pageBounds.Top - (int) ev.PageSettings.HardMarginY;
int width = pageBounds.Width;
int height = pageBounds.Height;
ev.Graphics.CompositingQuality = CompositingQuality.HighQuality;
ev.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
ev.Graphics.SmoothingMode = SmoothingMode.HighQuality;
ev.Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
local = new Rectangle(x, y, width, height);
ev.Graphics.FillRectangle(Brushes.Transparent, local);
ev.Graphics.DrawImage(img, local);
}
and the final function that prints
PrintDocument printDocument = new PrintDocument();
printDocument.PrinterSettings.PrinterName = form.Printer;
printDocument.DefaultPageSettings.Landscape = form.Landscape;
printDocument.DefaultPageSettings.PrinterSettings.Copies = form.Count;
printDocument.DefaultPageSettings.PaperSize =GetPaperSize(form.Width, form.Height);
printDocument.DefaultPageSettings.Margins = new Margins(0, 0, 0, 0);
Image img = ConverPdfToImage(form.PrintFile);
printDocument.PrintPage += (sender, args) => this.PrintPage(sender,args,img);
printDocument.Print();
the printDocument is from System.Drawing
It makes correct size in printer
printer are for lables and they have label papers with custom size
but the printed paper is blur and hard to read
some of it is so messed up and dirty
glad to help me make print sharp and good quality
I've written a C# print test project with pre-printed form - System.Drawing.Printing.PrintDocument. The purpose of it is to print the image from a file on custom paper size. Before to print the image is scaling down according to the paper size.
public PrintDocument printDoc = new PrintDocument();
.....
private void PrintButton_Click(object sender, EventArgs e)
{
string FileName = "D:\\temp\\testprint.png";
try
{
if (string.IsNullOrWhiteSpace(FileName)) return; // Prevents execution of below statements if filename is not selected.
PrintDocument pd = new PrintDocument();
PaperSize paperSize = new PaperSize("TEST PAPER SIZE", 50, 50);
paperSize.RawKind = (int)PaperKind.Custom;
//Disable the printing document pop-up dialog shown during printing.
PrintController printController = new StandardPrintController();
pd.PrintController = printController;
//For testing only: Hardcoded set paper size to particular paper.
pd.PrinterSettings.DefaultPageSettings.PaperSize = paperSize;
pd.DefaultPageSettings.PaperSize = paperSize;
pd.DefaultPageSettings.Margins = new Margins(0, 0, 0, 0);
pd.PrinterSettings.DefaultPageSettings.Margins = new Margins(0, 0, 0, 0);
pd.PrintPage += (sndr, args) =>
{
System.Drawing.Image i = System.Drawing.Image.FromFile(FileName);
args.Graphics.PageUnit = System.Drawing.GraphicsUnit.Millimeter;
//Adjust the size of the image to the page to print the full image without loosing any part of the image.
System.Drawing.Rectangle m = args.MarginBounds;
//Logic below maintains Aspect Ratio.
if ((double)i.Width / (double)i.Height > (double)m.Width / (double)m.Height) // image is wider
{
m.Height = (int)((double)i.Height / (double)i.Width * (double)m.Width);
}
else
{
m.Width = (int)((double)i.Width / (double)i.Height * (double)m.Height);
}
//Calculating optimal orientation.
pd.DefaultPageSettings.Landscape = m.Width > m.Height;
//Putting image in center of page.
m.Y = (int)((((System.Drawing.Printing.PrintDocument)(sndr)).DefaultPageSettings.PaperSize.Height - m.Height) / 2);
m.X = (int)((((System.Drawing.Printing.PrintDocument)(sndr)).DefaultPageSettings.PaperSize.Width - m.Width) / 2);
args.Graphics.DrawImage(i, m);
};
pd.Print();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
The image scaling works fine but paper size isn't changing it always stay A4. I've googled a lot and applied some options but still can't set custom paper properties. Can anyone help me to find out what the problem is? Or at least point me where to dig on?
Thanks in advance!
I am using this code to print to fit printer paper in landscape:
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(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.ExtentHeight, capabilities.PageImageableArea.ExtentWidth);
//update the layout of the visual to the printer page size.
this.Measure(sz);
this.Arrange(new Rect(new Point(capabilities.PageImageableArea.OriginHeight, capabilities.PageImageableArea.OriginWidth), sz));
printDlg.PrintTicket.PageOrientation = PageOrientation.Landscape;
printButton.Visibility = Visibility.Hidden;
exitButton.Visibility = Visibility.Hidden;
//now print the visual to printer to fit on the one page.
printDlg.PrintVisual(this, "First Fit to Page WPF Print");
I want to return the Windows to its original size (fullscreen). How do I accomplish this?
I am using GhostScript.Net to rasterize PDF to page images before sending the page images to the printer. I am doing this so that I can always rasterize to 300dpi. This allows me to print the PDF in a reasonable amount of time regardless of the size of any image in the PDF (mainly scanned PDFs).
However, it strikes me that in some cases there will not be a need to rasterize as high as 300dpi. It may be possible to rasterize to 200dpi or even 100dpi depending on the content of the page.
Has anyone attempted to determine the maximum DPI for the content of a PDF page? Perhaps using iTextSharp?
My current code is this:
var dpiList = new List<int> {50, 100, 150, 200, 250, 300, 350, 400, 450, 500};
string inputPdfPath = #"C:\10page.pdf";
string outputPath = #"C:\Print\";
var lastInstalledVersion =
GhostscriptVersionInfo.GetLastInstalledVersion(
GhostscriptLicense.GPL | GhostscriptLicense.AFPL,
GhostscriptLicense.GPL);
var rasterizer = new GhostscriptRasterizer();
rasterizer.Open(inputPdfPath, lastInstalledVersion, true);
var imageFiles = new List<string>();
for (int pageNumber = 1; pageNumber <= 10; pageNumber++)
{
foreach (var dpi in dpiList)
{
string pageFilePath = System.IO.Path.Combine(outputPath,
string.Format("{0}-{1}-{2}.png", pageNumber, Guid.NewGuid().ToString("N").Substring(0, 8), dpi));
System.Drawing.Image img = rasterizer.GetPage(dpi, dpi, pageNumber);
img.Save(pageFilePath, ImageFormat.Png);
imageFiles.Add(pageFilePath);
Console.WriteLine(pageFilePath);
}
}
var imageCount = 0;
var pd = new PrintDocument();
pd.PrintPage += delegate(object o, PrintPageEventArgs args)
{
var i = System.Drawing.Image.FromFile(imageFiles[imageCount]);
var pageBounds = args.PageBounds;
var margin = 48;
var imageBounds = new System.Drawing.Rectangle
{
Height = pageBounds.Height - margin,
Width = pageBounds.Width - margin,
Location = new System.Drawing.Point(margin / 2, margin / 2)
};
args.Graphics.DrawImage(i, imageBounds);
imageCount++;
};
foreach (var imagefile in imageFiles)
{
pd.Print();
}
PDF pages don't have a resolution. Images within them can be considered to have a resolution, which is given by the width of the image on the page, divided by the number of image samples in the x direction, and the height of the image on the page divided by the number of image samples in the y direction.
So this leaves calculating the width and height of the image on the page. This is given by the image matrix, modified by the Current Transformation Matrix. So in order to work out the width and height on the page, you need to interpret the content stream up to the point where the image is rendered, tracking the graphics state CTM.
For general PDF files, the only way to know this is to use a PDF interpreter. In the strictly limited case where the whole page content is a single image you can gamble that there is no scaling taking place and simply divide the media width by the image width, and the media height by the image height to give the x and y resolutions.
However this definitely won't work in the general case.
I have WPF window that i want to Print on paper size 4inch by 6inch.
i dont understand where to set this size??
i am using window size to print but window size its not working.
my printer is not fixed paper size.
this is my print code:
private void _print()
{
PrintDialog printDlg = new System.Windows.Controls.PrintDialog();
//printDlg.ShowDialog();
//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(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(this.ActualWidth, this.ActualHeight);
//update the layout of the visual to the printer page size.
this.Measure(sz);
this.Arrange(new Rect(new Point(capabilities.PageImageableArea.OriginWidth, capabilities.PageImageableArea.OriginHeight), sz));
//now print the visual to printer to fit on the one page.
printDlg.PrintVisual(this, "Print Page");
}
In WPF 1 unit = 1/96 of inch, so you can calculate your size in inches using this formula
you can set printDlg.PrintTicket.PageMediaSize to the size of the Paper and then transform your window to print in that area as below:
private void _print()
{
PrintDialog printDlg = new System.Windows.Controls.PrintDialog();
PrintTicket pt = printDlg.PrintTicket;
Double printableWidth = pt.PageMediaSize.Width.Value;
Double printableHeight = pt.PageMediaSize.Height.Value;
Double xScale = (printableWidth - xMargin * 2) / printableWidth;
Double yScale = (printableHeight - yMargin * 2) / printableHeight;
this.Transform = new MatrixTransform(xScale, 0, 0, yScale, xMargin, yMargin);
//now print the visual to printer to fit on the one page.
printDlg.PrintVisual(this, "Print Page");
}
You can also adjust the Visual with respect to the paper size. This code adjusts the image to 4x6 inch paper.
var photo = new BitmapImage();
photo.BeginInit();
photo.CacheOption = BitmapCacheOption.OnLoad;
photo.UriSource = new Uri(photoPath);
photo.EndInit();
bool isPortrait = photo.Width < photo.Height;
if (isPortrait)
{
var transformedPhoto = new BitmapImage();
transformedPhoto.BeginInit();
transformedPhoto.CacheOption = BitmapCacheOption.OnLoad;
transformedPhoto.UriSource = new Uri(photoPath);
transformedPhoto.Rotation = Rotation.Rotate270;
transformedPhoto.EndInit();
photo = transformedPhoto;
}
int width = 6;
int height = 4;
double photoScale = Math.Max(photo.Width / (96 * width), photo.Height / (96 * height));
var vis = new DrawingVisual();
var dc = vis.RenderOpen();
dc.DrawImage(photo, new Rect
{
Width = photo.Width / photoScale,
Height = photo.Height / photoScale
});
dc.Close();
var pdialog = new PrintDialog();
pdialog.PrintTicket.PageOrientation = PageOrientation.Landscape;
pdialog.PrintTicket.PageBorderless = PageBorderless.Borderless;
pdialog.PrintTicket.PageMediaSize = new PageMediaSize(PageMediaSizeName.NorthAmerica4x6);
pdialog.PrintTicket.Duplexing = Duplexing.OneSided;
pdialog.PrintTicket.CopyCount = 1;
pdialog.PrintTicket.OutputQuality = OutputQuality.Photographic;
pdialog.PrintTicket.PageMediaType = PageMediaType.Photographic;
pdialog.PrintQueue = new PrintQueue(new PrintServer(), PrinterName);
pdialog.PrintVisual(vis, "My Visual");