Hi Aspose support,
I have a question about positioning shapes inside GroupShape.
We have functionality that replaces Charts and SmartArts with images. For regular cases all works as expected in terms of replacing and image shape positioning in document.
But we have a problem with positioning image shape inside GroupShape - it always positions at the top left corner of a GroupShape, no matter whether Top and Left coordinates are set,
or copied from original object, on top of that I cannot even position original Chart/SmartArt (tried for testing purposes).
Here is the example of the document:
Group1.zip (59.7 KB)
It has a Chart which is placed little bit lower from top of GroupShape. When it’s replaced with image, image shows at the top left corner of a GroupShape. Imagine, if there’s more than one Chart,
they will be overlapped by each other at the same position.
BTW, within Word it is possible to set exact position for the shape inside the group.
Shapelayout.png (22.9 KB)
Code sample:
private void ReplaceShapes(Document doc, ImageSaveOptions options, DocumentBuilder builder)
{
NodeCollection shapes = doc.GetChildNodes(NodeType.Shape, true);
// Loop from last one to first one
for (int i = shapes.Count - 1; i >= 0; i--)
{
try
{
Shape shape = (Shape)shapes[i];
if (!(shape.HasChart || shape.HasSmartArt)) continue;
using (MemoryStream stream = new MemoryStream())
{
shape.GetShapeRenderer().Save(stream, options);
// Shape in group case
if (shape.ParentNode.NodeType == NodeType.GroupShape)
{
// Word creates fake group for Chart/SmartArt to group it with other objects
// and Word/Aspose does not allow insert objects into such fake group.
// So, to insert/append an object need to use the group on one level up.
var fakeGroup = (GroupShape)shape.ParentNode;
// get real parent group
var parentGroup = (fakeGroup.ParentNode.NodeType == NodeType.GroupShape) ? (GroupShape)fakeGroup.ParentNode : null;
if (parentGroup != null)
{
// original shape has 0 size, so need to get size of parent ShapeGroup as it has valid size
Shape image = builder.InsertImage(stream, fakeGroup.SizeInPoints.Width, fakeGroup.SizeInPoints.Height);
if (image != null)
{
parentGroup.AppendChild(image);
image.RelativeHorizontalPosition = fakeGroup.RelativeHorizontalPosition;
image.RelativeVerticalPosition = fakeGroup.RelativeVerticalPosition;
image.Top = fakeGroup.Top;
image.Left = fakeGroup.Bottom;
fakeGroup.Remove();
}
}
}
}
}
catch (Exception e)
{
// Ignore exception and continue process shapes collection
}
}
}
public void Replace(Document doc)
{
try
{
// Save Charts and SmartArts into PNG format as optimal format for them
ImageSaveOptions optionsPng = new ImageSaveOptions(SaveFormat.Png);
optionsPng.Scale = 2;
DocumentBuilder builder = new DocumentBuilder(_doc);
ReplaceShapes(doc, optionsPng, builder);
}
catch (Exception e)
{
//
}
}
Unfortunately I wasn’t able to find answer on my problem on the forum.
Please advise, what can be wrong with this approach? What we’ve missed?