Bug 49765 - addPictures() not displaying Image in XWPF
Summary: addPictures() not displaying Image in XWPF
Status: RESOLVED WONTFIX
Alias: None
Product: POI
Classification: Unclassified
Component: XWPF (show other bugs)
Version: 3.10-FINAL
Hardware: PC All
: P4 blocker with 3 votes (vote)
Target Milestone: ---
Assignee: POI Developers List
URL:
Keywords: FAQ
Depends on:
Blocks: 55476
  Show dependency tree
 
Reported: 2010-08-17 12:49 UTC by bbarbee
Modified: 2022-03-20 18:00 UTC (History)
4 users (show)



Attachments
Word Generated (42.06 KB, application/vnd.openxmlformats-officedocument.wordprocessingml.document)
2010-08-25 17:48 UTC, bbarbee
Details
POI Generated (32.59 KB, application/vnd.openxmlformats-officedocument.wordprocessingml.document)
2010-08-25 17:48 UTC, bbarbee
Details
Sample Image (31.73 KB, image/jpeg)
2010-08-25 17:49 UTC, bbarbee
Details
document.xml POI version (197 bytes, text/plain)
2010-09-02 18:13 UTC, TK Gospodinov
Details
document.xml Word version (1.96 KB, text/plain)
2010-09-02 18:14 UTC, TK Gospodinov
Details
docx file after addin image (39.42 KB, application/octet-stream)
2011-07-05 13:33 UTC, Alexander S.
Details
The Run created with the POI method (499 bytes, text/xml)
2011-07-06 14:54 UTC, Stefan Stern
Details
The Run was created by Word (1.57 KB, text/xml)
2011-07-06 14:55 UTC, Stefan Stern
Details
Fix wrong namespace value (886 bytes, patch)
2011-07-07 13:40 UTC, Stefan Stern
Details | Diff
Sample code (3.20 KB, application/octet-stream)
2012-05-23 06:44 UTC, Romesh Soni
Details
document template for the addPicture test (29.24 KB, application/vnd.openxmlformats-officedocument.wordprocessingml.document)
2022-03-16 13:50 UTC, Stefan Edelbusch
Details
picture to insert in document by addPicture (768.70 KB, image/jpeg)
2022-03-16 13:52 UTC, Stefan Edelbusch
Details

Note You need to log in before you can comment on or make changes to this bug.
Description bbarbee 2010-08-17 12:49:24 UTC
When I use the method addPictures() for XWPF documents, I assume this adds the image data to the Word document without any additional code. When I call this method, I do see the size of the Word document grow, due to the image data, but the image is not displayed in the Word document at all. It seems to, at least, be adding the image data to the Word document, but it doesn't seem to set it up correctly so it will actually display in the Word document.
Comment 1 Nick Burch 2010-08-25 05:09:27 UTC
If you start with an empty file, and add the picture, does that work?

If you have a few paragraphs of text in, and add the picture, does that still work?

If you add the picture, save and re-load, can poi see the picture?

If you create a new file in poi, add a line of text and a picture, then re-create the same file using Word, how do the files differ?
Comment 2 bbarbee 2010-08-25 15:10:51 UTC
I have not fully tested it, but I believe I can answer your questions. 
 1) No
 2) No
 3) Yes
 4) Image is not visible within the POI document.

I have tested with an existing Word document that already has an image in it. I am able to open the document and re-save it, and this actually works! It retains the image in the document! Fortunately, we can use this "template" document to retain our image data for now.
Comment 3 Nick Burch 2010-08-25 17:13:10 UTC
Could you upload three files? Two should have a single paragraph of text, and a small image embeded in them. One generated by word, one by poi. Finally, the third file is the image

