我正在处理一个从命令行获取图像名称的python代码,并将其打印在一个窗口中,重新调整为用户的喜好,即输入 python3.2 resize.py image.gif 2 3 将采用image.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.py 和 resize.py ,并且使用了正方形图像,但是当我放入一个无方形图像时,我得到以下内容:
pixel = 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行,in get
返回self.tk.call(self.name,' get',x,y)
_tkinter.TclError:pyimage1 get:坐标超出范围
不确定为什么说......
答案 0 :(得分: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)
现在,您可以将4
替换为xscale
,然后就完成了。现在只需对行重复相同的技巧(并给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
有用的情况,但这不是其中之一。
答案 1 :(得分:0)
我已经弄清楚了。这是r
和c
的问题。 r
必须在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()