Q:
Is there a way to replace a raster image in a PDF document without
creating a new page and copying all the elements over?
For example, I would like to do something similar to:
ElementReader page_reader = new ElementReader();
page_reader.Begin( page );
Element element;
while ((element = page_reader.Next()) != null)
{
if (element.GetType() == Element.Type.e_image)
{
//replace this image with another image
}
}
I can current do this by creating a new page and copying all the
elements over, replacing any image elements with another image. But
is there a way to "reassign" the element instead so that I don't have
to recreate a new page (I would assume that this would save some
time)? The hope would be to dynamically change the raster images
within a pdf::Page depending on where in the PDF I'm viewing and the
zoom level/DPI. What I'm try to do is relacing all high-resolution
images in the PDF with a lower resolution image.
----
A:
Yes, using PDFNet API you can replace/swap all images on an existing
page without touching the page content stream (i.e. without having to
create a new page copy ever elements, delete the old page, etc.).
You can access all image XObjects used on the page through page
resource dictionary (page.GetResources()):
SDF.Obj res = page.GetResources();
if (res != null) {
SDF.Obj images = res.FindObj("XObject")
if (images != null) {
SDF.DictInterator itr = images.DictBegin();
SDF.DictInterator end = images.DictEnd();
for (; itr!=end; itr.Next()) {
Obj image = itr.Value() // (C++; in C#/VB use itr.Value())
// check is the XObject is image or a form ... we are looking
for images only
Obj subtype = image.FindObj("Subtype")
if (subtype.GetName() == "Image") { // We have an image
pdftron.PDF.Image old_img = new pdftron.PDF.Image(image);
// or in C++ ... Image old_img(image);
pdftron.PDF.Image replacement_img = ... resample the old
image or get a new image
... now replace the old image with a new one
image.GetDoc().Swap(image.GetObjNum(),replacement_img.GetObjNum());
// that's it!
}
...