Form coordinates in PowerPoint (C #)

I want to get the coordinates of a PowerPoint form.

here is my c # implementation

Microsoft.Office.Interop.PowerPoint._Application myPPT = Globals.ThisAddIn.Application;
Microsoft.Office.Interop.PowerPoint.Slide curSlide = myPPT.ActiveWindow.View.Slide;

foreach (Shape current in curSlide.Shapes)
{
   Debug.Print(current.Type.ToString());              

   foreach (ShapeNode n in current.Nodes)
   {
      double x = n.Points[1, 1];
      double y = n.Points[1, 2];

      Debug.Print("X: " + x);
      Debug.Print("Y: " + y);
    }
}

      

This works fine for the "free hand", but not for the preset ones (eg rectangle, big arrow, stars, ...) there is a COMException error.

Does anyone know how to implement this and access the points of the shape?

+3


source to share


1 answer


I tried many times and always got HRESULT: 0x800A01A8 error.

The workaround was to export the shape as an image and use AForge to define the boundaries of that image. Not really, but did the job. I have not found any customized code below to handle diffs in transforms and offsets.



    static List<Tuple<float,float>> ShapeToPoints(Microsoft.Office.Interop.PowerPoint.Shape shape)
    {
        string path = @"C:\Temp\bpmimg\Test1.png";
        if (File.Exists(path))
            File.Delete(path);
        List<Tuple<float, float>> points = new List<Tuple<float, float>>();

        try
        {
            //Shape.Export is an internal method, but we access it via reflection this way
            var args = new object[] { path, Microsoft.Office.Interop.PowerPoint.PpShapeFormat.ppShapeFormatPNG, 0, 0, Microsoft.Office.Interop.PowerPoint.PpExportMode.ppRelativeToSlide };
            shape.GetType().InvokeMember("Export", System.Reflection.BindingFlags.InvokeMethod, null, shape, args); // Export to file on disk
            // locating objects
            BlobCounter blobCounter = new BlobCounter();
            blobCounter.FilterBlobs = true;
            blobCounter.MinHeight = 5;
            blobCounter.MinWidth = 5;

            //Important that the dispose is called so that the temp-file cleanup File.Delete doesn't crash due to locked file
            using (System.Drawing.Bitmap image = (System.Drawing.Bitmap)System.Drawing.Bitmap.FromFile(path))
            {
                blobCounter.ProcessImage(image);
            }
            Blob[] blobs = blobCounter.GetObjectsInformation();

            SimpleShapeChecker shapeChecker = new SimpleShapeChecker();
            if (blobs.Length != 1)
            {
                //Unexpected number of blobs
                return null;
            }
            var blob = blobs[0];

            List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blob);

            List<IntPoint> untransformedPoints;
            // use the shape checker to extract the corner points
            if (!shapeChecker.IsConvexPolygon(edgePoints, out untransformedPoints))
            {
                IConvexHullAlgorithm hullFinder = new GrahamConvexHull();
                untransformedPoints = hullFinder.FindHull(edgePoints);
            }
            var untransformedWidth = untransformedPoints.Max(p => p.X);
            var untransformedHeight = untransformedPoints.Max(p => p.Y);
            var widthRatio = untransformedWidth / shape.Width;//How many time bigger is the image-based figure than the shape figure
            var heightRatio = untransformedHeight / shape.Height;//How many time bigger is the image-based figure than the shape figure

            points = untransformedPoints.Select(p => new Tuple<float, float>(shape.Left + p.X / widthRatio, shape.Top + p.Y / heightRatio)).ToList();//Transform
        }
        finally
        {
            if (File.Exists(path))
                File.Delete(path);
        }
        return points;
    }

      

0


source







All Articles