如何用Python正确读取PPM文件

0 投票
1 回答
3149 浏览
提问于 2025-04-18 01:28

这是我的总体指示

写一个颜色类(Color),用来表示RGB颜色,使用的值是0到255之间的整数。你的类必须: 放在image.py文件里 提供一个构造函数,接受红色、绿色和蓝色通道的值,并存储这些值 提供公共方法,返回红色、绿色和蓝色通道的值

写一个可移植的像素图类(PortablePixmap),用来表示PPM图像。你的类必须: 放在image.py文件里 提供一个构造函数,接受魔法数字、宽度、高度、最大颜色值和像素数据,并存储这些值 将像素数据存储为Color对象的列表(或列表的列表) 提供一个公共方法,返回PPM图像的字符串表示

写一个read_ppm函数,打开一个PPM图像文件,读取其内容,并返回一个包含这些内容的PortablePixmap对象。你的函数必须: 放在image.py文件里 读取PPM图像文件的内容 对PPM图像文件的格式不敏感 如果期望的像素数量和提供的像素数量不一致,则退出并报错

写一个主函数,测试你的read_ppm函数。你的函数必须放在main.py文件里

这是我目前的进展

class Color:
# constructor takes in values from client and stores them
def __init__(self, red, green, blue): 


    # checks that type of arg == int: raises exception otherwise 
    if (isinstance(red, int) and isinstance(green, int) and isinstance(blue, int)):     
        print("good stuff, indeed integers")
    else:   
        raise TypeError("Argument must be an integer.")

    # checks if values are between 0 and 225 
    if red < 0 or red > 225: 
        print("0 < rgb values < 225")
    elif green < 0 or green > 225:
        print("0 < rgb values < 225") 
    elif blue < 0 or blue > 225:
        print("0 < rgb values < 225")

    # instance variables (RGB values)
    self._red = red 
    self._green = green
    self._blue = blue 


# methods that reuturn RGB values
def returnRed(self): 
    return self._red 

def returnGreen(self):
    return self._green

def returnBlue(self):
    return self._blue


'''class that represents a PPM image'''
class PortablePixmap:
    def __init__(self, magic_number, width, height, max_color_value, pixel_data):
        self._magic_number = magic_number
        self._width = width
        self._height = height
        self._max_color_value = max_color_value
        self._pixel_data = pixel_data


    def __str__(self):
        s = self._magic_number
        s += '\n' + str(self._width)
        s += ' ' + str(self._height)
        s += '\n' + str(self._max_color_value)
        for pixel in self._pixel_data:
            s += ' ' + str(pixel[0])
            s += ' ' + str(pixel[1])
            s += ' ' + str(pixel[2])

        return s

我有几个问题想要澄清: 1. 我创建Color类的方式对吗? 2. 我需要在这个类里抛出任何异常吗?因为我们最终会从一个文件中读取所有内容,但不一定每个内容都在单独的一行上。

我只是想知道我这样做是否正确。指示看起来是一步一步的,但我不太明白这些内容是如何连接在一起的,所以我担心自己做得太多或太少。

提前谢谢你

1 个回答

0

从说明书上看,并不清楚你是否需要检查数值,而且你的检查在某些情况下只会引发异常,其他情况下则会产生副作用(比如打印信息)。从重用的角度来看,我更希望只有异常,如果有的话。除了缩进错误(我假设这个错误只出现在这里,而不是你的源代码中),Color类似乎满足需求,尽管它的访问方式有点不符合Python的风格;可能是因为有人受过Java的训练。

文档字符串应该放在PortablePixmap类里面,而不是它的上面。

最值得注意的是,你的类需要同时满足不对PPM格式敏感和将像素存储为8位无符号RGB的要求。这使得支持所有PPM格式变得不可能,因为PPM格式支持16位的数值(注意PPM格式中的maxval字段)。

你的PortablePixmap类也没有使用Color类:“将像素数据存储为Color对象的列表(或列表的列表)”。这个要求导致实现效率非常低下,但我想这整个过程只是一个练习。你需要从像素数据字符串中提取RGB三元组。这也是你需要进行的唯一检查;验证像素的数量是否正好是正确的。如果检查失败,应该会抛出一个ValueError异常。

如果我是写这种东西的话,我可能会使用slots来减少Color类的内存使用,使用数组来处理大量有限范围的数值,可能还会使用属性来让存储变得透明,而不需要使用繁琐的获取方法。使用splitjoin会让处理像素集合变得更简单。

撰写回答