PDFSharp compress filesize in c# - c#

In my App i generate an PDF-File with PDFSharp.Xamarin which I got from this site:
https://github.com/roceh/PdfSharp.Xamarin
Everything is working fine.
In my PDF-Document I have many Images, which are compressed.
But the file size of my PDF-Document is too large.
Is there a possibility to compress my PDF-Document before saving it?
How can I work with the PdfSharp.SharpZipLib.Zip Namespace to deflate the file size?
UPDATE:
Here is my Code:
document = new PdfDocument();
document.Info.Title = nameDok.Replace(" ", "");
document.Info.Author = "---";
document.Info.CreationDate = DateTime.Now;
document.Info.Subject = nameDok.Replace(" ", "");
//That is how i add Images:
XImage image = XImage.FromStream(lstr);
gfx.DrawImage(image, 465, YPrev - 2, newimagewf, newimagehf);
document.CustomValues.CompressionMode = PdfCustomValueCompressionMode.Compressed;
document.Options.FlateEncodeMode = PdfFlateEncodeMode.BestCompression;
document.Save(speicherPfad);
Thanks for everyone.

I only know the original PDFsharp, not the Xamarin port: images are deflated automatically using SharpZipLib.
Make sure to use appropriate source images (e.g. JPEG or PNG, depending on the image).
On the project start page they write:
"Currently all images created via XGraphics are converted to jpegs with 70% quality."
This could mean that images are re-compressed, maybe leading to larger files than before.
Take one JPEG file, convert it to PDF, and check the size of the image (in bytes) in the PDF file.

Related

How do I create/edit a PNG file in C#?

