У меня есть проблема: нарисовать прямоугольник, чтобы покрыть все изображения в PDF.Я уже знаю, что изображение может быть записано как изображение, но оно также может быть записано как графические векторы.
Я хочу получить местоположения (X, Y, Ширина, Высота) нормальных изображений (сохраненных, например, какрастровое изображение) и нарисуйте прямоугольник поверх них, чтобы не покрывать другие элементы на странице, например текст под этим изображением (я не хочу охватывать всю страницу, если изображение занимает только 30% от нее).До сих пор я написал две функции для получения изображений:
public List<Image> GetImagesFromPdf(string path)
{
List<Image> imageList = new List<Image>();
PdfReader reader = new PdfReader(path);
for (int i=1;i<reader.NumberOfPages;i++)
{
PdfDictionary pdfDict = reader.GetPageN(i);
imageList.AddRange(GetImagesFromDocument(pdfDict, reader));
}
return imageList;
}
private List<Image> GetImagesFromDocument(PdfDictionary dict, PdfReader doc)
{
List<Image> imageList = new List<Image>();
PdfDictionary resources = (PdfReader.GetPdfObject(dict.Get(PdfName.RESOURCES))) as PdfDictionary;
PdfDictionary objects = (PdfReader.GetPdfObject(resources.Get(PdfName.XOBJECT))) as PdfDictionary;
if (objects != null)
{
foreach (PdfName objKey in objects.Keys)
{
PdfObject obj = objects.Get(objKey);
if (obj.IsIndirect())
{
PdfDictionary tg = (PdfDictionary)(PdfReader.GetPdfObject(obj));
PdfName objectType = (PdfName)(PdfReader.GetPdfObject(tg.Get(PdfName.SUBTYPE)));
if (
PdfName.IMAGE.Equals(objectType)
||PdfName.IMAGEB.Equals(objectType)
|| PdfName.IMAGEC.Equals(objectType)
|| PdfName.IMAGEI.Equals(objectType)
)
{
int xrefIdx = ((PRIndirectReference)obj).Number;
PdfObject pdfObj = doc.GetPdfObject(xrefIdx);
PdfStream str = (PdfStream)(pdfObj);
iTextSharp.text.pdf.parser.PdfImageObject pdfImage =
new iTextSharp.text.pdf.parser.PdfImageObject((PRStream)str);
System.Drawing.Image img = pdfImage.GetDrawingImage();
imageList.Add(img);
}
else if (PdfName.FORM.Equals(objectType) || PdfName.GROUP.Equals(objectType))
{
imageList.AddRange(GetImagesFromDocument(tg, doc));
}
}
}
}
return imageList;
}
Я вызываю функцию GetImagesFromPdf
, а затем для каждой страницы я запускаю функцию: GetImagesFromDocument
.Это приводит к правильному количеству изображений в pdf, но я действительно не знаю, как получить местоположения (X, Y, Ширина, Высота) .... Что-нибудь еще, что я могу использовать?Или я должен использовать другой механизм для этого?
Любая помощь будет оценена.PS.я кое-что заметил ... Я также попытался реализовать интерфейс IExtRenderListener
и заметил, что при наличии изображения в pdf вызывается функция RenderImage
.Есть одна функция, которую я могу вызвать на объекте renderInfo
, и результат инстерецирует, я получаю эти значения (функция называется GetImageCTM ()):
![The function is called GetImageCTM()](https://i.stack.imgur.com/4wDir.png)
Когда я пытался покрыть изображения, записанные в виде графических векторов, у меня не получилось.Ни одно изображение не было покрыто, но я получил около 15 000 очень маленьких прямоугольников, к сожалению, ни один не был виден.Я использовал этот код:
public void ModifyPath(PathConstructionRenderInfo renderInfo)
{
if (renderInfo.Operation == PathConstructionRenderInfo.RECT)
{
float x = renderInfo.SegmentData[0];
float y = renderInfo.SegmentData[1];
float w = renderInfo.SegmentData[2];
float h = renderInfo.SegmentData[3];
Vector a = new Vector(x, y, 1).Cross(renderInfo.Ctm);
Vector b = new Vector(x + w, y, 1).Cross(renderInfo.Ctm);
Vector c = new Vector(x + w, y + h, 1).Cross(renderInfo.Ctm);
Vector d = new Vector(x, y + h, 1).Cross(renderInfo.Ctm);
Rectangle rect = new Rectangle(x,y,x+w, y+h); //is that correct ?
}
else
{
for (int i = 0; i < renderInfo.SegmentData.Count - 1; i += 2)
{
float x = renderInfo.SegmentData[i];
float y = renderInfo.SegmentData[i + 1];
Vector a = new Vector(x, y, 1).Cross(renderInfo.Ctm);
// Rectangle rect = new Rectangle(x, y, x + ..., y + ...); What to do here ?
}
}
modifyPathCounter++;
}
ОК, его уже решили, решение здесь:
if (renderInfo.Operation == PathConstructionRenderInfo.RECT)
{
float x = renderInfo.SegmentData[0];
float y = renderInfo.SegmentData[1];
float w = renderInfo.SegmentData[2];
float h = renderInfo.SegmentData[3];
Vector a = new Vector(x, y, 1).Cross(renderInfo.Ctm);
Vector b = new Vector(x + w, y, 1).Cross(renderInfo.Ctm);
Vector c = new Vector(x + w, y + h, 1).Cross(renderInfo.Ctm);
Vector d = new Vector(x, y + h, 1).Cross(renderInfo.Ctm);
Rectangle rect = new Rectangle(a[0],a[1],c[0], c[1]);
//SquaresToDraw image = new SquaresToDraw(0, rect.Left, rect.Bottom, rect.Right, rect.Top);
// squaresToDraw.Add(image);
}
else
{
if (renderInfo.SegmentData!=null)
{
for (int i = 0; i < renderInfo.SegmentData.Count - 1; i += 2)
{
float x = renderInfo.SegmentData[i];
float y = renderInfo.SegmentData[i + 1];
Vector a = new Vector(x, y, 1).Cross(renderInfo.Ctm);
Rectangle rect = new Rectangle(x, y, a[0], a[1]);
SquaresToDraw image = new SquaresToDraw(0, rect.Left, rect.Bottom, rect.Right, rect.Top);
squaresToDraw.Add(image);
// Rectangle rect = new Rectangle(x, y, x + ..., y + ...); What to do here ?
}
}
}