Generate Text PDF with Bytes error - c#

I am trying to generate PDF, but I have some problems with the bytes error that hanging the system and web.
I found some reason why but could not find a solution yet.
When I debug, my codec stopped here and freeze my web. Then after I restart it will be very slowly loading my page.
I found out that if I wrote more than 200 characters, it will bug the system. But if I don't, everything will be fine. I just want to know why.
I am not very expert here. Thanks for you help. This is the codec debug where it stopped and frozen. Can anyone help me?
Dim bytes() As Byte
Dim fs As FileStream = New FileStream(strNewPathPDF, FileMode.Open, FileAccess.Read)
Dim reader As BinaryReader = New BinaryReader(fs)
bytes = reader.ReadBytes(CType(fs.Length, Integer))
fs.Close()

You get the nreco dll from here: https://www.nuget.org/packages/NReco.PdfGenerator/
And you can use the following code:
NReco.PdfGenerator.HtmlToPdfConverter nPdf = new NReco.PdfGenerator.HtmlToPdfConverter();
nPdf.Size = PageSize.Letter;
PageMargins mar = new PageMargins();
mar.Bottom = -5;
mar.Left = -5;
mar.Top = -5;
mar.Right = -5;
nPdf.Margins = mar;
nPdf.Orientation = PageOrientation.Landscape;
var pdffilename = "D:\Documents"+"filename" + ".pdf";
var htmltext="this testing pdf"
var pdfBytes = nPdf.GeneratePdf(htmltext);
File.WriteAllBytes(pdffilename, pdfBytes);

Related

Streamed File Contains Strange Characters - An Encoding Issue

