Identify coordinates for a visual element in idml

放肆的年华 提交于 2019-12-05 10:39:29
Jude Fisher

The heirarchy of containers for an image in an IDML document is as follows:

Document [Contains] > Spread > PageItem > PlacedImage. Pages aren't used as containers, and PageItems are stored in spread coordinates, so we can forget about the Document and Page elements. if you can find a Placed Image in Spread coordinates, and rebase those coords so 0,0 is at the top left of your screen, you can position an image as it was in the InDesign document.

A page item (which contains an image) doesn't have geometric bounds in IDML. Its bounds are stored as an array of PathPointType objects within the PathGeometry tag, like this:

<Properties>
            <PathGeometry>
                <GeometryPathType PathOpen="false">
                    <PathPointArray>
                        <PathPointType Anchor="-32.04 -35.04" LeftDirection="-32.04 -35.04" RightDirection="-32.04 -35.04" />
                        <PathPointType Anchor="-32.04 35.04" LeftDirection="-32.04 35.04" RightDirection="-32.04 35.04" />
                        <PathPointType Anchor="32.04 35.04" LeftDirection="32.04 35.04" RightDirection="32.04 35.04" />
                        <PathPointType Anchor="32.04 -35.04" LeftDirection="32.04 -35.04" RightDirection="32.04 -35.04" />
                    </PathPointArray>
                </GeometryPathType>
            </PathGeometry>
        </Properties>

You can calculate the bounds yourself simply enough by getting the lowest/greatest point values, assuming the border around your page item is a rectangle. Then you need the item transform,

ItemTransform="1 0 0 1 509.27559055100005 -123.76377952749999"

...and you need to allow for where IDML thinks 0,0 is (which is the origin of the transform).

In the X axis, 0 will be the binding location (which is variable - in a single page document it's usually the left hand edge of the spread, but in a two page document it may be the center of the spread). This is where you will need pages. BindingLocation is expressed as an integer (0 for before the first page, 1 for between first and second, etc). You find the coords of this by adding up the ItemTransforms of the preceding pages.

In the Y axis, for reasons best known to Adobe, 0 is the vertical center of the spread (not either the top or bottom, as you might expect).

The IDML docs have coord examples: http://www.photoshopelementsmac.com/devnet/indesign/documentation.html including translating from one coord space to another.

Also, within a page item (which gives the geometric bounds), a placed image has its own set of graphic bounds, which can offset it further, as well as its own ItemTransform

So, to answer your question, you would need to unpack the IDML zip file, find the image in the XML, then do a sum something like:

// Pseudo-code:
// Calculate PageItem GeometricBounds First as noted above
X: (Spread.BindingLocation) + Spread.ItemTransform.tx + PageItem.itemTransform.tx + PageItem.GeometricBounds.Left + PlacedImage.ItemTransform.tx + PlacedImage.GraphicBounds.Left

Y: (Half Spread Height) + Spread.ItemTransform.ty + PageItem.itemTransform.ty + PageItem.GeometricBounds.Top+ PlacedImage.ItemTransform.ty + PlacedImage.GraphicBounds.Top

Oh, one more thing: all IDML coords are in points. You'll need to divide all values by 72 divided by the PPI of your screen if you want to get results in pixels.

Each <PageItem> on a page uses the ItemTransform attribute to scale, rotate, shear, and transform itself relative to its containing element (technically the PageItem XML element doesn't exist but can be a Rectangle, Oval, etc. element).

Within the <PageItem>, its shape is determined by the <PathGeometry> element and its containing elements (the IDML reference describes this in detail with examples), also refer to JcFx's answer.

Heavily corrected answer based on IDML specification: Thanks to JcFx

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!