使用Python3.2重新缩放图像

2024-09-27 23:23:26 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在编写一个python代码,它从命令行获取一个图像名称,并在一个窗口中打印它,并根据用户的喜好重新缩放,即输入python3.2调整大小.py图像.gif2 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循环,但是我很难让事情正常工作。在

任何帮助都将不胜感激! 编辑:

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

^{pr2}$

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

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)

我用相等的标量(即3x3)对它进行了测试,它可以很好地处理正方形图像,但是当我试图改变其中一个时,我得到了一个错误:

ValueError: Pixel index out of range.

当我尝试用一个不正方形的图像时,我得到了一个错误,我的坐标超出了范围。在

我有点不知所措。。。谢谢你的帮助! —————————————————————————————————————————————— 我去测试了我的两个四倍.py调整大小.py,对于方形图像,它们是有效的,但是当我放入一个非方形图像时,我得到以下结果:

pixel = oldImage.getPixel(r, c)

File "/Users/jakebenedict/CPS/Lab6/cImage.py", line 313, in getTkPixel

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

File "/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/tkinter/init.py", line 3260, in get

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

_tkinter.TclError: pyimage1 get: coordinates out of range

不太清楚为什么它说。。。在


Tags: 代码inpy图像forgetrangewidth
2条回答

我已经想好了。{{cd2>有问题。r需要在oldWidth的范围内,而{}需要在{}的范围内:

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()

I feel that I should probably be able to implement a for loop

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

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

为什么?在

首先,每行有4行代码,如下所示:

^{pr2}$

因此,要将其抽象为一个循环,您希望4*c+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)

除了更简单,这还有另一个优点:您可以允许用户指定一个float scale值,并且循环不会发生任何更改。在


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

相关问题 更多 >

    热门问题