That'll let us compare and see what POI does differently. (If you can, also unzip the two .docx files, and use xmlint+diff or similar to spot where the differences lie)
Comment 4 bbarbee 2010-08-25 17:48:23 UTC
Created attachment 25942 [details]
Word Generated
Comment 5 bbarbee 2010-08-25 17:48:42 UTC
Created attachment 25943 [details]
POI Generated
Comment 6 bbarbee 2010-08-25 17:49:04 UTC
Created attachment 25944 [details]
Sample Image
Comment 7 bbarbee 2010-08-25 17:49:42 UTC
I was not able to do a 'diff', but I have attached the 3 files.
Comment 8 TK Gospodinov 2010-09-02 18:10:59 UTC
I did a diff and it looks like the picture is not referenced at all in the document.xml that is generated by POI, but the word version of the file has a reference to sample.jpg. I am trying to add a picture to a Word document with XWPF and I am having the same issue.
Comment 9 TK Gospodinov 2010-09-02 18:13:30 UTC
Created attachment 25974 [details]
document.xml POI version
Comment 10 TK Gospodinov 2010-09-02 18:14:26 UTC
Created attachment 25975 [details]
document.xml Word version
Comment 11 Nick Burch 2010-09-20 11:43:31 UTC
Thanks for investigating this. I believe it's fixed in r998960, as we now correctly setup the relationship. (Unit tests have been added for this)
Comment 12 TK Gospodinov 2010-10-06 16:43:18 UTC
This is still not working in beta3. The image is still added to the package, but does not appear on the resulting document.
Comment 13 Nick Burch 2010-10-06 17:59:46 UTC
Could you please re-do the comparison between Word and POI 3.7 beta 3, to try to spot what we're still missing?

