I am trying to figure out if its possible to convert PDF document into a series of images.
Currently looking to migrate from ASP.NET 4.6 to ASP.CORE and this is so far the roadbloack to it.
I cannot seem to find any working examples for ASP Core of this currently.
Appreciate any help i can get.
You can use Docnet,
Here is an example code from project:
private static byte[] GetModifiedImage(IPageReader pageReader)
{
var rawBytes = pageReader.GetImage();
var width = pageReader.GetPageWidth();
var height = pageReader.GetPageHeight();
var characters = pageReader.GetCharacters();
using (var bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb))
{
bmp.AddBytes(rawBytes);
bmp.DrawRectangles(characters);
using (var stream = new MemoryStream())
{
bmp.Save(stream, ImageFormat.Png);
return stream.ToArray();
}
}
}
Hope it helps
Cheers
Related
I want to open an existing PDF document and add different annotations to it. Namely bookmarks and some text
I am using the Telerik Document Processing Library (dpl) v2019.3.1021.40
I am new to dpl , but I believe the RadFlowDocument is the way to go.
I am having troubles creating the RadFlowDocument
FlowProvider.PdfFormatProvider provider = new FlowProvider.PdfFormatProvider();
using (Stream stream = File.OpenRead(sourceFile))
{
--> RadFlowDocument flowDoc = provider.Import(stream);
}
The line indicated w/ the arrow give the error "Import Not Supported"
There is a telerik blog post here
https://www.telerik.com/forums/radflowdocument-to-pdf-error
It seems relevant, but not 100% sure.
It cautions to be sure the providers are mated correctly, I believe they are in my example....
Again, ultimate goal is to open a PDF and add some stuff to it. I think the RadFlowDocument is the right direction. If there is a better solution, Im happy to hear that too.
I figured it out. The DPL is pretty good, but doc is still growing, hope this helps someone out...
This draws from a myriad of articles, I cant begin to cite them all.
There are 2 notions for working w/ PDFs in the DPL.
FixedDocument takes pages. I think this is meant for sewing docs together.
FlowDocument I believe lays things out like an HTML renderer would.
I am using Fixed, mainly b/c I can get that to work.
using System;
using System.IO;
using System.Windows; //nec for Size struct
using System.Diagnostics; //nec for launching the pdf at the end
using Telerik.Windows.Documents.Fixed.Model;
//if you have fixed and flow provider, you have to specify, so I make a shortcut
using FixedProvider = Telerik.Windows.Documents.Fixed.FormatProviders.Pdf;
using Telerik.Windows.Documents.Fixed.Model.Editing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace DocAggregator
{
[TestClass]
public class UnitTest2
{
[TestMethod]
public void EditNewFIle_SrcAsFixed_TrgAsFixed()
{
String dt = #"C:\USERS\greg\DESKTOP\DPL\";
String sourceFile = dt + "output.pdf";
//Open the sourceDoc so you can add stuff to it
RadFixedDocument sourceDoc;
//a provider parses the actual file into the model.
FixedProvider.PdfFormatProvider fixedProv = new FixedProvider.PdfFormatProvider();
using (Stream stream = File.OpenRead(sourceFile))
{
//'populate' the doc object from the file
//using the FLOW classes, I get "Import Not Supported".
sourceDoc = fixedProv.Import(stream);
}
int pages = sourceDoc.Pages.Count;
int pageCounter = 1;
int xoffset = 150;
int yoffset = 50;
//editor is the thing that lets you add elements into the source doc
//Like the provider, the Editor needs to match the document class (Fixed or Flow)
RadFixedDocumentEditor editor = new RadFixedDocumentEditor(sourceDoc);
foreach (RadFixedPage page in sourceDoc.Pages)
{
FixedContentEditor pEd = new FixedContentEditor(page);
Size ps = page.Size;
pEd.Position.Translate(ps.Width - xoffset, ps.Height - yoffset);
Block block = new Block();
block.HorizontalAlignment = Telerik.Windows.Documents.Fixed.Model.Editing.Flow.HorizontalAlignment.Center;
block.TextProperties.FontSize = 22;
block.InsertText(string.Format("Page {0} of {1} ", pageCounter, pages));
pEd.DrawBlock(block);
pageCounter++;
}
string exportFileName = "addedPageNums.pdf";
if (File.Exists(exportFileName))
{
File.Delete(exportFileName);
}
File.WriteAllBytes(exportFileName, fixedProv.Export(sourceDoc));
//launch the app
Process.Start(exportFileName);
}
}
}
In the features section on NReco's site, in the examples list: there is a line about MergePdf.
I have looked in the API-reference and using the intellisense in visualstudio but I can't find anything.
I wan't to merge several pdf's before I sent them in a mail. The Pdf's is generated with nreco wkhtmltopdf with different headers and footers which I could not get to work in the same generate so I splitted the generation and now I want to merge the pdf's again.
Or do I have to get yet another library involved.
Just sharing what I ended up with. At least for now.
It is a modification of the suggested solution with iTextSharp.
public static byte[] MergePdfs(IEnumerable<byte[]> pdfs)
{
using (var memoryStream = new MemoryStream())
{
var document = new Document(PageSize.A4);
var writer = PdfWriter.GetInstance(document, memoryStream);
document.Open();
var writerDirectContent = writer.DirectContent;
foreach (var pdf in pdfs)
{
var pdfReader = new PdfReader(pdf);
var numberOfPages = pdfReader.NumberOfPages;
for (var currentPageNumber = 1; currentPageNumber <= numberOfPages; currentPageNumber++)
{
document.SetPageSize(PageSize.A4);
document.NewPage();
var page = writer.GetImportedPage(pdfReader, currentPageNumber);
writerDirectContent.AddTemplate(page, 1f, 0, 0, 1f, 0, 0);
}
}
document.Close();
return memoryStream.ToArray();
}
}
There are 2 ways how you can achieve the goal you mentioned:
use GeneratePdfFromFiles method which accepts array of WkHtmlInput structures that allow you to specify header/footer separately for each input HTML file. As result one PDF is produced; note that this method requires a valid license key and is not available for a free library users
generate several PDFs in a standard way, and then merge them into one resulting PDF with help of iTextSharp library (free LGPL 4.1.6 can be used for this purpose).
For getting Pdf report in Asp.net MVC I am working with Stimulsoft 2015. The problem is that I have no idea how to convert my code in order to work with Stimulsoft Core in Asp.net Core. it seems some features are not available anymore in Stimulsoft Core (like StiReport).
This is the code which works fine in Asp.net MVC
public ActionResult GetReportSnapshot(string sort)
{
StiReport report = new StiReport();
report.Load(Server.MapPath("~/Reports/Jobs.mrt"));
report["#PrjectId"] = 1;
report["#OrderBy"] = sort;
report.Dictionary.Variables["title"] = new Stimulsoft.Report.Dictionary.StiVariable("title", sort);
report.Render();
MemoryStream stream = new MemoryStream();
report.ExportDocument(StiExportFormat.Pdf, stream);
stream.Position = 0;
FileStreamResult fsr = new FileStreamResult(stream, "application/pdf");
return fsr;
}
I will appreciate any help.
In NuGet Package Stimulsoft.Reports.Web.NetCore version 2018.3.5.
and Asp.Net core 2.0.
This is working for me, Try this:
public IActionResult GetReportSnapshot(string sort)
{
StiReport report = new StiReport();
report.Load(#"C:\Users\Admin\Desktop\report.mrt"); // laod report
report.Render();
report["#PrjectId"] = 1;
report["#OrderBy"] = sort;
report.Dictionary.Variables["title"] = new Stimulsoft.Report.Dictionary.StiVariable("title", sort);
// Create an PDF settings instance. You can change export settings.
var settings = new Stimulsoft.Report.Export.StiPdfExportSettings();
// Create an PDF service instance.
var service = new Stimulsoft.Report.Export.StiPdfExportService();
// Create a MemoryStream object.
var stream = new MemoryStream();
// Export PDF using MemoryStream.
service.ExportTo(report, stream, settings);
return File(stream.ToArray(), "application/octet-stream");
}
What nuget packages are you using? It could be you are missing the nuget packages containing the StiReport class. (I see they split up their library over multiple nuget packages)
Also it could be they have not migrated this part to dotnet core yet.
i'd advise you to click around there github repo and see if you can find any information there: https://github.com/stimulsoft, or on there website.
By the looks of nuget they have only recently started to migrate to dotnet core so this would suppose my second suggestion is the right suggestion.
I used QrEncoder (NuGet Package QrCode.Net) for generating QR Code in MVC 4. Now my question is how can I show this QR code in my RDLC Report dynamically. I searched through many websites but didn't got any feasible Solution.
One way would be to:
Create a handler in .net to dynamically generate the QR code based on querystring parameters and return it as a png.
setup the rdlc to have an image that is externally referenced.
when generating the report you will need to set it to allow external references
pass the url to the handler/image in the dataset being sent to the report and have that be the path for the image in the report.
When the report is generated it will then generate and show the QR code.
var data = db.spMemberDetailByMembership(CompanyId, BranchId, Convert.ToInt32(MemRegId)).Select(x => new SPMemberRegisterModel
{
ID = x.ID,
BookingPrice = x.BookingPrice,
MailingAddress = MailingAddress(x.ID),
BarCode = GenerateQrCode(x.UUID),
}).ToList();
reportdatasource.Value = data;
localReport.DataSources.Add(reportdatasource);
private byte[] GenerateQrCode(string qrmsg)
{
QRCoder.QRCodeGenerator qRCodeGenerator = new QRCoder.QRCodeGenerator();
QRCoder.QRCodeData qRCodeData = qRCodeGenerator.CreateQrCode(qrmsg, QRCoder.QRCodeGenerator.ECCLevel.Q);
QRCoder.QRCode qRCode = new QRCoder.QRCode(qRCodeData);
Bitmap bmp = qRCode.GetGraphic(5);
System.Web.UI.WebControls.Image imgBarCode = new System.Web.UI.WebControls.Image();
imgBarCode.Height = 150;
imgBarCode.Width = 150;
using (Bitmap bitMap = qRCode.GetGraphic(5))
{
using (MemoryStream ms = new MemoryStream())
{
bitMap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
byte[] byteImage = ms.ToArray();
return byteImage;
}
}
}
Updated my MVC3/.Net 4.5/Azure solution to MVC4.
My code for uploading an image to blob storage appears to fail each time in the upgraded MVC4 solution. However, when I run my MVC3 solution works fine. Code that does the uploading, in a DLL, has not changed.
I’ve uploaded the same image file in the MVC3 and MVC4 solution. I’ve inspected in the stream and it appears to be fine. In both instance I am running the code locally on my machine and my connections point to blob storage in cloud.
Any pointers for debugging? Any known issues that I may not be aware of when upgrading to MVC4?
Here is my upload code:
public string AddImage(string pathName, string fileName, Stream image)
{
var client = _storageAccount.CreateCloudBlobClient();
client.RetryPolicy = RetryPolicies.Retry(3, TimeSpan.FromSeconds(5));
var container = client.GetContainerReference(AzureStorageNames.ImagesBlobContainerName);
image.Seek(0, SeekOrigin.Begin);
var blob = container.GetBlobReference(Path.Combine(pathName, fileName));
blob.Properties.ContentType = "image/jpeg";
blob.UploadFromStream(image);
return blob.Uri.ToString();
}
I managed to fix it. For some reason reading the stream directly from the HttpPostFileBase wasn't working. Simply copy it into a new memorystream solved it.
My code
public string StoreImage(string album, HttpPostedFileBase image)
{
var blobStorage = storageAccount.CreateCloudBlobClient();
var container = blobStorage.GetContainerReference("containerName");
if (container.CreateIfNotExist())
{
// configure container for public access
var permissions = container.GetPermissions();
permissions.PublicAccess = BlobContainerPublicAccessType.Container;
container.SetPermissions(permissions);
}
string uniqueBlobName = string.Format("{0}{1}", Guid.NewGuid().ToString(), Path.GetExtension(image.FileName)).ToLowerInvariant();
CloudBlockBlob blob = container.GetBlockBlobReference(uniqueBlobName);
blob.Properties.ContentType = image.ContentType;
image.InputStream.Position = 0;
using (var imageStream = new MemoryStream())
{
image.InputStream.CopyTo(imageStream);
imageStream.Position = 0;
blob.UploadFromStream(imageStream);
}
return blob.Uri.ToString();
}