Search code examples
pythonmultidimensional-arraycoordinateswin32com

Python win32com and 2-dimensional arrays


When using python and win32com to automate the software form Adobe one encounters problem with passing arrays of 2d coordinates. If one looks at code that Adobe ships for visual basic (VB) its simple. A simplified example for drawing a line in Illustrator would look as follows:

Set appObj = CreateObject("Illustrator.Application")
Set docObj = appObj.Documents.Add

Set pathItem = docObj.PathItems.Add
    pathItem.SetEntirePath Array(Array(0.0, 0.0), Array(20.0, 20.0))

Now the naive assumption is that VB code could just just be turned into python by converting it as follows:

from win32com.client import Dispatch

appObj = Dispatch("Illustrator.Application")  
docObj = appObj.Documents.Add()

pathItem = docObj.PathItems.Add()
pathItem.SetEntirePath( [ [0.0,0.0], [20.0,20.0] ] )

Obviously, it's not that easy, python issues a error saying "Only arrays with dimension 1 are supported". Now i know that there's a difference between arrays of arrays and 2 dimensional arrays. So the question is how do i force python to make a array of the right kind?

I tried making my own VARIANT type but failed miserably. Ive also looked at ctypes for this. Anybody have had the same problem and could shed some light?

PS:

I am aware that the problem can be circumvented by using:

pathItem = docObj.PathItems.Add()
for point in (  [0.0,0.0], [20.0,20.0] ):
    pp = pathItem.PathPoints.Add() 
    pp.Anchor = point

But there are similar cases where this does not in fact work. Anyway the point is to write guidelines on porting to students so being as close to the original intent would be better.


Solution

  • I encountered this same issue when trying to determine selection areas using win32com. I found that using comtypes rather than win32com to access photoshop solved the multidimensional array problem outright.

    I believe that the one dimensional array problem is a limitation of win32com, but I may be wrong.

    You can get comtypes here: http://sourceforge.net/projects/comtypes/

    There is a post about this issue on Tech Artists Org which is worth a look through.

    Here is an example of passing through an array using comtypes from the tech artist's forum post linked above. The implementation for path points should be similar.

    import comtypes.client
    ps_app = comtypes.client.CreateObject('Photoshop.Application') 
    # makes a new 128x128 image
    ps_app.Documents.Add(128, 128, 72)
    
    # select 10x10 pixels in the upper left corner
    sel_area = ((0, 0), (10, 0), (10, 10), (0, 10), (0, 0))
    ps_app.ActiveDocument.Selection.Select(sel_area)