0

我正在尝试从 Python Imaging Library 向 Image 类添加一个新方法。我想要一个名为 DilateImage 的新类,它与原始 Image 类完全一样,除了它还包含一个 dilate() 函数,该函数在类实例上执行时会修改它。这是我的示例代码(不起作用):

import Image

def DilateImage(Image):
   def dilate(self):
      imnew = self.copy()
      sourcepix = imnew.load()
      destpix = self.load()

      for y in range(self.size[1]):
         for x in range(self.size[0]):
            brightest = 255
            for dy in range(-1,2):
               for dx in range(-1,2):
                  try:
                     brightest = min(sourcepix[x+dx,y+dy], brightest)
                  except IndexError:
                     pass
            destpix[x, y] = brightest

当我尝试使用这个新的类类型来创建一个使用基类的“open”函数的实例时,它失败了:

>>> test = DilateImage.open("test.jpg")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'function' object has no attribute 'open'
4

4 回答 4

9

利用

class DilateImage(Image)

不是

def DilateImage(Image)
于 2012-09-01T19:59:36.437 回答
3

您的代码有两个问题。其中之一已经指出,当定义一个类时,你需要使用class关键字,因为def关键字定义了一个函数或一个方法。

第二个问题是调用

import Image

将名为 Image的模块Image导入命名空间,以便Image在您的代码中引用该模块。它不是一个对象或类,所以

class MyImage(Image)

将尝试从模块派生一个新类,这将失败。

Image模块包含一个名为Image. 将模块导入Image命名空间后,您可以将此类称为Image.Image. 要扩展此类,您可以执行以下操作:

import Image

class MyImage(Image.Image)

为了减少混淆,您还可以将 Image 模块导入不同的命名空间:

import Image as Img

class MyImage(Img.Image)

问题在于,PIL 似乎并未设计为允许对 Image 类进行这种扩展。它的模块提供了一堆函数,这些函数将 Image 的实例作为参数并返回 Image 的新实例。实际 Image 类中只有几个方法。因此,您可能想要做的是编写一个函数,该函数将采用 Image 的实例并创建 Image 的新实例,而不是通过新方法扩展 Image 类。例如,像这样:

import Image

def DilateImage(source):
      dest = source.copy()
      sourcepix = source.load()
      destpix = dest.load()

      for y in range(source.size[1]):
         for x in range(source.size[0]):
            darkest = 255
            for dy in range(-1,2):
               for dx in range(-1,2):
                  try:
                     darkest = min(sourcepix[x+dx,y+dy], darkest)
                  except IndexError:
                     pass
            destpix[x, y] = darkest

      return dest


im1 = Image.open("test.jpg")

img2 = DilateImage(im1)

img2.show()
于 2012-09-12T17:25:58.980 回答
1

当您应该使用关键字时,您将定义DilateImage为一个函数(通过使用)。因此, since 函数没有属性。defclassAttributeErroropen

于 2012-09-01T20:00:47.193 回答
0

我不知道这是否是最近的更改,但与之前的评论风格相同,您实际上可以修改/添加到现有类。例如:

class list(list):
    #Create an Empty List
    def empty(N:int):
        """Create an N-Long Empty List"""
        return [None]*int(N)

这不会改变 'list' 类的现有功能,但会添加一个执行此操作的方法:

>>> list.empty(5)
[None, None, None, None, None]

您也可以对其他类执行此操作,因此提供示例代码以更直接地回答您的问题:

#Import Libraries
import Image

#Add Methods to Image
class Image(Image):
    def dilate(*args, **kwargs):
        ...

我不确定是否建议这样做,但是您可以做到这一点很酷!

于 2020-09-11T23:38:14.563 回答