I want to create invoices with PdfSharpCore. that also works very well.
I would like to add a background image for each page. Can someone help me here?
With this code I can insert a background image after the document is created.
CreateDocument();
PdfDocumentRenderer renderer = new(true)
{
Document = Pdf
};
if (!string.IsNullOrWhiteSpace(Invoice.BackgroundImage))
{
renderer.PrepareRenderPages();
int pages = renderer.DocumentRenderer.FormattedDocument.PageCount;
var background = XImage.FromStream(() => {
return System.IO.File.OpenRead(Invoice.BackgroundImage);
});
for (int i = 1; i <= pages; ++i)
{
PageInfo pageInfo = renderer.DocumentRenderer.FormattedDocument.GetPageInfo(i);
PdfPage page = renderer.PdfDocument.AddPage();
var gfx = XGraphics.FromPdfPage(page, XPageDirection.Downwards);
gfx.DrawImage(background, 0, 0, pageInfo.Width, pageInfo.Height);
renderer.DocumentRenderer.RenderPage(gfx, i);
}
}
else
renderer.RenderDocument();
if (!string.IsNullOrEmpty(password))
SetPassword(renderer, password);
renderer.PdfDocument.Save(filename);
Related
I try to print a pdf with IronPdf from html but the result leaves a border.
Is there a way to set Fit-To-Page in my PrintDocument?
Here my code:
public static void PrintDocument(string printer, bool landscape, PdfDocument pdfDocument, Duplexing duplex)
{
var printDocument = pdfDocument.GetPrintDocument();
printDocument.PrinterSettings.PrinterName = printer;
printDocument.DefaultPageSettings.Landscape = landscape;
printDocument.PrinterSettings.Duplex = DuplexMapping(duplex);
printDocument.PrinterSettings.DefaultPageSettings.PaperSize.RawKind = (int)PaperKind.A4;
printDocument.Print();
}
Thanks to IronPdf-Support I found a solution:
// enable javascript
var renderer = new IronPdf.HtmlToPdf();
renderer.PrintOptions.EnableJavaScript = true;
renderer.PrintOptions.RenderDelay = 500; //milliseconds
renderer.PrintOptions.CssMediaType = IronPdf.PdfPrintOptions.PdfCssMediaType.Screen;
renderer.PrintOptions.MarginTop = 0;
renderer.PrintOptions.MarginBottom = 0;
renderer.PrintOptions.MarginLeft = 0;
renderer.PrintOptions.MarginRight = 0;
Set Margin to 0.
How to add watermark image while uploading image in asp.net mvc.
I am using jquery.uploadfile.min.js multiple file upload for uploading image.
Want to add automatically stored logo image (watermark) to append in my image file that i am going to upload.
IN VIEW:
var errorOccured = false;
$(function () {
var uploadObj = $("#multipleupload").uploadFile({
url: "./Handler.ashx",
multiple: true,
fileName: "myfile",
maxFileSize: 1024 * 5000,
allowedTypes: "jpg,jpeg,gif,png",
autoSubmit: false,
formData: { "FunctionName": "UploadProductImage", "ProductID": '#clsEncrypt.Encrypt(ViewBag.ProductID.ToString())' }, //"ImgResizeOption": ImgResizeOption
afterUploadAll: function () {
if (!errorOccured) {
window.location.href = 'ProductImage?Product=#(clsEncrypt.Encrypt(ViewBag.ProductID.ToString()))';
}
},
onError: function (files, status, errMsg) {
alert('file(s) could not be uploaded. Error: ' + errMsg);
errorOccured = true;
}
});
$("#startUpload").click(function () {
uploadObj.startUpload();
});
});
IN HANDLER :
public void UploadProductImage()
{
int ProductID = Convert.ToInt32(clsEncrypt.Decrypt(HttpContext.Current.Request["ProductID"]));
string PhysicalFolderPath = "~/Images/Product/";
for (int j = 0; j < HttpContext.Current.Request.Files.Count; j++)
{
HttpPostedFile uploadFile = HttpContext.Current.Request.Files[j];
string extention = System.IO.Path.GetExtension(uploadFile.FileName);
UploadPic(uploadFile, j++, PhysicalFolderPath, ProductID);
}
}
protected void UploadPic(HttpPostedFile FUPhoto, int sort, string RemotePath, int ProductID)
{
if (FUPhoto.FileName != "")
{
string ImgUploadResponse = "";
string strExt = Path.GetExtension(FUPhoto.FileName).Trim().ToLower();
string ImageName = DateTime.Now.ToFileTimeUtc() + strExt;
string OriginalImageFullPath = "~/Images/Product/" + ImageName;
if (Directory.Exists(HttpContext.Current.Server.MapPath("~/Images/Product/")).Equals(false))
Directory.CreateDirectory(HttpContext.Current.Server.MapPath("~/Images/Product/"));
FUPhoto.SaveAs(HttpContext.Current.Server.MapPath(OriginalImageFullPath));
ProductImageEntity objProdImage = new ProductImageEntity();
objProdImage.ProductID = ProductID;
if (ImgUploadResponse != "")
objProdImage.Image = "";
else
objProdImage.Image = ImageName;
if (!String.IsNullOrEmpty(objProdImage.Image))
new ProductImageBLL().InsertUpdateProductImage(objProdImage);
}
}
Please refer the below code for watermark logo to add from code side.
using (Image image = Image.FromFile(#"C:\Users\Public\Pictures\Sample Pictures\Desert.jpg"))
using (Image watermarkImage = Image.FromFile(#"C:\Users\Public\Pictures\Sample Pictures\watermark.png"))
using (Graphics imageGraphics = Graphics.FromImage(image))
using (TextureBrush watermarkBrush = new TextureBrush(watermarkImage))
{
int x = (image.Width / 2 - watermarkImage.Width / 2);
int y = (image.Height / 2 - watermarkImage.Height / 2);
watermarkBrush.TranslateTransform(x, y);
imageGraphics.FillRectangle(watermarkBrush, new Rectangle(new Point(x, y), new Size(watermarkImage.Width+1, watermarkImage.Height)));
image.Save(#"C:\Users\Public\Pictures\Sample Pictures\Desert_watermark.jpg");
}
I have installed and tried your dll. Everything is good but one issue. The watermark text is added vertically to vertical images (images whose height is bigger than width). Better solution is to add watermark in a horizantal line to vertical images as well as horizantal images. Thanks anyway.
--Edit--
I have solved the problem within this code, which checks and changes the orientation of the image in need. (uploadedImage is the image that i read from stream)
if (uploadedImage.PropertyIdList.Contains(0x0112))
{
PropertyItem propOrientation = uploadedImage.GetPropertyItem(0x0112);
short orientation = BitConverter.ToInt16(propOrientation.Value, 0);
if (orientation == 6)
{
uploadedImage.RotateFlip(RotateFlipType.Rotate90FlipNone);
}
else if (orientation == 8)
{
uploadedImage.RotateFlip(RotateFlipType.Rotate270FlipNone);
}
else
{
// Do nothing
}
}
Recently I've published a nugget package that do add image water mark with control over opacity and target spot to place the watermark in. Additionally you can add text watermark and do image crop/resize as well.
install via nugget:
Install-Package LazZiya.ImageResize
then you can use the code as below:
//get image from local path
var img = Image.FromFile("wwwroot\\images\\lum3n-358833-unsplash.jpg");
//scale and crop, 600x250 center focus
var newImg = ImageResize.ScaleAndCrop(img, 600, 250, TargetSpot.Center);
//watermark image path
var imgWatermark = "wwwroot\\images\\icon.png";
//add image watermark
newImg.ImageWatermark(imgWatermark,
TargetSpot.TopRight, //define target spot
10, //margin
37); //opacity (0-100)
//save new image
newImg.SaveAs("wwwroot\\images\\600x250-image-watermark.jpg");
//dispose to free up memory
img.Dispose();
newImg.Dispose();
[UPDATE]
The package is updated and some methods has been changed, and better support for more image formats is available (including animated gif).
See the docs for more details.
see live demo page.
I am placing a watermark on a Document, but sometimes the watermark ends up behind some image and I can't bring it to front. I tried to set the ZOrderPosition and ZOrder property to high values like 99 but it still not in front of everything else.
The problem occurs because watermark shape resides inside header footer story of Word document and main content is inside body story (please see Story class). If you insert a watermark using Microsoft Word 2016, you will observe the same behavior. All content of document's header/footer is always behind the main content of the document.
However, you may overcome this problem by manually inserting watermarks in each Page. You can achieve this by moving the cursor to the first Run in each Page of your document and then making those Runs as an anchor points for your watermarks. Please see the following code for example:
Document doc = new Document(MyDir + #"input.doc");
Node[] runs = doc.GetChildNodes(NodeType.Run, true).ToArray();
for (int i = 0; i < runs.Length; i++)
{
Run run = (Run)runs[i];
int length = run.Text.Length;
Run currentNode = run;
for (int x = 1; x < length; x++)
{
currentNode = SplitRun(currentNode, 1);
}
}
DocumentBuilder builder = new DocumentBuilder(doc);
PageSetup ps = builder.PageSetup;
NodeCollection smallRuns = doc.GetChildNodes(NodeType.Run, true);
LayoutCollector collector = new LayoutCollector(doc);
int pageIndex = 1;
foreach (Run run in smallRuns)
{
if (collector.GetStartPageIndex(run) == pageIndex)
{
Shape watermark = new Shape(doc, Aspose.Words.Drawing.ShapeType.TextPlainText);
watermark.RelativeHorizontalPosition = RelativeHorizontalPosition.Page;
watermark.RelativeVerticalPosition = RelativeVerticalPosition.Page;
watermark.Width = 300;
watermark.Height = 70;
watermark.HorizontalAlignment = HorizontalAlignment.Center;
watermark.VerticalAlignment = VerticalAlignment.Center;
watermark.Rotation = -40;
watermark.Fill.Color = Color.Gray;
watermark.StrokeColor = Color.Gray;
watermark.TextPath.Text = "watermarkText";
watermark.TextPath.FontFamily = "Arial";
watermark.Name = string.Format("WaterMark_{0}", Guid.NewGuid());
watermark.WrapType = WrapType.None;
builder.MoveTo(run);
builder.InsertNode(watermark);
pageIndex++;
}
}
doc.Save(MyDir + #"output\18.3.doc");
///////////////////////////////////////
private static Run SplitRun(Run run, int position)
{
Run afterRun = (Run)run.Clone(true);
afterRun.Text = run.Text.Substring(position);
run.Text = run.Text.Substring((0), (0) + (position));
run.ParentNode.InsertAfter(afterRun, run);
return afterRun;
}
Hope, this helps. I work with Aspose as Developer Evangelist.
Hi I am looking to print a StackPanel that contains a listbox which can contain an infinite number of items and therefore needs to print over multiple pages. I found this code online and it works fine.
public static FixedDocument GetFixedDocument(FrameworkElement toPrint, PrintDialog printDialog)
{
if (printDialog == null)
{
printDialog = new PrintDialog();
}
var capabilities = printDialog.PrintQueue.GetPrintCapabilities(printDialog.PrintTicket);
var pageSize = new Size(printDialog.PrintableAreaWidth, printDialog.PrintableAreaHeight);
var visibleSize = new Size(capabilities.PageImageableArea.ExtentWidth, capabilities.PageImageableArea.ExtentHeight);
var fixedDoc = new FixedDocument();
//If the toPrint visual is not displayed on screen we neeed to measure and arrange it
toPrint.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
toPrint.Arrange(new Rect(new Point(0, 0), toPrint.DesiredSize));
//
var size = toPrint.DesiredSize;
//Will assume for simplicity the control fits horizontally on the page
double yOffset = 0;
while (yOffset < size.Height)
{
var vb = new VisualBrush(toPrint)
{
Stretch = Stretch.None,
AlignmentX = AlignmentX.Left,
AlignmentY = AlignmentY.Top,
ViewboxUnits = BrushMappingMode.Absolute,
TileMode = TileMode.None,
Viewbox = new Rect(0, yOffset, visibleSize.Width, visibleSize.Height)
};
var pageContent = new PageContent();
var page = new FixedPage();
((IAddChild)pageContent).AddChild(page);
fixedDoc.Pages.Add(pageContent);
page.Width = pageSize.Width;
page.Height = pageSize.Height;
var canvas = new Canvas();
FixedPage.SetLeft(canvas, capabilities.PageImageableArea.OriginWidth);
FixedPage.SetTop(canvas, capabilities.PageImageableArea.OriginHeight);
canvas.Width = visibleSize.Width;
canvas.Height = visibleSize.Height;
canvas.Background = vb;
page.Children.Add(canvas);
yOffset += visibleSize.Height;
}
return fixedDoc;
}
However this causes certain items of a listbox to be cut off at the bottom of a page and continued on the next page (as shown below). Is it possible to modify this code in any way to determine the size of the page and if the current listboxitem does not fit onto this page that it starts on the next page? Quite new to all this so any help would be greatly appreciated.
I had a similiar task once and came up with this code, which uses a 'dummy' renderer to determine the height of the element up front and then either adds it to the current page or creates a new one. For sure, that's not a very beautiful solution, but it did the job at the time. Maybe you can take sth. away from it.
Size A4Size = new Size(793.92, 1122.24);
Size InfiniteSize = new Size(double.PositiveInfinity, double.PositiveInfinity);
var pages = new List<FrameworkElement>();
int pageNumber = 0;
var printDate = DateTime.Now;
var size = A4Size;
var currentPage = new Report(size, printDate);
currentPage.Render();
var listElements = new Queue<ElementsToPrint>(...);
var dummyRenderer = new Viewbox();
dummyRenderer.Child = currentPage;
dummyRenderer.Measure(InfiniteSize);
dummyRenderer.Arrange(new Rect(dummyRenderer.DesiredSize));
dummyRenderer.UpdateLayout();
var template = (DataTemplate)View.FindResource("ItemTemplate");
dummyRenderer.Child = null;
var availableHeight = currentPage.View.ActualHeight;
while (listElements.Count > 0)
{
var elementToRender = listElements.Dequeue();
dummyRenderer.Child = new ListViewItem()
{
Content = elementToRender,
ContentTemplate = template,
Foreground = Brushes.Black
};
dummyRenderer.Measure(InfiniteSize);
dummyRenderer.Arrange(new Rect(dummyRenderer.DesiredSize));
dummyRenderer.UpdateLayout();
var renderedItem = (ListViewItem)dummyRenderer.Child;
dummyRenderer.Child = null;
var willItFit = availableHeight > renderedItem.ActualHeight;
if (willItFit)
{
currentPage.DataListView.Items.Add(renderedItem);
availableHeight -= renderedItem.ActualHeight;
}
else
{
dummyRenderer.Child = currentPage;
dummyRenderer.Measure(InfiniteSize);
dummyRenderer.Arrange(new Rect(dummyRenderer.DesiredSize));
dummyRenderer.UpdateLayout();
dummyRenderer.Child = null;
pages.Add(currentPage);
// Set up a new Page
pageNumber++;
currentPage = new DiaryReport(size,pageNumber,printDate,anonymous);
dummyRenderer.Child = currentPage;
dummyRenderer.Measure(InfiniteSize);
dummyRenderer.Arrange(new Rect(dummyRenderer.DesiredSize));
dummyRenderer.UpdateLayout();
dummyRenderer.Child = null;
availableHeight = currentPage.DataListView.ActualHeight;
currentPage.DataListView.Items.Add(renderedItem);
availableHeight -= renderedItem.ActualHeight;
}
I can't load all grid spots with images at once. I have a 5x5 grid and it is intended to load 25 random images in random spots. With 25 images it should fill out the entire grid.
I can't figure out why there are empty spots when I load 25 or when I load less. I'm having one image repeat itself throughout the entire grid in order to avoid image format related issues. I think the problem might be related to the Random class.
Here is the code:
private readonly Random _r = new Random();
public void LoadPictures(int numberOfPictures)
{
// Create a 2d array of specified dimensions
var picArr = new bool[5, 5];
for (int j = 0; j < numberOfPictures; j++)
{
// Get the images from the specified folder
string[] imagePaths = Directory.GetFiles(
Environment.CurrentDirectory + "/images");
bool invalidPlacement = true; // default is true
while (invalidPlacement)
{
var i = new Image();
try
{
// Load the image with a random Picture
var uri = new Uri(imagePaths[_r.Next(0, imagePaths.Length)]);
i.Source = new BitmapImage(uri);
Debug.WriteLine(uri.AbsolutePath);
i.Width = ImageWidth;
i.Height = ImageHeight;
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
// Put it somewhere
int row = _r.Next(5);
Thread.Sleep(TimeSpan.FromMilliseconds(50));
int col = _r.Next(5);
// Check to see if there is something there
if (picArr[col, row] == false)
{
picArr[col, row] = true;
Grid.SetColumn(i, col);
Grid.SetRow(i, row);
Background2.Children.Add(i);
AnimateControl(i, 100, 100, 0, 0);
invalidPlacement = false;
}
}
}
}