Page 1 of 1

How to replace an image

PostPosted: Sun Sep 21, 2008 5:18 am
by neversaydie
Case1:
I have an image1 in document and want to replace it with image2.

Case2:
Or I have a variable ${image1} and want to replace that with an actual image.

These are not text replacement but replacement of an image in place of a text or image.

Case1 - attempt:
I follow the example (OpenMainDocumentAndTraverse.java) and try to detect the Image in the document and modiify the URI. For an image it does not detect the binary part as org.docx4j.wml.Drawing object but as org.docx4j.wml.CTPicture. I am unable to find any way to update the referenece to a new image from the CTPicture object. If I debug the code I do not see any such class embedded.


Case 2 - attempt:
I follow the example (OpenMainDocumentAndTraverse.java) and inside walkList() method when I reach replacement part, I do below code snippet:
for (Object o : children) {
if (o instanceof JAXBElement) {
if (((JAXBElement) o).getDeclaredType().getName().equals("org.docx4j.wml.Text")) {
Text t = (Text) ((JAXBElement) o).getValue();
if (t.getValue().contains("$image1")) {
createImagePart(wordMLPackage);
}
}}}

}

createImagePart(WordprocessingMLPackage wordMLPackage) method is same as sample AddImage.java.

I get a Concurrent modification exception with List. I tried with an iterator instead of java1.5 for loop. And same exception.
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(Unknown Source)
at java.util.AbstractList$Itr.next(Unknown Source)
at com.cisco.test.ModifySmallDocUC_STS.walkJAXBElements(ModifySmallDocUC_STS.java:137)

Any help on this would be appreciated.

Thanks.

Re: How to replace an image

PostPosted: Mon Sep 22, 2008 11:56 pm
by neversaydie
Using Jason's input that there is no need to update an uri rather try to update the BinaryPart itself, I could get cas1 (i.e. replace an image with a different one) successfully. Thanks Jason.

Below is code snippet:

private String ml = "<w:p xmlns:ve=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" "
+ "xmlns:o=\"urn:schemas-microsoft-com:office:office\" "
+ "xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" "
+ "xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\" "
+ "xmlns:v=\"urn:schemas-microsoft-com:vml\" "
+ "xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" "
+ "xmlns:w10=\"urn:schemas-microsoft-com:office:word\" "
+ "xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" "
+ "xmlns:wne=\"http://schemas.microsoft.com/office/word/2006/wordml\">"
+ "<w:r><w:pict>"
+ "<v:shapetype id=\"_x0000_t75\" coordsize=\"21600,21600\" o:spt=\"75\" o:preferrelative=\"t\" path=\"m@4@5l@4@11@9@11@9@5xe\" filled=\"f\" stroked=\"f\">"
+ "<v:stroke joinstyle=\"miter\"/>"
+ "<v:formulas>"
+ "<v:f eqn=\"if lineDrawn pixelLineWidth 0\"/>"
+ "<v:f eqn=\"sum @0 1 0\"/><v:f eqn=\"sum 0 0 @1\"/>"
+ "<v:f eqn=\"prod @2 1 2\"/>"
+ "<v:f eqn=\"prod @3 21600 pielWidth\"/>"
+ "<v:f eqn=\"prod @3 21600 pixelHeight\"/>"
+ "<v:f eqn=\"sum @0 0 1\"/>"
+ "<v:f eqn=\"prod @6 1 2\"/>"
+ "<v:f eqn=\"prod @7 21600 pixelWidth\"/>"
+ "<v:f eqn=\"sum @8 21600 0\"/>"
+ "<v:f eqn=\"prod @7 21600 pixelHeight\"/>"
+ "<v:f eqn=\"sum @10 21600 0\"/>"
+ "</v:formulas>"
+ "<v:path o:extrusionok=\"f\" gradientshapeok=\"t\" o:connecttype=\"rect\"/><o:lock v:ext=\"edit\" aspectratio=\"t\"/>"
+ "</v:shapetype>"
+ "<v:shape id=\"_x0000_i1025\" type=\"#_x0000_t75\" style=\"width:187.5pt;height:187.5pt\">"
+ "<v:imagedata r:id=\"${rEmbedId}\" o:title=\"\"/>"
+ "</v:shape></w:pict></w:r></w:p>";


BinaryPart imagePart = new BinaryPart(new PartName("/word/media/image1.png"));
InputStream is = new FileInputStream("scfloral15.png");
imagePart.setBinaryData(is);
imagePart.setContentType(new ContentType(ContentTypes.IMAGE_PNG));
imagePart.setRelationshipType(Namespaces.IMAGE);

Relationship rel = wordMLPackage
.getMainDocumentPart()
.getRelationshipsPart().getRelationshipByID("rId5"); //Hard coded now by looking at the doc
//iterate through wordMLPackage.getMainDocumentPart().getRelationshipsPart() -> each Relationship gives the target back e.g. image1.png



HashMap<String, String> mappings = new HashMap<String, String>();
mappings.put("rEmbedId", rel.getId());

rel = wordMLPackage.getMainDocumentPart().addTargetPart(imagePart);
rel.setId( mappings.get("rEmbedId"));

wordMLPackage.getMainDocumentPart().addObject(
XmlUtils.unmarshallFromTemplate(ml, mappings));

Re: How to replace an image

PostPosted: Tue Sep 23, 2008 11:56 pm
by neversaydie
Here is a helpful hint from Jason:

> I see.
> I can very well identify the w:t element which I want to replace.
> After that, to add a w:pict element, I can either do XML string
> unmarshall (which will not work in this case) or I can create a
> CTPicture Object (?) and add.
> If I go with a CTPicture, I do not see any method to add an URI to image.
> Same is true for Pic class.

Either should work.

If you created a CTPicture object programmatically using the object factory, you'd then add a v:shape, and to that v:imagedata. It is v:imagedata which has @r:id

You might need the other child v:shapetype which Word generated. If you do, then it starts to become tedious.

The string unmarshall method is a better idea, and should work. You just need to cast the resulting object to org.docx4j.wml.CTPicture:

org.docx4j.wml.CTPicture mypic =
(org.docx4j.wml.CTPicture)XmlUtils.unmarshallFromTemplate(IMAGE_ML,
mappings);

By the way CTPicture is the default name JAXB generated. Most of the commonly used classes we renamed - CT stands for "complex type"; and "ST" stands for simple type.

cheers

Jason