Python的putpixel()无法正常工作

4

我正在做一个学校项目(我只懂得基本的编程,而且python是我唯一知道的语言),需要改变像素颜色来在图片中编码信息,但PIL的putpixel似乎无法工作,这是我的代码。

附注:所有关于PIL的信息都是自学的,英语不是我的主要语言,如果您能使用简化的语言交流我会非常感激。

from PIL import Image
e=input('file and location?  ')
img=Image.open(e)
pmap=img.load()
imy=img.height
imx=img.width
if int(input('1 for encoding, 2 for decoding   '))==1:
    a=input('Your message?   ')
    for i in range(len(a)):
        r , g , b=img.getpixel((i+10,imy//2))
        img.putpixel((i+10,imy//2),(ord(a[i]),g,b))
    r,g,b=img.getpixel((len(a)+10,imy//2))
    img.putpixel((len(a)+10,imy//2),(999,g,b)) #999 is the stop code in     decoding
else:
    r=u=0
    m=''
    while r!=999:
        r , g , b=img.getpixel((10+u,imy//2))
        m+=chr(r)
        u+=1
    print(m[:len(a)-1])
img.save(e)

请注意,我并不想改变视觉效果,并且我已经完成了调试。此外,没有错误,但是putpixel却无法正常工作。正如我所说,我是编程新手,如果有愚蠢的错误,请见谅。


嗯,我认为这是你的第一个问题,不算太糟糕。然而,请尝试更详细地解释一下错误在哪里。如果您没有看到错误,请告诉我们您得到了什么,以及您期望得到什么。请记住,您越努力地解释您的问题,社区就越容易帮助您。 - Héctor Valverde
我没有收到任何错误信息,但像putpixel这样的像素根本没有改变,我不认为我做错了什么。 - Kamyab Qanizadeh
好的,尝试添加一些调试行以了解发生了什么。例如,在a=input('Your message? ')语句下面添加print a,确保您实际上存储了预期的值。同样地,再添加几个print语句。 - Héctor Valverde
你只是修改了一些单个像素。你确定没有任何改变吗?你可能在查看图像时无法“看到”它。 - tfv
我已经完成了调试,一切都正常,唯一的问题是在程序的最后,我从未到达r=999的像素,因此循环将继续进行,直到超出图像范围,这是因为putpixel无法应用停止代码。而且,当我说它不起作用时,我的意思不是看不到,而是R值没有改变。 - Kamyab Qanizadeh
2个回答

3
使用您的代码并在图像上尝试后,putpixel按预期工作。像素的变化非常难以看到,这可能是您认为它不起作用的原因。相信我,它正在工作,只是您看不到。
然而,我发现您的代码有两个问题:
1)999无法编码
999不能在单个像素中编码。像素的最大值是255(范围为0-255)。您需要选择不同的停止代码/序列。我建议将停止代码更改为255。
2)解码时,a从未被定义
您需要通过其他方式获取消息的长度。我建议使用计数器来完成此操作:
counter = 0
while something:
    counter += 1

# do something with count here

总之,您的代码的工作版本应如下所示:
e=input('file and location?  ')
img=Image.open(e)
pmap=img.load()
imy=img.height
imx=img.width
if int(input('1 for encoding, 2 for decoding   '))==1:
    a=input('Your message?   ')
    for i in range(len(a)):
        r , g , b= img.getpixel((i+10,imy//2))
        img.putpixel((i+10,imy//2),(ord(a[i]),g,b))
    r,g,b=img.getpixel((len(a)+10,imy//2))
    img.putpixel((len(a)+10,imy//2),(255,g,b)) #255 is the stop code in     decoding
else:
    r=u=0
    m=''
    message_length=0
    while r!=255:
        message_length+=1
        r , g , b=img.getpixel((10+u,imy//2))
        m+=chr(r)
        u+=1
    print(m[:message_length-1])
img.save(e) 

0

虽然差异存在,但只有几个像素。如果我计算原始图像和新图像之间的差异,你会在左中部看到它,存储在test2.png中。为了增强对比度,我已经“均衡化”了该图像。

from PIL import Image, ImageChops, ImageOps

img=Image.open("image.jpg")
pmap=img.load()
img2=img.copy()
imy=img.height
imx=img.width
if int(input('1 for encoding, 2 for decoding   '))==1:
    a=input('Your message?   ')
    for i in range(len(a)):
        r , g , b=img.getpixel((i+10,imy//2))
        img.putpixel((i+10,imy//2),(ord(a[i]),g,b))
    r,g,b=img.getpixel((len(a)+10,imy//2))
    img.putpixel((len(a)+10,imy//2),(999,g,b)) #999 is the stop code in     decoding
else:
    r=u=0
    m=''
    while r!=999:
        r , g , b=img.getpixel((10+u,imy//2))
        m+=chr(r)
        u+=1
    print(m[:len(a)-1])
img.save("test.png")
img3=ImageChops.difference(img, img2)
img3=ImageOps.equalize(img3)
img3.save("test2.png")

这是结果:

在此输入图像描述


我不想改变图片的外观,我只是想通过将像素的R值更改为相应字符的ASCII码来将消息编码到其中,以便稍后解码。如果我理解有误,请您详细解释一下。 - Kamyab Qanizadeh
我的观点是:你的程序正在工作。你保存的图像与原始图像不同。但如果我要编码的文本是“test”,你只修改了4个单像素(len(a)=4),所以你肉眼看不出差异。这就是为什么我减去了原始图像和新图像,只留下差异。由于差异值很小(ord(a[i])约为60),因此我通过均衡化放大灰度值。 - tfv

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接