Forum


Replies: 6   Views: 2089
Get the image size of an image placeholder when using createdocxfromtemplate
Topic closed:
Please note this is an old forum thread. Information in this post may be out-to-date and/or erroneous.
Every phpdocx version includes new features and improvements. Previously unsupported features may have been added to newer releases, or past issues may have been corrected.
We encourage you to download the current phpdocx version and check the Documentation available.

Posted by blocked-ISSL  · 19-06-2019 - 13:30

The only topic I can find related to this is https://www.phpdocx.com/en/forum/default/topic/1633 but the information there doesn't work.

I am loading a document using CreateDocxFromTemplate, and there is a placeholder image in there with a placeholder of $FLOORPLAN$. I need to do is get its width, because I can't just use replacePlaceholderImage as it will squash the image (the floor plans are different sizes), and I can't set the width as I don't know the width of the placeholder image (it changes between templates).

I thought this would work looking at Indexer.php, but it requires DOMDocument and I can't see a way to create that from CreateDocxFromTemplate.

// load XML content
$contentDOM = new DOMDocument();
$contentDOM->loadXML($xml); # How do I do this with CreateDocxFromTemplate??

// do a xpath query getting only image tags
$contentXpath = new DOMXPath($contentDOM);
$contentXpath->registerNamespace('rel', 'http://schemas.openxmlformats.org/package/2006/relationships');
$imageEntries = $contentXpath->query('//rel:Relationship[@Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"]');

How do I simply get the width of a placeholder image?

Posted by admin  · 19-06-2019 - 14:16

Hello,

Indexer uses a DOCX as source, not a DOMDocument (https://www.phpdocx.com/api-documentation/docxutilities/indexer-parse-word-documents-with-PHP):

$indexer = new Indexer('document.docx');
$output = $indexer->getOutput();

This class returns a lot of information about images, including sizes.

Also please note that replacePlacehoderImage allows keeping the size of the previous image or use the sizes from the new image with the following options:

width     mixed   The value in cm (float) or 'auto' (use image size).
height  mixed   The value in cm (float) or 'auto' (use image size).
dpi     int     Dots per inch. This parameter is only taken into account if width or height are set to auto.

If you want to get all the information about a single image with a placeholder you can use DOCXPath:

$referenceNode = array(
    'customQuery' => '//w:drawing[descendant::wp:docPr[contains(@descr, "$VAR$")]]',
);
$queryInfo = $docx->getDocxPathQueryInfo($referenceNode);

This code returns the elements of an XPath query (the image that includes $VAR$ as placeholder). So you can read it to get the size; although you can get it from the Indexer class, this the code used to get image sizes:

foreach ($drawingChildNodes as $drawingChildNode) {
    if ($drawingChildNode->tagName == 'wp:extent') {
        if ($drawingChildNode->hasAttribute('cx')) {
            $widthImage = $drawingChildNode->getAttribute('cx');
        }
        if ($drawingChildNode->hasAttribute('cy')) {
            $heightImage = $drawingChildNode->getAttribute('cy');
        }
    }
}

$this->documentStructure[$target]['images'][] = array(
    'content' => $imageString,
    'path' => $imageEntry->getAttribute('Target'),
    'height_word_emus' => $heightImage,
    'width_word_emus' => $widthImage,
    'height_word_inches' => $heightImage/914400,
    'width_word_inches' => $widthImage/914400,
    'height_word_cms' => $heightImage/360000,
    'width_word_cms' => $widthImage/360000,
);

Regards.

Posted by blocked-ISSL  · 19-06-2019 - 15:53

Thanks for the reply. Indexer doesn't return any information about placeholders - just their raw data and fake file names, no sizes are included unfortunately. This is all that's returned when using Indexer:

array:2 [
        0 => array:2 [
                "content" => b"""
                        ëPNG\r\n
                        image code here
                        """
                "path" => "media/image1.png"
        ]
        1 => array:2 [
                "content" => b"""
                        ëPNG\r\n
                        image code here
                        """
                "path" => "media/image2.png"
        ]
]

I can't use the options of replacePlaceholderImage because I don't know the width or height of the placeholder as the templates are user-editable, and 'auto' uses the replacement size (which might be many times larger than the placeholder).

Using getDocxPathQueryInfo only returns the following:

array:2 [
  "length" => 1
  "query" => "//w:drawing[descendant::wp:docPr[contains(@descr, "$FLOORPLAN$")]]"
]

which I can't use

The drawingChildNodes comes from DOMXPath right? But the code requires a DOMDocument which I don't know how to create from a template.

Posted by admin  · 19-06-2019 - 16:33

Hello,

What version of phpdocx are you using? Indexer includes image sizes information since phpdocx 7.0, and the getDocxPathQueryInfo method returns the elements of the query since phpdocx 7.5.

It seems you are using phpdocx 6.5. Your license has an active LUS, please download and use the latest release available on MY PHPDOCX page to be able to use both features with the new features.

Regards.

Posted by blocked-ISSL  · 20-06-2019 - 08:02

Hi there,

We're using 8.2 according to the readme.

It seems like it isn't working correctly, so we'll look to upgrade to 9 soon and hope that works.

Posted by admin  · 20-06-2019 - 08:09

Hello,

We have tested the following samples available in phpdocx 8.2:

· examples/indexer/sample_1.php

· examples/DocxPath/getDocxPathQueryInfo/sample_1.php

And both are working perfectly. The first one return images with their sizes, and the second one returns this output:

array(3) {
  ["elements"]=>
  object(DOMNodeList)#22 (1) {
    ["length"]=>
    int(2)
  }
  ["length"]=>
  int(2)
  ["query"]=>
  string(17) "//w:body/w:p[1=1]"
}

The elements key returns a DOMNodeList with the information of the elements.

Please test both included examples.

Regards.

Posted by blocked-ISSL  · 20-06-2019 - 08:19

I've just updated our test environment to use the latest version and I now get the required information from the Indexer:

[
        "height_word_emus" => "526636",
        "width_word_emus" => "1511085",
        "height_word_inches" => 0.57593613298338,
        "width_word_inches" => 1.6525426509186,
        "height_word_cms" => 1.4628777777778,
        "width_word_cms" => 4.1974583333333,
]

I'm not sure why the previous version wasn't doing the same but I'm glad it is now!