PDFsharp & MigraDoc Foundation

PDFsharp - A .NET library for processing PDF & MigraDoc Foundation - Creating documents on the fly
It is currently Thu Mar 28, 2024 5:42 pm

All times are UTC


Forum rules


Please read this before posting on this forum: Forum Rules



Post new topic Reply to topic  [ 4 posts ] 
Author Message
PostPosted: Fri Aug 25, 2017 6:59 am 
Offline

Joined: Fri Aug 25, 2017 6:22 am
Posts: 2
Hi,

using below code (PDFSharp 3.5 beta 4) leads to different file sizes (after saving byte array resp stream to file) and different quality of graphics. But ... there's no difference in creation of pdf document.
Saving via bytearray or stream result in the same pdf quality, saving direct as file is slightly bigger and has a good quality. Attached zip contains 3 pdf's, please look at page 3 on each pdf - there you see my logo with described quality problems.

Code:
public partial class PdfBuilder
    {
        // default: 1 cm border on each side (except left side to have space for punch holes)
        private XUnit _leftBorder = new XUnit(2, XGraphicsUnit.Centimeter);
        private XUnit _topBorder = new XUnit(1, XGraphicsUnit.Centimeter);
        private XUnit _rightBorder = new XUnit(1, XGraphicsUnit.Centimeter);
        private XUnit _bottomBorder = new XUnit(1, XGraphicsUnit.Centimeter);


        private void SetBorder(double left, double top, double right, double bottom, XGraphicsUnit xGraphicsUnit)
        {
            _leftBorder = new XUnit(left, xGraphicsUnit);
            _topBorder = new XUnit(top, xGraphicsUnit);
            _rightBorder = new XUnit(right, xGraphicsUnit);
            _bottomBorder = new XUnit(bottom, xGraphicsUnit);
        }


        private void CreatePdfFromImages(IEnumerable<Image> images, string fileName)
        {
            var doc = new PdfDocument(fileName);

            CreatePdf(images, doc);
            doc.Close(); // this will save the document
        }


        private void CreatePdfFromImages(IEnumerable<Image> images, out byte[] pdfArray)
        {
            var h = new MemoryStream();
            var doc = new PdfDocument(h);

            CreatePdf(images, doc);

            using (var ms = new MemoryStream())
            {
                doc.Save(ms, false);
                pdfArray = ms.ToArray();
            }
        }


        private void CreatePdfFromImages(IEnumerable<Image> images, out MemoryStream pdf)
        {
            pdf = new MemoryStream();

            var h = new MemoryStream();
            var doc = new PdfDocument(h);
           

            CreatePdf(images, doc);

            doc.Save(pdf, false);
            doc.Close();

            pdf.Seek(0, SeekOrigin.Begin);
        }


        private void CreatePdf(IEnumerable<Image> images, PdfDocument document)
        {
            document.Info.CreationDate = DateTime.Now;
            document.Info.Author = "holonsoft.pdf";

            foreach (var rawImage in images)
            {
                var page = document.AddPage();
                page.Size = PageSize.A4;
                page.TrimMargins.Left = _leftBorder;
                page.TrimMargins.Right = _rightBorder;
                page.TrimMargins.Top = _topBorder;
                page.TrimMargins.Bottom = _bottomBorder;

                var graphics = XGraphics.FromPdfPage(page);
                using (var imgStream = ConvertImageToStream(rawImage))
                {
                    var image = XImage.FromStream(imgStream);
                    graphics.DrawImage(image, 0, 0);
                }
            }

        }


        private Stream ConvertImageToStream(Image rawImage)
        {
            var result = new MemoryStream();

            rawImage.Save(result, rawImage.RawFormat);

            return result;
        }
    }



Code:
_pdfBuilder.CreatePdfFromImages(imgList, out pdfStream);

            var f = new FileStream(_fileNameViaStream, FileMode.CreateNew);

            pdfStream.CopyTo(f);
            f.Close();


Code:
byte[] array;
            _pdfBuilder.CreatePdfFromImages(imgList, out array);

            File.WriteAllBytes(_fileNameViaArray, array);


Attachments:
File comment: 3 pdf's generated with the code above
pdfbuilder_examples.7z [243.48 KiB]
Downloaded 336 times
Top
 Profile  
Reply with quote  
PostPosted: Fri Aug 25, 2017 9:43 am 
Offline
PDFsharp Expert
User avatar

Joined: Sat Mar 14, 2015 10:15 am
Posts: 909
Location: CCAA
Hi!

The large file starts with "%PDF-1.4", the smaller files start with "%PDF-0.0".
Alpha-transparency requires at least 1.4 (nice logo), with 0.0 PDFsharp does not use alpha-transparency and the logo looks edgy.

So how do you set version number to 0.0?
I don't know. Version 0.0 is not valid, 1.0 is the minimum value.
Maybe you're doing something "unusual" that leads to the 0.0 version number.

Code to set it explicitly (before calling Save()):
Code:
// Set version to PDF 1.4 (Acrobat 5) because we use transparency.
if (document.Version < 14)
  document.Version = 14;


What's the purpose of "ConvertImageToStream"? There is XImage.FromImage which takes an Image.

The "h" here makes no sense:
Code:
var h = new MemoryStream();
            var doc = new PdfDocument(h);
Why not use "var doc = new PdfDocument();" instead?

_________________
Best regards
Thomas
(Freelance Software Developer with several years of MigraDoc/PDFsharp experience)


Top
 Profile  
Reply with quote  
PostPosted: Fri Aug 25, 2017 11:54 am 
Offline

Joined: Fri Aug 25, 2017 6:22 am
Posts: 2
Hi Thomas,
thank you very much for your quick answer.

Setting the doc version explicitly solved the issue.
I didn't set anywhere in code the version, it seems that PDFSharp 'save to file' does it automatically but 'saving to a stream' does not set this value.

It was a relict hoping that PDFSharp does not dispose it when saving. But the stream will always diposed by PDFSharp, so: you're right, the h helper stream is useless here. Thank you :-)

Thomas wrote:
What's the purpose of "ConvertImageToStream"? There is XImage.FromImage which takes an Image.

No, I'm sorry. Just XImage.FromFile() / .FromStream() available.

Best regards
Christian


Top
 Profile  
Reply with quote  
PostPosted: Fri Aug 25, 2017 12:33 pm 
Offline
PDFsharp Expert
User avatar

Joined: Sat Mar 14, 2015 10:15 am
Posts: 909
Location: CCAA
All samples use "new PdfDocument()" without parameter and "Save".
Alternatively you can use "new PdfDocument(<file or stream>)" and call "Close()" - but you shouldn't call "Save" in this case.
Mixing both patterns could lead to problems.

Not use if "new PdfDocument(<file or stream>)" forgets to set the version.

Only the GDI+ build has "XImage.FromImage". When using class Image in your code, you might as well use the GDI+ build.
If you create your Image objects from streams or files, then better also create the XImage objects from the same streams or files.

_________________
Best regards
Thomas
(Freelance Software Developer with several years of MigraDoc/PDFsharp experience)


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 4 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 140 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Privacy Policy, Data Protection Declaration, Impressum
Powered by phpBB® Forum Software © phpBB Group