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!