Search code examples
c#pdfjpeguwpsyncfusion

Change PdfImage type (Syncfusion PDF)


So I'm using Syncfusion Controls for UWP XAML, and I'm trying to insert JPEGs into a PDF I'm creating, but PdfImage seems to always return bitmaps. Or at least images with bitmap-like file sizes. Is there any way to ensure the images being inserted are of JPEG size? The images I'm inputting are JPEGs to begin with. I'd be fine with bitmaps if I wasn't making PDFs of manga (Japanese comic books), i.e. the size per manga right now ranges from 50-150MB.

It's not a working sample, but here's what I'm using right now.

public async void SaveAsPdf(Stream fs, Manga manga)
    {
        var m = manga;
        var c = m.Content;

        if (fs.Length != 0) return;
        var pdf = new PdfDocument();
        var pages = await GetPages(m);
        pdf.PageSettings.SetMargins(0);


        pdf.FileStructure.IncrementalUpdate = true;
        pdf.EnableMemoryOptimization = true;
        pdf.Compression = PdfCompressionLevel.Best;


        for (var pi = 0; pi < c.ContentPages; pi++)
        {
            var section = pdf.Sections.Add();
            var mr = section.PageSettings.Margins = new PdfMargins();
            mr.All = 0;
            var page = section.Pages.Add();
            var g = page.Graphics;
            page.DefaultLayerIndex = 0;
            var pu = pages[pi];
            var client = new HttpClient();
            var im = await client.GetAsync(pu);
            var pdi = PdfImage.FromStream(im.Content.ReadAsStreamAsync().Result);

            g.DrawImage(pdi, new PointF(0, 0), g.ClientSize);
            await pdf.SaveAsync(fs);
        }
        await pdf.SaveAsync(fs);
        pdf.DocumentInformation.Title = c.ContentName;
        pdf.DocumentInformation.Author += string.Join(", ", c.ContentArtists.Select(x => x.Attribute));
        pdf.DocumentInformation.Keywords += string.Join(", ", c.ContentTags.Select(x => x.Attribute)).Replace("\"", string.Empty);
        pdf.Save(fs);
        pdf.Close(true);

        var toast = Notifications.NotifyMangaDownloaded(m);
        ToastNotificationManager.CreateToastNotifier().Show(toast);
        fs.Dispose();
    }

I'd ask about the memory leak but it'd probably be best if I made another post for that.

Thanks in advance.

(I posted this on the Syncfusion forums but I felt like I might get a better response here)


Solution

  • Well, I refactored some of the methods and the memory leak ended up being the cause. Lesson learned: using statements are your friends.

    To be a little more specific, I just created a file as a destination for the PDF, then called

    using (Stream s = new FileStream(/*string*/>f.Path, FileMode.OpenOrCreate))
    {
        await Task.Run(() => SaveAsPdf(/*StorageFile*/f, /*Manga*/m));
    }
    

    Various other things needed to be moved around, but leaving the FileStream open ended up being the problem.