Проблема при попытке удалить встроенные изображения из PDF с помощью iTextSharp
Я недавно обнаружил iTextSharp.
Я исследовал проблему с производительностью при рендеринге PDF-документов, и Бруно Лоуаги (автор iText) любезно объяснил мне причину, по которой у меня возникла такая проблема: это было связано с количеством «встроенных изображений» в моих PDF-документах. Он также объяснил основы для удаления этих «встроенных изображений» ... (Моя цель - «возможно» показать предварительный просмотр документа с четким уведомлением о том, что это не настоящий документ и что этот документ может открываться очень медленно. Я четко понимаю, что то, что я пытаюсь сделать, далеко не надежно / безопасно / ... Проблема должна быть решена на другом уровне, например: при создании документов, ...)
К сожалению, мне не удается самостоятельно выполнить очистку: / Вот некоторый код, который у меня есть в настоящее время (вдохновленный различными образцами, найденными в stackOverflow) ...
PdfReader pdfReader = new PdfReader(filename);
try
{
//pdfReader.RemoveUnusedObjects();
var cleanfilename = filename.Replace(".pdf", ".clean.pdf");
if (File.Exists(cleanfilename))
File.Delete(cleanfilename);
using (var file = new FileStream(cleanfilename, FileMode.Create))
{
var pdfstamper = new PdfStamper(pdfReader, file);
for (var page = 1; page <= pdfReader.NumberOfPages; page++)
{
PdfDictionary pageDict = pdfReader.GetPageN(page);
PdfObject pageObj = pageDict.GetDirectObject(PdfName.CONTENTS);
if (pageObj.IsStream())
{
CleanStream(pageObj);
}
else if (pageObj.IsArray())
{
PdfArray pageArray = pageDict.GetAsArray(PdfName.CONTENTS);
for (int j = 0; j < pageArray.Size; j++)
{
PdfIndirectReference arrayElement = (PdfIndirectReference)pageArray[j];
pageObj = pdfReader.GetPdfObject(arrayElement.Number);
if (pageObj.IsStream())
{
CleanStream(pageObj);
}
}
}
}
pdfstamper.Close();
}
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex.Message, "Error");
}
finally
{
pdfReader.Close();
}
а также
Regex regEx = new Regex("\\nBI.*?\\nEI", RegexOptions.Compiled);
private void CleanStream(PdfObject obj)
{
var stream = (PRStream)obj;
var data = PdfReader.GetStreamBytes(stream);
var currentContent = Encoding.ASCII.GetString(data);
var newContent = regEx.Replace(currentContent, "");
var newData = Encoding.ASCII.GetBytes(newContent);
stream.SetData(newData);
}
Он отлично работает на PDF без встроенных изображений ... Но «текст» исчезает со страниц, где есть встроенные изображения.
Я думал, что проблема была с заменой. Но это не тот случай, насколько я могу судить. Используя следующий код (вид прохода), с выходным документом все в порядке:
private void CleanStream(PdfObject obj)
{
var stream = (PRStream)obj;
var data = PdfReader.GetStreamBytes(stream);
stream.SetData(data);
}
Однако, используя следующий код, который теоретически не меняет ни одного байта (не так ли?), Выходные документы больше не отображаются нормально (некоторое содержимое, похоже, не отображается)?!?!?
private void CleanStream(PdfObject obj)
{
var stream = (PRStream)obj;
var data = PdfReader.GetStreamBytes(stream);
var currentContent = Encoding.ASCII.GetString(data);
var newData = Encoding.ASCII.GetBytes(currentContent);
stream.SetData(newData);
}
Похоже, преобразование байтового массива в строку и обратно в массив не является «прозрачной» операцией.
Я действительно не понимаю!?! Но с другой стороны, я знаю, что я настоящий новичок в отношении PDF. Что мне не хватает?
Это совсем не критично (мне все равно, не удастся ли мне удалить эти встроенные изображения). Но мне сейчас очень интересно понять, что происходит: D
Вот образец PDF:https://drive.google.com/file/d/0Byqch0ZyIb5DWDdmSTJ3SDMxMW8/edit?usp=sharing