1

我正在编写一个 python 代码,该代码从命令行获取图像名称,并将其打印在窗口中,根据用户的喜好重新缩放,即输入python3.2 resize.py image.gif 2 3将获取图像。 gif 和两倍的宽度和三倍的高度。我编写了一个将图像翻两番的代码:

import sys
from cImage import *

def main():
    oldImage = FileImage(sys.argv[1])
    width = oldImage.getWidth()
    height = oldImage.getHeight()
    myWin = ImageWin("Old Image", width, height)
    myNewWin = ImageWin("Quadrupled Image", width*4, height*4)
    newImage = EmptyImage(width*4, height*4)

    for r in range(width):
        for c in range(height):
            pixel = oldImage.getPixel(r, c)
            newImage.setPixel(4*r, 4*c, pixel)
            newImage.setPixel(4*r, 4*c+1, pixel)
            newImage.setPixel(4*r, 4*c+2, pixel)
            newImage.setPixel(4*r, 4*c+3, pixel)
            newImage.setPixel(4*r+1, 4*c, pixel)
            newImage.setPixel(4*r+1, 4*c+1, pixel)
            newImage.setPixel(4*r+1, 4*c+2, pixel)
            newImage.setPixel(4*r+1, 4*c+3, pixel)
            newImage.setPixel(4*r+2, 4*c, pixel)
            newImage.setPixel(4*r+2, 4*c+1, pixel)
            newImage.setPixel(4*r+2, 4*c+2, pixel)
            newImage.setPixel(4*r+2, 4*c+3, pixel)
            newImage.setPixel(4*r+3, 4*c, pixel)
            newImage.setPixel(4*r+3, 4*c+1, pixel)
            newImage.setPixel(4*r+3, 4*c+2, pixel)
            newImage.setPixel(4*r+3, 4*c+3, pixel)
    oldImage.draw(myWin)
    newImage.draw(myNewWin)
    myWin.exitOnClick()
    myNewWin.exitOnClick()

main()

但是我在试图弄清楚如何编辑我的代码以便它按要求对其进行缩放时遇到了麻烦。我觉得我应该能够实现一个 for 循环,但我很难让事情正常工作。

任何帮助将非常感激!编辑:

我正在使用以下修改后的代码:

from cImage import *
import sys

def main():
    oldImage = FileImage(sys.argv[1])
    oldWidth = oldImage.getWidth()
    oldHeight = oldImage.getHeight()

    widthScalar = int(sys.argv[2])
    heightScalar = int(sys.argv[3])

    newWidth = oldWidth * widthScalar
    newHeight = oldHeight * heightScalar

    myWin = ImageWin("Old Image", oldWidth, oldHeight)
    myNewWin = ImageWin("Scaled Image", newWidth, newHeight)
    newImage = EmptyImage(newWidth, newHeight)

    for r in range(oldHeight*heightScalar):
        for c in range(oldWidth*widthScalar):
            pixel = oldImage.getPixel(r // heightScalar, c // widthScalar)
            newImage.setPixel(r, c, pixel)

    oldImage.draw(myWin)
    newImage.draw(myNewWin)
    myWin.exitOnClick()
    myNewWin.exitOnClick()

main()

我也尝试过使用更复杂的方法:

for r in range(oldHeight):
        for c in range(oldWidth):
            pixel = oldImage.getPixel(r,c)
            for i in range(heightScalar):
                for j in range(widthScalar):
                    myNewImage.setPixel((heightScalar*r)+i, (widthScalar*c)+j, pixel)

我已经用相等的标量(即 3 x 3)对其进行了测试,它适用于方形图像,但是当我尝试更改其中一个时,出现错误:

ValueError:像素索引超出范围。

当我尝试使用非方形图像时,我得到了我的坐标超出范围的错误。

我有点不知所措......谢谢你的帮助! - - - - - - - - - - - - - - - - - - - - - - - 我已经走了并测试了我的quadruple.pyresize.py,并且它们可以使用方形图像,但是当我放入非方形图像时,我得到以下信息:

像素 = oldImage.getPixel(r, c)

文件“/Users/jakebenedict/CPS/Lab6/cImage.py”,第 313 行,在 getTkPixel 中

p = [int(j) for j in self.im.get(x,y).split()]

文件“/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/tkinter/init .py ”,第 3260 行,在 get

return self.tk.call(self.name, 'get', x, y)

_tkinter.TclError: pyimage1 get: 坐标超出范围

不太清楚为什么这么说...

4

2 回答 2

0

我觉得我应该能够实现一个 for 循环

你在正确的轨道上。但要这样做,您实际上需要两个嵌套的 for 循环。*

for yoffset in range(yscale):
    for xoffset in range(xscale):
        newImage.setPixel(yscale*r + yoffset, xscale*c + xoffset, pixel)

为什么?

嗯,首先,对于每一行,你有 4 行代码,如下所示:

newImage.setPixel(4*r, 4*c, pixel)
newImage.setPixel(4*r, 4*c+1, pixel)
newImage.setPixel(4*r, 4*c+2, pixel)
newImage.setPixel(4*r, 4*c+3, pixel)

因此,要将其抽象为一个循环,您希望它4*c+n是一个n从 0 到 3 的循环,如下所示:

for n in range(4):
    newImage.setPixel(4*r, 4*c+n, pixel)

现在你可以用 替换4xscale你就完成了。现在只需对行重复相同的技巧(并给出n一个更好的名称,以便您可以保持行和列的偏移量直线)并且您拥有上面的代码。


然而,如果你改变你的算法,可能有一种更简单的方法来看待这个问题。与其遍历原始像素并找出每个像素映射到的 16 个新像素,为什么不遍历新像素并找出每个(非唯一)映射到的 1 个旧像素呢?

for r in range(height*yscale):
    for c in range(width*xscale):
        pixel = oldImage.getPixel(r // yscale, c // xscale)
        newImage.setPixel(r, c, pixel)

除了更简单之外,这还有另一个优点:您可以允许用户指定浮点值,并且循环无需更改即可工作。


* 你真的不需要两个循环;您始终可以在笛卡尔积上编写一个循环,例如for (yoffset, xoffset) in itertools.product(range(yscale), range(xscale)):. 但这实际上只是以更复杂的方式说同样的话。肯定有一些product有用的情况,但这不是其中之一。

于 2013-10-02T20:36:23.443 回答
0

我已经想通了。r和有问题cr需要在 的范围内oldWidth,并且c需要在 的范围内oldHeight

from cImage import *
import sys

def main():
    oldImage = FileImage(sys.argv[1])
    oldWidth = oldImage.getWidth()
    oldHeight = oldImage.getHeight()

    widthScalar = int(sys.argv[2])
    heightScalar = int(sys.argv[3])

    newWidth = oldWidth * widthScalar
    newHeight = oldHeight * heightScalar

    myWin = ImageWin("Old Image", oldWidth, oldHeight)
    myNewWin = ImageWin("Scaled Image", newWidth, newHeight)
    newImage = EmptyImage(newWidth, newHeight)

    for r in range(oldWidth):
        for c in range(oldHeight):
            pixel = oldImage.getPixel(r, c)
            for i in range (widthScalar):
                for j in range(heightScalar):
                    newImage.setPixel((widthScalar*r)+i, (heightScalar*c)+j, pixel)

    oldImage.draw(myWin)
    newImage.draw(myNewWin)
    myWin.exitOnClick()
    myNewWin.exitOnClick()

main()
于 2013-10-03T15:41:30.510 回答