0

I used tags in the title, but I think in this case it is needed ;)

I am trying to compress all Images of a pdf file with a Windows store app using iTextSharp.

Through Google I didn't find any solution to this, but I found different approaches that I tried to Combine.

The code runs without an error, but it doesnt seem to do anything.

public async Task startCompressing()
    {
        var stream = await input.OpenAsync(FileAccessMode.ReadWrite);
        PdfReader reader = new PdfReader(stream.AsStream());

        Document doc = new Document();
        doc.Open();

        //Create our output PDF
        using (MemoryStream ms = new MemoryStream())
        {
            //Bind a stamper to the file and our reader
            using (PdfStamper stamper = new PdfStamper(reader, ms))
            {

                for (int i = 1; i < reader.NumberOfPages; i++)
                {
                    PdfDictionary page = reader.GetPageN(i);
                    //Get the xobject structure
                    PdfDictionary resources = (PdfDictionary)PdfReader.GetPdfObject(page.Get(PdfName.RESOURCES));
                    PdfDictionary xobject = (PdfDictionary)PdfReader.GetPdfObject(resources.Get(PdfName.XOBJECT));
                    if (xobject != null)
                    {
                        PdfObject obj;
                        //Loop through each key
                        foreach (PdfName name in xobject.Keys)
                        {
                            obj = xobject.Get(name);
                            if (obj.IsIndirect())
                            {
                                //Get the current key as a PDF object
                                PdfDictionary imgObject = (PdfDictionary)PdfReader.GetPdfObject(obj);
                                //See if its an image
                                if (imgObject.Get(PdfName.SUBTYPE).Equals(PdfName.IMAGE))
                                {
                                    //NOTE: There's a bunch of different types of filters, I'm only handing the simplest one here which is basically raw JPG, you'll have to research others
                                    if (imgObject.Get(PdfName.FILTER).Equals(PdfName.DCTDECODE))
                                    {
                                        //Get the raw bytes of the current image
                                        byte[] oldBytes = PdfReader.GetStreamBytesRaw((PRStream)imgObject);

                                        //convert ByteStream to InMemoryRandomAccessStream to be able to create a Bitmap
                                        var newStream = new InMemoryRandomAccessStream();
                                        await (newStream.AsStreamForWrite()).WriteAsync(oldBytes, 0, oldBytes.Length);
                                        await newStream.FlushAsync();

                                        var decoder = await BitmapDecoder.CreateAsync(newStream);
                                        var memStream = new InMemoryRandomAccessStream();
                                        var encoder = await BitmapEncoder.CreateForTranscodingAsync(memStream, decoder);

                                        encoder.BitmapTransform.InterpolationMode = BitmapInterpolationMode.Fant;

                                        try
                                        {
                                            await encoder.FlushAsync();
                                        }
                                        catch (Exception err)
                                        {
                                            throw err;
                                        }

                                        //Create a new iTextSharp image from our bytes
                                        iTextSharp.text.Image compressedImage = iTextSharp.text.Image.GetInstance(memStream.AsStream());
                                        //Kill off the old image
                                        PdfReader.KillIndirect(obj);
                                        //Add our image in its place
                                        //stamper.Writer.AddDirectImageSimple(compressedImage, (PRIndirectReference)obj);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

If I comment out the line:

stamper.Writer.AddDirectImageSimple(compressedImage, (PRIndirectReference)obj);

in my understanding I should lose the Images on all pages. Unfortunately this doesn't happen. It seems like nothing happens. Ignoring whatever I do to the streams and if thats correct,, at least this line should be enough to kill the images.

PdfReader.KillIndirect(obj);

As this doesn't happen, it seems like I have some Problems in my code, that I cannot figure out. The code runs without an error, executing all the lines (The check for jpeg is true aswell)

I couldn't find anything regarding compression with iTextSharp in Windows Store Apps. Maybe you can help me out?

Thanks for your help!

HideAndSeek
  • 374
  • 3
  • 16
  • Did you read the very specific comment that I wrote in the [original post](http://stackoverflow.com/questions/8740244/pdf-compression) "There's a bunch of different types of filters, I'm only handing the simplest one here which is basically raw JPG, you'll have to research others". Maybe you don't have an image that has the `DCTDECODE` filter applied. – Chris Haas Mar 11 '15 at 01:18
  • Yeah, I read it, but when debugging I found the if Statement regarding the filter gets evaluated to true. Ill Check this once more though. Thanks for your help! – HideAndSeek Mar 11 '15 at 08:43
  • http://stackoverflow.com/questions/12399597/free-pdf-writer-for-windows-8-metro-apps suggests that iTextSharp might have a problem with windows store apps. – Arctic Vowel Mar 11 '15 at 09:52
  • Please take a look at **step 3** in my answer to [this question](http://stackoverflow.com/questions/26580912/pdf-convert-to-black-and-white-pngs). By replacing the existing stream and by using the `PdfImage` class, you will avoid plenty of difficulties (difficulties that you are now facing as @ChrisHaas mentions in his comment). – Bruno Lowagie Mar 11 '15 at 13:54
  • I am still having issues createning the PdfStamper without using a FileStream :/ I really don't understand it anymore :/ Guess I am gonna drop this. Or wait till someone creates the code for to compress images in Windows store apps. Thanks for your help! – HideAndSeek Mar 12 '15 at 10:18

0 Answers0