使用Python3.2重新缩放图像

使用Python3.2重新缩放图像,python,image-processing,python-3.x,image-resizing,Python,Image Processing,Python 3.x,Image Resizing,我正在编写一个python代码,该代码从命令行获取一个图像名称,并将其打印在窗口中,根据用户的喜好重新缩放,即输入python3.2 resize.py image.gif 23将获取image.gif,并将宽度增加一倍,高度增加三倍。我编写了一个将图像翻倍的代码: import sys from cImage import * def main(): oldImage = FileImage(sys.argv[1]) width = oldImage.getWidth()

我正在编写一个python代码,该代码从命令行获取一个图像名称,并将其打印在窗口中,根据用户的喜好重新缩放,即输入python3.2 resize.py image.gif 23将获取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:像素索引超出范围

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

我有点不知所措。。。谢谢你的帮助! —————————————————————————————————————————————— 我已经测试了我的quartle.py和resize.py,它们可以使用方形图像,但是当我放入一个非方形图像时,我得到以下结果:

像素=oldImage.getPixelr,c

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

p=[intj代表self.im.getx中的j,y.split]

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

返回self.tk.callself.name,'get',x,y

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

不太清楚为什么会说

我觉得我应该能够实现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)
for n in range(4):
    newImage.setPixel(4*r, 4*c+n, pixel)
所以,要把它抽象成一个循环,你需要4*c+n是一个循环,其中n从0到3,如下所示:

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)
for n in range(4):
    newImage.setPixel(4*r, 4*c+n, pixel)
现在,您可以用xscale替换4,就完成了。现在,只需对行重复相同的技巧,并给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)
除了更简单之外,这还有另一个优点:您可以允许用户指定一个浮动比例值,并且循环可以在不做任何更改的情况下工作


*你不需要两个循环;您始终可以在笛卡尔乘积上编写单个循环,如itertools中的yoffset、xoffset。productrangeyscale、rangexscale:。但这实际上只是用一种更复杂的方式说了同样的话。当然也有产品有用的情况,但这不是其中之一。

我已经找到了答案。这是r和c的问题。r需要在oldWidth范围内,c需要在oldHeight范围内:


作为一个旁注:我很确定你的环的宽度和高度是向后的;行应该在高度范围内,列应该在宽度范围内,对吗?是的,你是对的。我猜,因为它只是在一个正方形的尺度上工作,所以顺序并不重要。看起来你得到的新错误与向后获得宽度和高度是同一个问题。查看每个函数的文档,确保顺序正确。我猜要么getPixel/setPixel取x,y而不是r,c,要么ImageWin和EmptyImage取行、列而不是宽度、高度。对于一个图书馆来说,做一些rXc和其他xXy的事情是很奇怪的。非常感谢你的帮助!现在,我正在用你给我的新的、更简单的代码进行测试。变量名r和c在这种情况下非常容易引起误解。r听起来应该是一个行号,一个Y值,和c一个列号,一个X值,但你用的是另一种方式。是的,可以理解。我选择r和c是因为当我学习python中的图像时使用了这两个变量。这仍然有点令人困惑,因为人们倾向于期望行-列顺序而不是列-行,而他们期望x-y而不是y-x,但远不及调用行c和列r。