I've written a program that can create digital art. Images like the Mandelbrot Set and the Julia Set. But I'm looking to save these images as PNGs. At present, in Java, I'm generating the images in an application window and then taking a screen shot of the display. However, I lose the finer detail of these images. Plus, this method also reduces the physical size of the images as well. I want to potentially be able to make a big poster out of these pictures.
In C#, I'm using the following:
Bitmap myimage = new Bitmap("image.png"); and: myimage.SetPixel(x,y, Color.FromArgb(255*colors[x,y], 255*colors[x,y], 255*colors[x,y]); where colors[,] is some value between 0 and 1.
The code runs fine, minus the Bitmap declaration. My understanding is that new Bitmap(filepath); allows you to edit and manipulate the PNG image. Am I right to think that? How do I create/edit a PNG file in C#?
(edit)PS: The PNG file, "image.png", does exist in the solution folder.
Firstly you have to know the step by step process in creating the PNG file.
Setup Aspose.Imaging for .NET package from Nuget.org.
Include reference to following two namespaces: Aspose.Imaging,
Aspose.Imaging.ImageOptions.
Specify license using SetLicense method before converting.
Read BMP file into an Image object.
Set attributes for output PNG image using PngOptions class.
Save the output PNG image with the specified PNG options.
Code to create PNG image from BMP
using System;
//Use following namespaces to create PNG image
using Aspose.Imaging;
using Aspose.Imaging.ImageOptions;
namespace CreatePNGImage
{
class Program
{
static void Main(string[] args)
{
//Set license before creating PNG image from BMP
Aspose.Imaging.License AsposeImagingLicense = new Aspose.Imaging.License();
AsposeImagingLicense.SetLicense(#"c:\asposelicense\license.lic");
//load input BMP image
Image BmpToPngImage = Image.Load("InputBMPImage.bmp");
//set attributes of the output PNG file
PngOptions PNGImageOptions = new PngOptions();
PNGImageOptions.ResolutionSettings = new ResolutionSetting(300, 300);
PNGImageOptions.CompressionLevel = 6;
//save converted output PNG image
BmpToPngImage.Save("OutputPNGImage.png", PNGImageOptions);
}
}
}
Try this to create the PNG file out of c#.

Blank PNG file after conversion with GhostScript.NET

In my software I make 2 PDF files from 1 input file using iTextSharp. I'd like to convert these files into 2 different PNG images using GS, but something strange happens. I use this code for the conversion:
GhostscriptRasterizer rasterizer = new GhostscriptRasterizer();
rasterizer.Open(newFilePath1, gsInfo, false);
Image image = rasterizer.GetPage(300, 300, 1);
image.Save(subDirPath + serCod + "_S1.png");
rasterizer.Close();
rasterizer.Open(newFilePath2, gsInfo, false);
image = rasterizer.GetPage(300, 300, 1);
image.Save(subDirPath + serCod + "_S2.png");
rasterizer.Close();
When I save the first image it shows like a blank page and the file name is the same of newFilePath1 without .pdf but with .png.
When I look at the second image with the same file name as newFilePath2 with .png instead of .pdf, it has the image of the newFilePath1 pdf file.
How can I solve this problem?
I'd suggest you try the same operation using Ghostscript from the command line (instead of through Ghostscript.NET). If you get the same result then you can open a bug report at bugs.ghostscript.com and someone can look at it (remember to include the PDF file(s) and command lines).
Otherwise you'll have to contact jhabjan (the author of Ghostscript.NET) and have him investigate it.

Efficient way to upload images in SQP.NET

I am still very much learning ASP.NET using c# and Webmatrix. I have put together a photography competition site but can't quite find an ideal way of uploading images. I don't see the point of uploading images greater than 1200x900 (projectors maximum resolution) so want to make sure images are small as possible.
I am using tag and checking he image size. If it's too big I am using 'ImageResizer' to resize the image when saving. The only way I know to check the size is to convert the 'HttpPostedFileBase' file into an image using System.Drawing.Image. But when the image is 36Mpixels (it is a photography club) this is taking an age just to read the height and width properties. Can I just load the first x bytes to read the properties or do I have to read the whole image?
The second reason I am converting to an image is to extract the exif data. Again is there an easier and quicker way to read the exif data?
I hope my question makes sense this is all a bit new to me.
simplified code:
HttpPostedFileBase uploadedFile = Request.Files[0];
using (System.Drawing.Image image = System.Drawing.Image.FromStream(uploadedFile.InputStream, true, true))
{
string Exif;
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
try{
Exif = encoding.GetString(image.GetPropertyItem(36867).Value);
}
catch
{
Exif="";
}
if (image.Width <Convert.ToInt32(MaxWidth) && image.Height <Convert.ToInt32(MaxHeight))
{
// SAVE IMAGE AS IS
image.Save(fileSavePath);
// LOAD IMAGE DETAILS WITH EXIF
db.Execute("INSERT INTO CompImages (ImageTitle,CompID,GroupID,ClubID,FileName,UserID,ExifDate) VALUES(#0,#1,#2,#3,#4,#5,#6)",ImageTitle,CompID,GroupID,ClubID,fileName,WebSecurity.CurrentUserId,DateTaken);
}
else
{
// LOAD IMAGE DETAILS WITH EXIF
db.Execute("INSERT INTO CompImages (ImageTitle,CompID,GroupID,ClubID,FileName,UserID,ExifDate) VALUES(#0,#1,#2,#3,#4,#5,#6)",ImageTitle,CompID,GroupID,ClubID,fileName,WebSecurity.CurrentUserId,DateTaken);
// RESIZE IMAGE
ImageResizer.ImageJob iF = new ImageResizer.ImageJob(image, "~/UpImages/"+CompID+"/"+fileName, new ImageResizer.ResizeSettings(
"width="+MaxWidth+";height="+MaxHeight+";format=jpg;mode=max"));
iF.CreateParentDirectory = true; //Auto-create the uploads directory.
iF.Build();
}
}
The only way I know to check the size is to convert the
'HttpPostedFileBase' file into an image using System.Drawing.Image.
You could also checkout the ContentLength property directly:
int uploadedFileSize = uploadedFile.ContentLength;
The second reason I am converting to an image is to extract the exif
data. Again is there an easier and quicker way to read the exif data?
I am not aware of a built-in class in the BCL that would allow you to read EXIF information without loading the image in memory but you could use some third party library like this one: http://www.codeproject.com/Articles/36342/ExifLib-A-Fast-Exif-Data-Extractor-for-NET-2-0

.net compressing pdf generated with crystal reports

As of now, we are generating PDFs programmatically using crystal reports and saving it to database. The PDF document has barcode image in it. Each file is of size 120-150 KB.
Everything is running fine but lately we are facing problem with huge growth in database size and storage requirements. This is due to 100 - 1000 records being generated each day.
Is there any way to compress the PDF files and then store it. Any API/tools available that perform these without creating issue to the barcode.Can we gain much reduction in size after compression?
Or any alternative way of storing the data will be good?
Any suggestions on this would be highly appreciated.
Thanks,
Sveerap
Unfortunately, you won't gain much by compressing a PDF as it is already compressed.
Many compressed PDF files can be compressed further.
Size of a PDF file can usually be decreased by:
removing unused objects (if any)
removing extra whitespace characters from the file (not from the visual content)
using object streams (a PDF 1.5 feature)
I do not know how well Crystal Report compresses PDFs but you might want to try Docotic.Pdf library and the following code and see if your files can be compressed better.
public static void CompressExistingDocument(string original, string output)
{
using (PdfDocument pdf = new PdfDocument(original))
{
pdf.SaveOptions.Compression = PdfCompression.Flate;
pdf.SaveOptions.UseObjectStreams = true;
pdf.SaveOptions.RemoveUnusedObjects = true;
pdf.SaveOptions.WriteWithoutFormatting = true;
pdf.Save(output);
}
FileInfo originalFileInfo = new FileInfo(original);
FileInfo compressedFileInfo = new FileInfo(output);
MessageBox.Show(
String.Format("Original file size: {0} bytes;\r\nCompressed file size: {1} bytes",
originalFileInfo.Length, compressedFileInfo.Length));
System.Diagnostics.Process.Start(output);
}
Disclaimer: I work for the vendor of the library.

iTextsharp - PDF file size after inserting image

I'm currently converting some legacy code to create PDF files using iTextSharp. We're creating a largish PDF file that contains a number of images, which I'm inserting like so:
Document doc = new Document(PageSize.A4, 50, 50, 25, 25);
PdfWriter writer = PdfWriter.GetInstance(doc, myStream);
writer.SetFullCompression();
doc.Open();
Image frontCover = iTextSharp.text.Image.GetInstance(#"C:\MyImage.png");
//Scale down from a 96 dpi image to standard itextsharp 72 dpi
frontCover.ScalePercent(75f);
frontCover.SetAbsolutePosition(0, 0);
doc.Add(frontCover);
doc.Close();
Inserting an image (20.8 KB png file) seems to increase the PDF file size by nearly 100 KB.
Is there a way of compressing the image before entry (bearing in mind that this needs to be of reasonable print quality), or of further compressing the entire PDF? Am I even performing any compression in the above example?
The answer appears to have been that you need to set an appropriate version of the PDF spec to target and then set the compression as follows:
PdfWriter writer = PdfWriter.GetInstance(doc, ms);
PdfContentByte contentPlacer;
writer.SetPdfVersion(PdfWriter.PDF_VERSION_1_5);
writer.CompressionLevel = PdfStream.BEST_COMPRESSION;
This has brought my file size down considerably. I also found that PNG's were giving me the best results as regards to final size of document.
I did some experiments this morning. My test image was 800x600 with a file size of 100.69K when saved as a PNG. I inserted this into a PDF (using iTextSharp and the usual GetInstance() method) and the file size increased from 301.71K to 402.63K. I then re-saved my test image as a raw bitmap with file size of 1,440,054. I inserted this into the PDF and the file size went DOWN to 389.81K. Interesting!
I did some research on the web for a possible explanation, and, based on what I found, it looks like iTextSharp does not compress images, but rather it compresses everything with some generic compression. So in other words, the BMP is not actually converted to another file type, it's just compressed very much like you would by ZIPping it. Whatever they're doing, it must be good, for it compressed better than the image with PNG compression. I assume iTextSharp woudld try to compress the PNG but would compress at 0% since it already is compressed. (This is inconsistent with the original author's observations, though... Paddy said his PDF size increased much more than the size of the PNG... not sure what to make of that. I can only go on my own experiments).
Conclusions:
1) I don't need to add some fancy library to my project to convert my (eventual dynamically-created) image to PNG; it actually does better to leave it totally uncompressed and let iTextSharp do all the compression work.
2) I also read stuff on the web about iTextSharp saving images at a certain DPI. I did NOT see this problem... I used ScalePercent() method to scale the bitmap to 1% and the file size was the same and there was no "loss" in the bitmap pixels in the bitmap... this confirms that iTextSharp is doing a simple, nice, generic lossless compression.
It seems that PDF requires the png to be transcoded to something else, jpeg, most probably.
see here: http://forums.adobe.com/message/2952201
The only thing I can think of is to convert png to smallest jpeg first, including scaling down 75%, then importing that file without scaling.
use:
var image = iTextSharp.text.Image.GetInstance(srcImage, ImageFormat.Jpeg);
image.ScaleToFit(document.PageSize.Width, document.PageSize.Height);
//image.ScalePercent(75f);
image.SetAbsolutePosition(0, 0);
document.Add(image);
document.NewPage();

Categories

Resources