(Everything I think we were missing before should now be there, so it must be something else we've not yet thought of)
Comment 14 Huib 2011-04-04 23:25:07 UTC
From what I can tell, the following is not being generated in the \word\document.xml:

<w:drawing>
	<wp:inline distT="0" distB="0" distL="0" distR="0">
		<wp:extent cx="2466975" cy="552450"/>
		<wp:docPr id="1" name="Picture 0" descr="generated.jpg"/>
		<a:graphic xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
			<a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture">
				<pic:pic xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">
					<pic:nvPicPr>
						<pic:cNvPr id="0" name="generated.jpg"/>
						<pic:cNvPicPr/>
					</pic:nvPicPr>
					<pic:blipFill>
						<a:blip r:embed="rId16"/>
						<a:stretch>
							<a:fillRect/>
						</a:stretch>
					</pic:blipFill>
					<pic:spPr>
						<a:xfrm>
							<a:off x="0" y="0"/>
							<a:ext cx="2466975" cy="552450"/>
						</a:xfrm>
						<a:prstGeom prst="rect">
							<a:avLst/>
						</a:prstGeom>
					</pic:spPr>
				</pic:pic>
			</a:graphicData>
		</a:graphic>
	</wp:inline>
</w:drawing>

In the example above
Width: 2466975
Height: 552450
(with an EMU of 9525 per pixel; example above was 259 x 58 px)

rId16: is defined in \word\_rels\document.xml.rels
  <Relationship Id="rId16" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/image1.jpeg"/>

But at least the image itself is correctly added to \word\media\image1.jpeg
(and also the relationship is correctly added)
Comment 15 Huib 2011-04-05 20:20:49 UTC
My first failed attempt:
CTPicture pict = createParagraph().createRun().getCTR().addNewPict();
        XWPFPicture shape = new XWPFPicture(pict, createParagraph());
        shape.setPictureReference(rel);


My current working workaround:

import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlToken;
import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTInline;

import java.io.IOException;
import java.io.InputStream;

public class CustomXWPFDocument extends XWPFDocument
{
    public CustomXWPFDocument(InputStream in) throws IOException
    {
        super(in);
    }

    public void createPicture(int id, int width, int height)
    {
        final int EMU = 9525;
        width *= EMU;
        height *= EMU;
        String blipId = getAllPictures().get(id).getPackageRelationship().getId();

        CTInline inline = createParagraph().createRun().getCTR().addNewDrawing().addNewInline();

        String picXml = "" +
                "<a:graphic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\">" +
                "   <a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">" +
                "      <pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">" +
                "         <pic:nvPicPr>" +
                "            <pic:cNvPr id=\"" + id + "\" name=\"Generated\"/>" +
                "            <pic:cNvPicPr/>" +
                "         </pic:nvPicPr>" +
                "         <pic:blipFill>" +
                "            <a:blip r:embed=\"" + blipId + "\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"/>" +
                "            <a:stretch>" +
                "               <a:fillRect/>" +
                "            </a:stretch>" +
                "         </pic:blipFill>" +
                "         <pic:spPr>" +
                "            <a:xfrm>" +
                "               <a:off x=\"0\" y=\"0\"/>" +
                "               <a:ext cx=\"" + width + "\" cy=\"" + height + "\"/>" +
                "            </a:xfrm>" +
                "            <a:prstGeom prst=\"rect\">" +
                "               <a:avLst/>" +
                "            </a:prstGeom>" +
                "         </pic:spPr>" +
                "      </pic:pic>" +
                "   </a:graphicData>" +
                "</a:graphic>";

        //CTGraphicalObjectData graphicData = inline.addNewGraphic().addNewGraphicData();
        XmlToken xmlToken = null;
        try
        {
            xmlToken = XmlToken.Factory.parse(picXml);
        }
        catch(XmlException xe)
        {
            xe.printStackTrace();
        }
        inline.set(xmlToken);
        //graphicData.set(xmlToken);

        inline.setDistT(0);
        inline.setDistB(0);
        inline.setDistL(0);
        inline.setDistR(0);

        CTPositiveSize2D extent = inline.addNewExtent();
        extent.setCx(width);
        extent.setCy(height);

        CTNonVisualDrawingProps docPr = inline.addNewDocPr();
        docPr.setId(id);
        docPr.setName("Picture " + id);
        docPr.setDescr("Generated");
    }
}

This is invoked with:
int id = document.addPicture(new FileInputStream(new File("c:\\test.jpg")), Document.PICTURE_TYPE_JPEG);
document.createPicture(id, 259, 58);

id = document.addPicture(new FileInputStream(new File("c:\\test.png")), Document.PICTURE_TYPE_PNG);
document.createPicture(id, 400, 200);


I'm sure there must be a nicer way to do this, but it works for me for now...
Comment 16 Nick Burch 2011-04-08 11:53:57 UTC
On reflection, I don't think that end users should normally be calling the low level addPicture call. Instead, I think we should put some logic onto a XWPFRun and let you add a picture in there, with it handling the CTDrawing stuff for you.

It'll need a bit of work though...
Comment 17 Nick Burch 2011-04-15 12:17:29 UTC
Thanks for the work figuring out the minimum bit to go on the run.

I think I've implemented this in r1092755 with the new method on XSSFRun. It should be like yours, but using a bit more xmlbeans objects for the setup, and less inline xml, so hopefully it'll work better if we need to tweak anything in future.

Any chance you could give it a whirl, and see if it works for your use case?
Comment 18 hacker5257 2011-05-06 03:08:25 UTC
(In reply to comment #14)
The result word can display image added by poi3.7 after using your method.
Thank you very much!
Comment 19 Alexander S. 2011-07-05 13:31:04 UTC
Method addPicture() in  XWPFRun in POI 3.8 beta doesn't work too. I call
    document.createParagraph().createRun().
        addPicture(new FileInputStream(imageFilePath),
                   Document.PICTURE_TYPE_JPEG, imageName, 328, 247);
but it damage *.docx file.

I create Docx file in POI:
XWPFDocument document = new XWPFDocument();
And save after adding image:
document.write(stream);

There is no exceptions or error messages on this operations.
Comment 20 Alexander S. 2011-07-05 13:33:21 UTC
Created attachment 27257 [details]
docx file after addin image
Comment 21 Stefan Stern 2011-07-06 14:54:51 UTC
Created attachment 27264 [details]
The Run created with the POI method

This run was created by POI and extracted from attachment 27257 [details].
Comment 22 Stefan Stern 2011-07-06 14:55:45 UTC
Created attachment 27265 [details]
The Run was created by Word

This Run was created using word. 
1. Create a new document
2. Drop the sample image from attachement 27257 into the docx
3. Save the document.
Comment 23 Stefan Stern 2011-07-06 14:59:13 UTC
Hello

For comparison, I extracted both runs from the corrupted document and the one that Word created. The POI-run misses the blip-fill element, which would explain why the document is evaluated as corrupt. I will setup a UNIT-Test to ensure this methods function and attach a patch until Friday.
Comment 24 Stefan Stern 2011-07-07 13:40:50 UTC
Created attachment 27269 [details]
Fix wrong namespace value

Comparing both original and POI XML, the given namespace for the element nested in the <graphicData> is wrong. The namespace defined there is supposed to specify the contained element.

I was not yet able to write a deliverable UNIT-test for that. I will look into it.
Comment 25 Romesh Soni 2012-05-22 10:13:35 UTC
I know this may be too late, but still the problem persists.
I downloaded latest stable release "poi-3.8", and running the sample code which is found with the source (pls see below). The word file which is created is not opening due to corruption. Anyone please help.:

public class SimpleImages {

    public static void main(String[] args) throws Exception {
        XWPFDocument doc = new XWPFDocument();
        XWPFParagraph p = doc.createParagraph();

        XWPFRun r = p.createRun();

        for(String imgFile : args) {
            int format;

            if(imgFile.endsWith(".emf")) format = XWPFDocument.PICTURE_TYPE_EMF;
            else if(imgFile.endsWith(".wmf")) format = XWPFDocument.PICTURE_TYPE_WMF;
            else if(imgFile.endsWith(".pict")) format = XWPFDocument.PICTURE_TYPE_PICT;
            else if(imgFile.endsWith(".jpeg") || imgFile.endsWith(".jpg")) format = XWPFDocument.PICTURE_TYPE_JPEG;
            else if(imgFile.endsWith(".png")) format = XWPFDocument.PICTURE_TYPE_PNG;
            else if(imgFile.endsWith(".dib")) format = XWPFDocument.PICTURE_TYPE_DIB;
            else if(imgFile.endsWith(".gif")) format = XWPFDocument.PICTURE_TYPE_GIF;
            else if(imgFile.endsWith(".tiff")) format = XWPFDocument.PICTURE_TYPE_TIFF;
            else if(imgFile.endsWith(".eps")) format = XWPFDocument.PICTURE_TYPE_EPS;
            else if(imgFile.endsWith(".bmp")) format = XWPFDocument.PICTURE_TYPE_BMP;
            else if(imgFile.endsWith(".wpg")) format = XWPFDocument.PICTURE_TYPE_WPG;
            else {
                System.err.println("Unsupported picture: " + imgFile +
                        ". Expected emf|wmf|pict|jpeg|png|dib|gif|tiff|eps|bmp|wpg");
                continue;
            }

            r.setText(imgFile);
            r.addBreak();
            r.addPicture(new FileInputStream(imgFile), format, imgFile, Units.toEMU(200), Units.toEMU(200)); // 200x200 pixels
            r.addBreak(BreakType.PAGE);
        }

        FileOutputStream out = new FileOutputStream("images.docx");
        doc.write(out);
        out.close();
    }


}
Comment 26 Romesh Soni 2012-05-23 06:44:25 UTC
Created attachment 28822 [details]
Sample code

Call the CustomXWPFDocument.java like this:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.xwpf.usermodel.Document;
import org.apache.poi.xwpf.usermodel.XWPFDocument;

/*
Romesh Soni
soni.romesh@gmail.com
*/

public class TestCustom {

	public static void main(String []a) throws FileNotFoundException, IOException, InvalidFormatException
	{

		CustomXWPFDocument document = new CustomXWPFDocument(new FileInputStream(new File("c://Economic.docx")));
		FileOutputStream fos = new FileOutputStream(new File("C:\\updatedTemplate.docx"));

		String blipId = document.addPictureData(new FileInputStream(new File("c:\\Most_famous_Caves_of_the_Dordogne_Private_p_4.jpg")), Document.PICTURE_TYPE_JPEG);
		
		System.out.println(document.getNextPicNameNumber(Document.PICTURE_TYPE_JPEG));
		
		//System.out.println(document.getNextPicNameNumber(Document.PICTURE_TYPE_JPEG));
		document.createPicture(blipId,document.getNextPicNameNumber(Document.PICTURE_TYPE_JPEG), 500, 500);

		
        document.write(fos);
        fos.flush();
        fos.close();
        
	}

}
Comment 27 Matti Bickel 2013-02-13 19:13:06 UTC
Can't see why this issue was closed NEEDINFO?

I tested with the last 3.9 release and the issue persists using XWPFRun.addPicture()

The image data is written quite fine, BUT then the <pic:pic /> element is not actually filled with content, corrupting the written file.

Using the code from comment 26 I was able to insert the picture just fine. AFAIK all that's different is that the whole block is passed to XmlFactory.parse instead of filling it programmatically? If that helps, the CTPicture returned from getCTPictures().get(0) (XWPFRun.java, line 706) lacks a non-null parent field (shouldn't it point to the <a:graphicData>?).
Comment 28 Amitabh Ranjan 2013-07-25 04:38:28 UTC
I am trying to work on Apache POI in order to insert a picture into a word document. I went through many posts and forums for this and finally I found in this forum (comment #26 and #27) that there is a way to do this. It can be done by using "CustomXWPFDocument" class. After reading about it I came to know that this class extends "XWPFDocument. But When I am trying to use the code written in comment #26 then its giving me the error as"CustomXWPFDocument cannot be resolved to a type". I am not even getting the imports for this class. 

Here I will also write the jars I am using(basically I have used every JAR related to POI to make this program work but till now no luck):- (1) poi-3.9-20121203 (2) poi-examples-3.9-20121203 (3) poi-excelant-3.9-20121203 (4) poi-ooxml-3.9-20121203 (5) poi-ooxml-schemas-3.9-20121203 (6) poi-scratchpad-3.9-20121203 (7) xmlbeans-2.3.0 (8) stax-api-1.0.1 (9) dom4j-1.6.1 (10) commons-codec-1.5 (11) commons-logging-1.1 (12) junit-3.8.1 (13) log4j-1.2.13

Please tell me if something is wrong.
Comment 29 Nick Burch 2013-07-25 09:38:47 UTC
(In reply to Amitabh Ranjan from comment #28)
> I went through many posts and forums 

This is not a forum, this is a bug tracker. For help with using Apache POI, please use the mailing lists: http://poi.apache.org/mailinglists.html
Comment 30 km.ashwini92 2014-01-21 05:26:59 UTC
I tried to add an image with the help of provided here, its working fine.

But next i tried to add this image into header but its not working,

How to add an image into header?
Comment 31 paniraju 2014-03-12 11:32:35 UTC
Im trying to add picture using poi 3.10 final 

FileInputStream pic = new FileInputStream("C:\\Happybirthday.JPG");
byte [] picbytes = IOUtils.toByteArray(pic);
doc.createParagraph().createRun().addPicture(pic, Document.PICTURE_TYPE_JPEG, "C:\\Happybirthday.JPG", 200, 200);

still im not able to add picture , size of docx file has increased when i open docx file and can see the image file loaded inside. But im unable to open the docx file. 
Please help to solve my problem.
Comment 32 Nick Burch 2014-03-12 11:36:30 UTC
(In reply to paniraju from comment #31)
> Im trying to add picture using poi 3.10 final 
> 
> FileInputStream pic = new FileInputStream("C:\\Happybirthday.JPG");
> byte [] picbytes = IOUtils.toByteArray(pic);
> doc.createParagraph().createRun().addPicture(pic,
> Document.PICTURE_TYPE_JPEG, "C:\\Happybirthday.JPG", 200, 200);

If you save this file, close, re-open with XWPFDocument, and read, is POI able to see and read the image correctly? i.e. is the problem that POI is writing the image completely wrong, or is it writing in a way that POI copes with but that's wrong for Word?
Comment 33 paniraju 2014-03-12 13:32:50 UTC
Thanks for prompt reply 

XWPFDocument docx = new XWPFDocument(OPCPackage.openOrCreate(new File("c:\\simple.docx")));  
XWPFWordExtractor wx = new XWPFWordExtractor(docx);  
String text = wx.getText();  
System.out.println("text = "+text);  

Im using above code to open existing doc and trying to print , when i do that my complete applications itself getting crashed, i think this happening because after adding image to docx file, docx file got corrupted and now XWPFDocument unable to parse the file and getting. My concern is org.apache.poi of version 3.10 is able add images to word file or not, i have seen lot of bug pages saying lot of issues in adding the image. Does adding image to docx file happens in version 3.10 or still a bug in it
Comment 34 Nick Burch 2014-03-12 18:40:31 UTC
At this point, we need for POI 3.10, a unit test that:
 * Creates a simple word file from scratch
 * Adds a single picture to it
 * Adds a bit of test text to it (maybe 4 paragraphs, 2-3 runs per paragraph)
 * Saves that to a temp file, which you try to load from Word
 * Check if Word loads it and displays it? (I gather no? But confirm)
 * Trys to re-open the file in POI
 * Checks we can correctly read the text from it?
 * Checks if the picture is found in the picture list?
 * Loads the paragraph with the picture in, and sees if POI can correctly find + read the picture from there?
Comment 35 paniraju 2014-03-14 09:59:45 UTC
(In reply to Nick Burch from comment #34)
> At this point, we need for POI 3.10, a unit test that:
>  * Creates a simple word file from scratch
                    --Yes did
>  * Adds a single picture to it
                    --did
>  * Adds a bit of test text to it (maybe 4 paragraphs, 2-3 runs per paragraph)
                    --did
>  * Saves that to a temp file, which you try to load from Word
                    -- did
>  * Check if Word loads it and displays it? (I gather no? But confirm)
                    -- it doen't load the image
>  * Trys to re-open the file in POI
                     -- yes i did
>  * Checks we can correctly read the text from it?
                     --- able to read text and print on console 
>  * Checks if the picture is found in the picture list?
                     -- when i use document.getallPicture() function, i am able to get the picture which i have added earlier
>  * Loads the paragraph with the picture in, and sees if POI can correctly
                     -- did same still im not able to get image , bthis time not able to open the word file.
> find + read the picture from there?

Thanks for reply,

I have done all points which you have mentioned in your post still im not able to see image in msword docx file. Please try to give me a way where i can able to add images to msword file.
Comment 36 paniraju 2014-03-14 12:33:39 UTC
> At this point, we need for POI 3.10, a unit test that:
>  * Creates a simple word file from scratch
                    --Yes did
>  * Adds a single picture to it
                    --did
>  * Adds a bit of test text to it (maybe 4 paragraphs, 2-3 runs per paragraph)
                    --did
>  * Saves that to a temp file, which you try to load from Word
                    -- did
>  * Check if Word loads it and displays it? (I gather no? But confirm)
                    -- it doen't load the image
>  * Trys to re-open the file in POI
                     -- yes i did
>  * Checks we can correctly read the text from it?
                     --- able to read text and print on console 
>  * Checks if the picture is found in the picture list?
                     -- when i use document.getallPicture() function, i am able to get the picture which i have added earlier
>  * Loads the paragraph with the picture in, and sees if POI can correctly
                     -- did same still im not able to get image , bthis time not able to open the word file.
> find + read the picture from there?

Thanks for reply,

I have done all points which you have mentioned in your post still im not able to see image in msword docx file. Please try to give me a way where i can able to add images to msword file.
Comment 37 Luka Kosenina 2014-06-20 09:10:57 UTC
Hello, 
I found a working example of inserting images into discs document. This example consists of two programs, first one is CustomXWPFDocument (link: http://pastebin.com/CbQ3iw8t) and the second one is a simple example class (link: http://pastebin.com/2YAneYgt).
In this example I used the latest jar binaries of Apache poi (version 3.10). 
I hope you find this example helpful.
Comment 38 Pablo 2015-06-14 20:52:35 UTC
buscando a una persona
Comment 39 Dominik Stadler 2017-07-22 08:07:50 UTC
There was no discussion on this issue since some time and we did not manage to get a unit test which allows us to reproduce the problem. 

Therefore I am setting this to WONTFIX for now unless someone comes up with a better description of how this can be reproduced/analyzed. If you still have this problem and have some standalone reproducing piece of code then please reopen this issue.
Comment 40 radu.c.stefanescu@gmail.com 2018-04-13 13:06:34 UTC
Seems this issue reported 8 years ago is still reproducing.
The only viable fix seems to be the one reported in 2011 in Comment 15.
Please have a look at this repo where the issue can be replicated:

https://github.com/RaduCStefanescu/apache_poi_49765

Will also add an attachment containing the output document after running the code. The document seems to contain the XML structure with the image reference in the paragraph, but the image is not displayed in the docx document.

I believe this bug should be reopened.
Comment 41 radu.c.stefanescu@gmail.com 2018-04-13 13:41:18 UTC
Update on my above comment: using Apache POI version 3.17
Comment 42 radu.c.stefanescu@gmail.com 2018-04-13 14:52:47 UTC
Moving back to the initial state, the issue was on my side. 

The XWPFRun addPicture method requires the width and height of the image to be set using EMU measuring units, the conversion can be done using Units.EMU_PER_PIXEL in package org.apache.poi.util.
Comment 43 Stefan Edelbusch 2022-03-15 15:29:09 UTC
When I use the method XWPFRun.addPicture to add images to an word document I got an error message when opening the new document which says that there is some not readable content in the document.
Problem is, that it comes to a conflict between drawings (w:drawing) that were already in the word template with the new inserted images. In the XML there are subnodes of drawing of type "wp:docPr" which have identical ID's.

I managed to workaround this conflict by testing if the id for the next drawing to insert is already used in the list of known drawings. If so, I increment this next id as long as it is unique so it will not be used twice in the document.

For that I expanded the XWPFDocument class as follows.

public class ExtendedXWPFDocument extends XWPFDocument {

    public void makeUniqueNextDrawingId(List<CTDrawing> drawingsAll)
    {
        try {
            Method getDrawingIdManager = getClass().getSuperclass().getDeclaredMethod("getDrawingIdManager", new Class<?>[]{});
            getDrawingIdManager.setAccessible(true);
            IdentifierManager idManager = (IdentifierManager) getDrawingIdManager.invoke(this, (Object[])null);
            if(idManager != null) {
                Field field = idManager.getClass().getDeclaredField("segments");
                if(field != null){

                    // make private field accessible
                    field.setAccessible(true);
                    List<?> segmentsList = (List<?>)field.get(idManager);

                    Object segment =  segmentsList.get(0);
                    Field fieldStart = segment.getClass().getDeclaredField("start");
                    fieldStart.setAccessible(true);
                    long nextID = fieldStart.getLong(segment);

                    HashMap<Long, Object> drawingsInUseMap = new HashMap<Long, Object>();

                    for (CTDrawing drawing : drawingsAll) {

                        List<CTInline> inlineList = drawing.getInlineList();
                        for (CTInline inline : inlineList) {
                            Long inlineId = inline.getDocPr().getId();
                            drawingsInUseMap.put(inlineId, inline);
                        }
                        List<CTAnchor> anchorList = drawing.getAnchorList();
                        for (CTAnchor anchor : anchorList) {
                            Long inlineId = anchor.getDocPr().getId();
                            drawingsInUseMap.put(inlineId, anchor);
                        }
                    }

                    while (drawingsInUseMap.containsKey(nextID)) {

                        nextID = idManager.reserveNew();
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

}


When I insert an image I first test, if next id is unique.

List<CTDrawing> drawingsAll = getAllDrawings();
document.makeUniqueNextDrawingId(drawingsAll);

run.addPicture(inputStream, format, image.getName(), width, height);
Comment 44 PJ Fanning 2022-03-15 16:21:05 UTC
Stefan - could you provide some guidance on how to reproduce your issue? Are you modifying an existing file or creating a new one? Do you have any idea why the existing code is adding a duplicate id? What version of POI are you using?

Your solution may help users who stumble across your comment but it would be better to fix the underlying problem in POI.
Comment 45 Stefan Edelbusch 2022-03-16 13:50:44 UTC
Created attachment 38227 [details]
document template for the addPicture test

document template for XWPFRun.addPicture test
Comment 46 Stefan Edelbusch 2022-03-16 13:52:24 UTC
Created attachment 38228 [details]
picture to insert in document by addPicture

picture to insert in document by XWPFRun.addPicture
Comment 47 Stefan Edelbusch 2022-03-16 14:02:17 UTC
I am using POI-4.1.2 for my tests.

I now created a small test, that inserts in a docx-template an image file.
When the resulting document is opende it results an error message that says that ther is content in the file, that can not be read.  

To execute this test please insert the two attachements that I just uploaded to folder "C:\TEMP\xwpfrun_addpicture_testfiles" and than run the following Unit-Test:




public class Ticket_xwpfrun_addpicture extends BaseTest {
    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
    }

    @AfterClass
    public static void tearDownAfterClass() throws Exception {
    }

  
    @Before
    public void setUp() throws Exception {
    }

    @After
    public void tearDown() throws Exception {
    }

  
    private List<XWPFParagraph> getParagraphsOfTablesRecursive(List<XWPFTable> tables) {

        List<XWPFParagraph> paraList = new ArrayList<XWPFParagraph>();
        for (XWPFTable table : tables)
        {
            for (XWPFTableRow row : table.getRows())
            {
                for (XWPFTableCell cell : row.getTableCells())
                {
                    List<XWPFParagraph> cellParaList = cell.getParagraphs();
                    paraList.addAll(cellParaList);

                    List<XWPFTable> cellTables = cell.getTables();
                    List<XWPFParagraph> tablesParaList = getParagraphsOfTablesRecursive(cellTables);
                    paraList.addAll(tablesParaList);
                }
            }
        }
        return(paraList);
    }

    public void insertImageAtBookmark(List<XWPFParagraph> paraList,String bookmarkName,String fileName, int pictureType) {
        Iterator<XWPFParagraph> paraIter = paraList.iterator();

        while(paraIter.hasNext()) {
            XWPFParagraph para = paraIter.next();

            List<CTBookmark> bookmarkList = para.getCTP().getBookmarkStartList();
            Iterator<CTBookmark> bookmarkIter = bookmarkList.iterator();

            while (bookmarkIter.hasNext()) {
                CTBookmark bookmark = bookmarkIter.next();
                String nameActual = bookmark.getName();
                if (nameActual.equalsIgnoreCase(bookmarkName)) {

                    final XWPFRun run = para.createRun();
                    InputStream pic1 = null;
                    try {
                        pic1 = new FileInputStream(fileName);
                        run.addPicture(pic1, pictureType, "my pic 1", Units.toEMU(200), Units.toEMU(200));
                        pic1.close();
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    } catch (InvalidFormatException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    
	@Test
    public void testFromScratch() throws Exception {
        InputStream docTemplate = new FileInputStream("C:/TEMP/xwpfrun_addpicture_testfiles/xwpfrun_addpicture_template.docx");
        XWPFDocument docx = new XWPFDocument(docTemplate);

        List<XWPFParagraph> paraList = new ArrayList<XWPFParagraph>();
        List<XWPFParagraph> docxParaList = docx.getParagraphs();
        paraList.addAll(docxParaList);
        List<XWPFTable> tables = docx.getTables();
        List<XWPFParagraph> tablesParaList = getParagraphsOfTablesRecursive(tables);
        paraList.addAll(tablesParaList);

        String bookmarkName = "REKKUND_DOCS_PATH";
        String fileName = "C:/TEMP/xwpfrun_addpicture_testfiles/xwpfrun_addpicture_testimage.jpg";
        insertImageAtBookmark(paraList, bookmarkName, fileName,Document.PICTURE_TYPE_JPEG);

        FileOutputStream fos = new FileOutputStream("C:/TEMP/xwpfrun_addpicture_testfiles/xwpfrun_addpicture_with_image.docx");
        docx.write(fos);
    }
}
Comment 48 PJ Fanning 2022-03-16 15:10:35 UTC
Thanks - it might take me until next week to have a look but much appreciated - there is already a new release in progress and I want to concentrate on that
Comment 49 PJ Fanning 2022-03-20 17:54:49 UTC
The provided code is working at the generated class level. That is the wild west. When we provide XWPF APIs, we try to look after all the low level XML as part of that. If you switch from XWPF classes and start using CTBookmark and equivalent classes, looking after all the XML internals is up to you.
Comment 50 PJ Fanning 2022-03-20 18:00:56 UTC
I raised https://bz.apache.org/bugzilla/show_bug.cgi?id=65969