I have a WCF service end-point which generates an excel file and returns this file as a MemoryStream in the end in order to make client download the relevant file.
The file generated on the respective directory has no issues. I don't see any strange characters when I open and check it.
But, the file I returned with MemoryStream is full of strange unreadable characters.
My end-point is like that,
public Stream GetEngagementFeedFinalizeData(int workspaceId, string startDate, string endDate, Stream data)
{
try
{
string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;";
string extension = "xls";
string fileName = "report-" + DateTime.Now.Ticks.ToString();
string contentDisposition = string.Format(CultureInfo.InvariantCulture, "attachment; filename={0}.{1}", fileName, extension);
WebOperationContext.Current.OutgoingResponse.ContentType = contentType;
WebOperationContext.Current.OutgoingResponse.Headers.Set("Content-Disposition", contentDisposition);
//Here is some business logic and fetching data from db. Not any encoding
//related issue. The data set is assigned to a variable
//named "feedFinalizeDataTable" in the end
feedFinalizeDataTable.TableName = "Summary";
DataSet dataSet = new DataSet();
dataSet.Tables.Add(feedFinalizeDataTable);
using (ExcelPackage excelPackage = new ExcelPackage())
{
foreach (DataTable dt in dataSet.Tables)
{
ExcelWorksheet sheet = excelPackage.Workbook.Worksheets.Add(dt.TableName);
sheet.Cells["A1"].LoadFromDataTable(dt, true);
}
var path = System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory);
var filePath = path + "\\" + "New.xls";
excelPackage.SaveAs(new System.IO.FileInfo(filePath)); //This file is flawless
FileStream fs = new FileStream(filePath, FileMode.Open);
int length = (int)fs.Length;
WebOperationContext.Current.OutgoingResponse.ContentLength = length;
byte[] buffer = new byte[length];
int sum = 0;
int count;
while ((count = fs.Read(buffer, sum, length - sum)) > 0)
{
sum += count;
}
fs.Close();
return new MemoryStream(buffer); //This file is full of unreadable chars as per above shared screenshot
}
I'm using OfficeOpenXml to generate excel files.
Then, I checked both files encoding by open them with notepad. I saw that the file on the directory (the flawless one) has ANSI encoding. And, the one which is returned by the end-point (the broken one) has UTF-8 encoding.
After that, I try to change the encoding type of the stream like this,
var byteArray = System.IO.File.ReadAllBytes(filePath);
string fileStr = new StreamReader(new MemoryStream(byteArray), true).ReadToEnd();
var encd = Encoding.GetEncoding(1252); //On the other topics I saw that ANSI represented with 1252
var end = encd.GetBytes(fileStr);
return new MemoryStream(end);
But, this doesn't help too. Though some of the strange characters are replaced with some other strange characters, but as I said, streamed file is still unreadable. And, when I open it with notepad to see its encoding, I saw that its still UTF-8.
Thus, I'm kind of stuck. I have also try directly to stream the generated excel file (without writing it to a directory and then reading it) with OfficeOpenXml's built in function called .GetAsByteArray(), but the downloaded file looks exactly the same as per above screenshot.
Thanks in advance.

GhostscriptRasterizer.PageCount always returns zero

This problem has already been discussed here:GhostscriptRasterizer Objects Returns 0 as PageCount value
But the answer to this question did not help me solve the problem.
In my case, it doesn’t help from kat to an older version of Ghostscript. 26 and 25. I always have PageCount = 0, and if the version is lower than 27, I get an error "Native Ghostscript library not found."
private static void PdfToPng(string inputFile, string outputFileName)
{
var xDpi = 100; //set the x DPI
var yDpi = 100; //set the y DPI
var pageNumber = 1; // the pages in a PDF document
using (var rasterizer = new GhostscriptRasterizer()) //create an instance for GhostscriptRasterizer
{
rasterizer.Open(inputFile); //opens the PDF file for rasterizing
//set the output image(png's) complete path
var outputPNGPath = Path.Combine(outputFolder, string.Format("{0}_Page{1}.png", outputFileName,pageNumber));
//converts the PDF pages to png's
var pdf2PNG = rasterizer.GetPage(xDpi, yDpi, pageNumber);
//save the png's
pdf2PNG.Save(outputPNGPath, ImageFormat.Png);
Console.WriteLine("Saved " + outputPNGPath);
}
}
I was struggling with the same problem and ended up using iTextSharp just to get the page count. Below is a snippet from the production code:
using (var reader = new PdfReader(pdfFile))
{
// as a matter of fact we need iTextSharp PdfReader (and all of iTextSharp) only to get the page count of PDF document;
// unfortunately GhostScript itself doesn't know how to do it
pageCount = reader.NumberOfPages;
}
Not a perfect solution but this is exactly what solved my problem. I left that comment there to remind myself that I have to find a better way somehow but I’ve never bothered to come back because it just works fine as it is...
PdfReader class is defined in iTextSharp.text.pdf namespace.
And I'm using Ghostscript.NET.GhostscriptPngDevice instead of GhostscriptRasterizer to rasterize the specific page of PDF document.
Here is my method that rasterizes the page and saves it to PNG file
private static void PdfToPngWithGhostscriptPngDevice(string srcFile, int pageNo, int dpiX, int dpiY, string tgtFile)
{
GhostscriptPngDevice dev = new GhostscriptPngDevice(GhostscriptPngDeviceType.PngGray);
dev.GraphicsAlphaBits = GhostscriptImageDeviceAlphaBits.V_4;
dev.TextAlphaBits = GhostscriptImageDeviceAlphaBits.V_4;
dev.ResolutionXY = new GhostscriptImageDeviceResolution(dpiX, dpiY);
dev.InputFiles.Add(srcFile);
dev.Pdf.FirstPage = pageNo;
dev.Pdf.LastPage = pageNo;
dev.CustomSwitches.Add("-dDOINTERPOLATE");
dev.OutputPath = tgtFile;
dev.Process();
}
Hope that would help...

Telerik Reporting - Picturebox is already in use error

I have a following exception on my report:
I think i tried every possible way to fix it, I even changed the way I load that image to load it from base64 string:
var bytes = Convert.FromBase64String(#"base64string");
using (var ms = new MemoryStream(bytes))
{
pbLogo.Value = Image.FromStream(ms);
}
The problem is that it's non deterministic - sometimes it will work and sometines and will only appear from time to time, without any way to always reproduce it.
Edit - this is a designer code:
// pbLogo
//
this.pbLogo = new Telerik.Reporting.PictureBox()
this.pbLogo.Location = new Telerik.Reporting.Drawing.PointU(Telerik.Reporting.Drawing.Unit.Inch(0D), Telerik.Reporting.Drawing.Unit.Inch(3.9418537198798731E-05D));
this.pbLogo.MimeType = "";
this.pbLogo.Name = "pbLogo";
this.pbLogo.Size = new Telerik.Reporting.Drawing.SizeU(Telerik.Reporting.Drawing.Unit.Pixel(185D), Telerik.Reporting.Drawing.Unit.Pixel(42D));
this.pbLogo.Sizing = Telerik.Reporting.Drawing.ImageSizeMode.ScaleProportional;
this.pbLogo.Style.BackgroundImage.MimeType = "image/jpeg";
this.pbLogo.Style.BackgroundImage.Repeat = Telerik.Reporting.Drawing.BackgroundRepeat.NoRepeat;
this.pbLogo.Value = "";

C# How to remove XPKeywords (PropertyItem 0x9c9e) from an image

I was having trouble editing or removing keywords from a photograph. The following works to replace the keywords successfully:
...
string s_keywords = "tag1;tag2;tag3";
PropertyItem item_keyword = (PropertyItem)FormatterServices.GetUninitializedObject(typeof(PropertyItem));
item_keyword.Id = 0x9c9e; // XPKeywords
item_keyword.Type = 1;
item_keyword.Value = System.Text.Encoding.Unicode.GetBytes(s_keywords + "\0");
item_keyword.Len = item_keyword.Value.Length;
image.SetPropertyItem(item_keyword);
...
Note that my experiments show that image.RemovePropertyItem(0x9c9e); seems to have no effect on the saved image. Instead use the above code with s_keywords = "";
Don't do it this way: The following code works to remove the keywords, but results in the jpeg being re-encoded and loosing some quality (the image file goes from about 4MB to < 2MB and I can see some slight visual differences):
...
Image image_copy = new Bitmap(image);
foreach (var pi in image.PropertyItems)
{
if (pi.Id != 0x9c9e) image_copy.SetPropertyItem(pi);
}
image.Dispose();
image = (Image)image_copy.Clone();
...
I'm was having similar issues with setting the XPTitle - setting the propertyItem 0x9c9b seemed to have no effect in the saved image, instead I had to open the file as a BitmapFrame, extract the BitmapMetadata and use the Title property, then build a new jpeg using JpegBitmapEncoder - thus re-encoding and loosing image quality.
...
BitmapFrame bf_title = BitmapFrame.Create(new Uri(tmp_file, UriKind.Relative));
BitmapMetadata bmd_title = (BitmapMetadata)bf_title.Metadata.Clone();
bmd_title.Title = new_title;
BitmapFrame bf_new = BitmapFrame.Create(bf_title, bf_title.Thumbnail, bmd_title, bf_title.ColorContexts);
JpegBitmapEncoder je = new JpegBitmapEncoder();
je.Frames.Add(bf_new);
FileStream fs = new FileStream(tmp_file, FileMode.Create);
je.Save(fs);
fs.Close();
...
See my answer below for the correct way to change the title.
This was driving me crazy, I hope this can help someone else...
Note that the above keywords code now works perfectly.
I'm answering this because I could not find sample code to do this when I searched - so hopefully someone else will find this useful.
To change the title use the following code. The problem was that there are two tags that affect how windows shows the title - one of which (0x010e) takes priority over the XPTitle (0xc9b) tag...
...
string new_value = "New title for the image";
PropertyItem item_title = (PropertyItem)FormatterServices.GetUninitializedObject(typeof(PropertyItem));
item_title.Id = 0x9c9b; // XPTitle 0x9c9b
item_title.Type = 1;
item_title.Value = System.Text.Encoding.Unicode.GetBytes(new_value + "\0");
item_title.Len = item_title.Value.Length;
image.SetPropertyItem(item_title);
PropertyItem item_title2 = (PropertyItem)FormatterServices.GetUninitializedObject(typeof(PropertyItem));
item_title2.Id = 0x010e; // ImageDescription 0x010e
item_title2.Type = 2;
item_title2.Value = System.Text.Encoding.UTF8.GetBytes(new_value + "\0");
item_title2.Len = item_title2.Value.Length;
image.SetPropertyItem(item_title2);
image.Save("new_filename.jpg", ImageFormat.Jpeg)
image.Dispose();
...
Note - Another potential issue, you need to save the image to a new location. You can then dispose of the image and copy it into the original location if desired.

Loading Canon .CR2 files in .NET

I am trying to process Canon RAW .CR2 files using C#. My code is as follows:
BitmapDecoder bmpDec = BitmapDecoder.Create(new Uri(origFile), BitmapCreateOptions.DelayCreation, BitmapCacheOption.None);
BitmapEncoder bmpEnc = new BmpBitmapEncoder();
bmpEnc.Frames.Add(bmpDec.Frames[0]);
Stream ms = new MemoryStream();
bmpEnc.Save(ms);
Image srcImage = Bitmap.FromStream(ms);
The first few lines seem to run without a hitch, but the line
bmEnc.Save(ms);
just hangs without completing and without raising any exception.
Has anyone had any success with this?
Know this is a old thread but I found a nice easy to use library (Magick.NET).
How to do a conversion:
using (MagickImage image = new MagickImage("StillLife.CR2"))
{
image.Write("StillLife.jpg");
}
https://github.com/dlemstra/Magick.NET/blob/master/docs/ReadRawImageFromCamera.md
Details of nuget package installation:
Install-Package Magick.NET-Q16-AnyCPU
https://github.com/dlemstra/Magick.NET
W8.1 or W7 after applying https://www.microsoft.com/en-us/download/details.aspx?id=26829 seems to work well
var files = Directory.GetFiles(#"D:\DCIM","*.CR2");
for(var i = 0; i < files.Length; i++) {
Console.Write("{0,-4}: {1} => ", i, files[i]);
var bmpDec = BitmapDecoder.Create(new Uri(files[i]), BitmapCreateOptions.DelayCreation, BitmapCacheOption.None);
var bmpEnc = new JpegBitmapEncoder();
bmpEnc.QualityLevel = 100;
bmpEnc.Frames.Add(bmpDec.Frames[0]);
var oldfn = Path.GetFileName(files[i]);
var newfn = Path.ChangeExtension(oldfn, "JPG");
using(var ms = File.Create(Path.Combine(#"D:\DCIM\100CANON", newfn), 10000000)) {
bmpEnc.Save(ms);
}
Console.WriteLine(newfn);
}
I don't believe BitmapDecoder understands .CR2. It is not a conventional image format by far, as it contains the raw bayer-sensor image (one color per pixel), not a standard image.
If you want to convert CR2 and other camera raw formats, you should look at DCRaw: http://www.cybercom.net/~dcoffin/dcraw/ or libraw (based on dcraw, friendly as a library): http://www.libraw.org/

Categories