发生异常:非法参数2,应为对象(使用Win32 COM制作Photoshop联系人表)

2024-09-29 17:12:27 发布

您现在位置:Python中文网/ 问答频道 /正文

我正试图用Photoshop API中包含的MakeContactSheet函数制作一个Photoshop联系人表。可以使用“win32com.client”访问它

我的第一行: psApp = Dispatch("Photoshop.Application")

创建一个win32com.gen_py.E891EE9A-D0AE-4CB4-8871-F92C0109F18Ex0x1x0._Application._Application对象

该对象的类似乎具有documentation中列出的所有可用函数

然后,我继续使用os.walk创建字符串列表

CSInputFiles = [path.join(r, f) for r, sd, fs in walk('C:\\Users\\chris\\Desktop\\1A') for f in fs]

然后是一组混合选项:

CSoptions = [True, psApp, False, False, 6, True, None, 0, 7, 4, 3, 300, 3, None, True]

最后,我传递这些论点: psApp.MakeContactSheet(CSInpuFiles, CSoptions)

考虑到_Application中的函数定义,这似乎是正确的:

def MakeContactSheet(self, InputFiles=defaultNamedNotOptArg, Options=defaultNamedOptArg):
    'create a contact sheet from multiple files'
    # Result is a Unicode object
    return self._oleobj_.InvokeTypes(1129599816, LCID, 1, (8, 0), ((12, 1), (12, 17)),InputFiles
        , Options)

唉,我得到了以下错误:

Traceback (most recent call last):
  File "C:\Users\chris\Desktop\test.py", line 17, in <module>
    psApp.MakeContactSheet(CSInputFiles, CSoptions)
  File "C:\Users\chris\AppData\Local\Temp\gen_py\3.9\E891EE9A-D0AE-4CB4-8871-F92C0109F18Ex0x1x0\_Application.py", line 97, in MakeContactSheet
    return self._oleobj_.InvokeTypes(1129599816, LCID, 1, (8, 0), ((12, 1), (12, 17)),InputFiles
pywintypes.com_error: (-2147352567, 'Exception occurred.', (0, 'Adobe Photoshop', 'Illegal argument - argument 2\n- Object expected', None, 0, -2147220261), None)

我最初的直觉是使用pathlib将csInputFiles数组中的所有字符串转换为path对象

from pathlib import Path

CSInputFiles = [Path(path.join(r, f)) for r, sd, fs in walk('C:\\Users\\chris\\Desktop\\1A') for f in fs]

当我将数组传递给函数时,产生了这段模糊的垃圾:

psApp.MakeContactSheet(CSInputFiles, CSoptions)

#RUN!

File "C:\Users\chris\Desktop\test.py", line 17, in <module>
    psApp.MakeContactSheet(CSInputFiles, CSoptions)
  File "C:\Users\chris\AppData\Local\Temp\gen_py\3.9\E891EE9A-D0AE-4CB4-8871-F92C0109F18Ex0x1x0\_Application.py", line 97, in MakeContactSheet
    return self._oleobj_.InvokeTypes(1129599816, LCID, 1, (8, 0), ((12, 1), (12, 17)),InputFiles
TypeError: must be real number, not WindowsPath

这根本没有道理!它怎么会期望一个真实的数字呢?这是一个输入文件数组


Tags: 函数inpynoneforapplicationfsusers
1条回答
网友
1楼 · 发布于 2024-09-29 17:12:27

问题中指定的错误是因为我将options参数设置为列表而不是对象。有关对象结构的信息,可以查看here

然而,在对GitHub进行了一些询问之后,我发现MakeContactSheet是一个不推荐使用的函数,如this文档第19页所述

这导致我使用枕头库开发了一种替换品

解决方法是简单地创建一个空的png,然后将所有要放在联系人表上的图像粘贴到该png

为了解决这里的问题,我将粘贴这个程序的简化版本

from PIL import Image
from os import walk, path

#rows = amount of rows (int)
#columns = amount of clomns (int)
#sheetWidth = the width of the contact sheet in inch (int)
#sheetHeight = the height of the contact sheet in inch (int)
#aspectRatio = the simplified height to width ratio of the images on the contact sheet (height/width) (float)
#ppi = pixels per inch
#path = the folder containing all the images you wish to make a contact sheet of (string)

def make_contact_sheet(rows, columns, sheetWidth, sheetHeight, aspectRatio, ppi, filePath):

    #convert inches to pixels
    sheetWidth *= ppi
    sheetHeight *= ppi

    #Calculate the size that images will be on the sheet
    imageHeight = sheetHeight // columns
    imageWidth = int(imageHeight * aspectRatio)

    #Calculate how far apart the images will be spaced (I call this padding)
    xRemSpace = sheetWidth - (imageWidth * columns)
    xPad = xRemSpace // (columns-1)

    yRemSpace = sheetHeight - (imageHeight * rows)
    yPad = yRemSpace // (rows+1)

    #Now make the empty png
    sheet = Image.new("RGBA", (sheetWidth, sheetHeight), color=(0,0,0,255))

    #Loop through paths of the images and paste the images one by one
    x, y = 0, yPad
    images = [Image.open(path.join(r,f)) for r,sd,fs in walk(filePath) for f in fs]

    for i in range(len(images)):
        #Resize the image
        resized = images[i].resize((imageWidth, imageHeight))

        #Paste the images
        if i == 0:
            sheet.paste(resized, (x,y))
        elif i % columns == 0:
            x = 0
            y += imageHeight + yPad
            sheet.paste(resized, (x,y))
        else:
            x += imageWidth + xPad
            sheet.paste(resized, (x,y))

    return sheet

if __name__ == "__main__":
    sheet = make_contact_sheet(3, 5, 8, 5, (2/3), 300, r"Some path")
    sheet.show()

如上所述,这是一个非常粗糙的示例,它基于我编写的最终程序的更复杂版本。但我已经超越了相关性的界限

相关问题 更多 >

    热门问题