Python枕头和JPEG文件的奇怪问题-像素元组元素不断减少。为什么?

Python枕头和JPEG文件的奇怪问题-像素元组元素不断减少。为什么?,python,debugging,tuples,python-imaging-library,steganography,Python,Debugging,Tuples,Python Imaging Library,Steganography,我有一个隐写术python程序的(非常)草稿,它在图片中编码一条秘密消息。现在,我只是根据消息的下一个二进制元素(消息转换为ascii十六进制,然后转换为二进制),将每个3000像素的第三个元素调高或调低一个 我的问题有点无关紧要,但我包含了我所有的代码,因此如果有人真的觉得自己很好,他们可以简单地复制并通过代码(可能需要pip安装pillow,获取图像,并为myascii模块制作单独的python脚本,但仅此而已) 我的问题:每次我运行这段代码时,打印(px[width-1,height-1]

我有一个隐写术python程序的(非常)草稿,它在图片中编码一条秘密消息。现在,我只是根据消息的下一个二进制元素(消息转换为ascii十六进制,然后转换为二进制),将每个3000像素的第三个元素调高或调低一个

我的问题有点无关紧要,但我包含了我所有的代码,因此如果有人真的觉得自己很好,他们可以简单地复制并通过代码(可能需要pip安装pillow,获取图像,并为myascii模块制作单独的python脚本,但仅此而已)

我的问题:每次我运行这段代码时,打印(px[width-1,height-1])和打印(px[width-2,height-2])在每个rgb值中递减一。我不明白为什么要救我的命。因此,一些终端输出如下所示:

PS C:\Users\xxx> & C:/Users/xxx/AppData/Local/Programs/Python/Python38-32/python.exe c:/Users/xxx/Desktop/Python_stuff/assorted/steganography/steganography.py
['4B', '65', '6C', '6C', '65', '79', '27', '73', '20', '66', '61', '76', '6F', '72', '69', '74', '65', '20', '63', '6F', '6C', '6F', '72', '20', '69', '73', '20', '67', '72', '65', '65', '6E', '2E']
010010110110010101101100011011000110010101111001001001110111001100100000011001100110000101110110011011110111001001101001011101000110010100100000011000110110111101101100011011110111001000100000011010010111001100100000011001110111001001100101011001010110111000101110
(75, 51, 17)
(74, 50, 16)
(73, 37, 13)
PS C:\Users\xxx> & C:/Users/xxx/AppData/Local/Programs/Python/Python38-32/python.exe c:/Users/xxx/Desktop/Python_stuff/assorted/steganography/steganography.py
['4B', '65', '6C', '6C', '65', '79', '27', '73', '20', '66', '61', '76', '6F', '72', '69', '74', '65', '20', '63', '6F', '6C', '6F', '72', '20', '69', '73', '20', '67', '72', '65', '65', '6E', '2E']
010010110110010101101100011011000110010101111001001001110111001100100000011001100110000101110110011011110111001001101001011101000110010100100000011000110110111101101100011011110111001000100000011010010111001100100000011001110111001001100101011001010110111000101110
(74, 50, 16)
(73, 49, 15)
(73, 37, 13)
PS C:\Users\xxx> & C:/Users/xxx/AppData/Local/Programs/Python/Python38-32/python.exe c:/Users/xxx/Desktop/Python_stuff/assorted/steganography/steganography.py
['4B', '65', '6C', '6C', '65', '79', '27', '73', '20', '66', '61', '76', '6F', '72', '69', '74', '65', '20', '63', '6F', '6C', '6F', '72', '20', '69', '73', '20', '67', '72', '65', '65', '6E', '2E']
010010110110010101101100011011000110010101111001001001110111001100100000011001100110000101110110011011110111001001101001011101000110010100100000011000110110111101101100011011110111001000100000011010010111001100100000011001110111001001100101011001010110111000101110
(73, 49, 15)
(72, 48, 14)
(73, 37, 13)
程序和模块如下所示:

#def encode(myimage):


#def decode(myimage):

import bin_hex_ascii_converter as myascii

myascii.hex_to_dec("34")
#letter_to_ascii_hex(letter):
#hex_to_bin(foo):
from PIL import Image
foo = Image.open("C:/Users/xxx/Pictures/Saved Pictures/funny_image_encoded.jpg")
#foo = Image.open("C:/Users/xxx/Pictures/Saved Pictures/funny_image.jpg")
#myImage.show()

secret_message = "Jimmie's favorite color is green."

msg = []
for let in secret_message:
   msg.append(myascii.letter_to_ascii_hex(let))
print(msg)

msg_bin = ""
for myhex in msg:
   msg_bin += myascii.hex_to_bin(myhex)
print(msg_bin)

px = foo.load()

width = foo.size[0]
height = foo.size[1]

print(px[width-1,height-1])
print(px[width-2,height-2])

secret_separation = 3000
bar = 0
myiter = 0
limit = len(msg_bin)
for i in range(0,height):
   for j in range(0,width):
       if bar % 3000 == 0 and myiter < limit:
           temp = int(msg_bin[myiter])
           if temp == 0:
               temp = -1
           px[j,i] = (px[j,i][0], px[j,i][1], px[j,i][2]+temp)
           myiter += 1
       bar += 1

#px[5,5] = (px[5,5][0], px[5,5][1], px[5,5][2]+1)
foo.save("C:/Users/xxx/Pictures/Saved Pictures/funny_image_encoded.jpg","JPEG")
print(px[5,5])
       
#定义编码(myimage):
#def解码(myimage):
将bin_十六进制ascii_转换器作为myascii导入
myascii.十六进制至十二进制(“34”)
#字母\至\ ascii \十六进制(字母):
#十六进制至四进制(foo):
从PIL导入图像
foo=Image.open(“C:/Users/xxx/Pictures/Saved Pictures/fully\u Image\u encoded.jpg”)
#foo=Image.open(“C:/Users/xxx/Pictures/Saved Pictures/fully_Image.jpg”)
#myImage.show()
secret\u message=“吉米最喜欢的颜色是绿色。”
味精=[]
对于“泄露秘密”消息:
msg.append(myascii.letter_to_ascii_hex(let))
打印(msg)
msg_bin=“”
对于msg中的myhex:
msg_-bin+=myascii.hex_-to_-bin(myhex)
打印(msg_bin)
px=foo.load()
宽度=食物大小[0]
高度=食物尺寸[1]
打印(像素[宽度-1,高度-1])
打印(像素[宽度-2,高度-2])
秘密分离=3000
巴=0
迈特=0
限制=长度(msg_bin)
对于范围内的i(0,高度):
对于范围(0,宽度)内的j:
如果bar%3000==0且myiter<极限:
temp=int(msg_bin[myiter])
如果温度=0:
温度=-1
px[j,i]=(px[j,i][0],px[j,i][1],px[j,i][2]+温度)
迈特+=1
巴+=1
#px[5,5]=(px[5,5][0],px[5,5][1],px[5,5][2]+1)
foo.save(“C:/Users/xxx/Pictures/Saved Pictures/fully\u image\u encoded.jpg”,“JPEG”)
打印(px[5,5])
另外,我作为myascii导入的模块是:

#hex to dec conversion
def hex_to_dec(foo):
    letts = " ABCDEF"
    if foo[0] in letts:
        num1 = 9 + letts.index(foo[0])
    else:
        num1 = int(foo[0])
    if foo[1] in letts:
        num0 = 9 + letts.index(foo[1])
    else:
        num0 = int(foo[1])
    return num1*16 + num0

def ascii_to_letter(foo):
    low_lett = "abcdefghijklmnopqrstuvwxyz"
    upp_lett = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    #ADD comma and period as well
    if foo == 44:
        return ","
    if foo == 46:
        return "."
    if foo == 32:
        return " "
    if foo == 63:
        return "?"
    if foo > 96 and foo < 123:
        return low_lett[foo - 97]
    if foo > 64 and foo < 91:
        return upp_lett[foo - 65]
    #otherwise
    return "*"

def letter_to_ascii_hex(letter):
    return hex(ord(letter))[2:].upper()

# Returning one byte (8 bits)
def hex_to_bin(foo):
    myarr = ["0000",
    "0001",
    "0010",
    "0011",
    "0100",
    "0101",
    "0110",
    "0111",
    "1000",
    "1001",
    "1010",
    "1011",
    "1100",
    "1101",
    "1110",
    "1111"]

    num2 = foo[0]
    if num2 == "A":
        num2 = "1010"
    elif num2 == "B":
        num2 = "1011"
    elif num2 == "C":
        num2 = "1100"
    elif num2 == "D":
        num2 = "1101"
    elif num2 == "E":
        num2 = "1110"
    elif num2 == "F":
        num2 = "1111"
    else:
        num2 = myarr[int(num2)]

    num1 = foo[1]
    if num1 == "A":
        num1 = "1010"
    elif num1 == "B":
        num1 = "1011"
    elif num1 == "C":
        num1 = "1100"
    elif num1 == "D":
        num1 = "1101"
    elif num1 == "E":
        num1 = "1110"
    elif num1 == "F":
        num1 = "1111"
    else:
        num1 = myarr[int(num1)]

    return num2 + num1
#十六进制到十进制的转换
def十六进制至十二进制(foo):
letts=“ABCDEF”
如果letts中的foo[0]:
num1=9+letts.index(foo[0])
其他:
num1=int(foo[0])
如果letts中有foo[1]:
num0=9+letts.index(foo[1])
其他:
num0=int(foo[1])
返回num1*16+num0
def ascii字母对字母(foo):
low_lett=“abcdefghijklmnopqrstuvxyz”
upp_lett=“abcdefghijklmnopqrstuvxyz”
#同时添加逗号和句点
如果foo==44:
返回“,”
如果foo==46:
返回”
如果foo==32:
返回“”
如果foo==63:
返回“?”
如果foo>96且foo<123:
返回低位[foo-97]
如果foo>64且foo<91:
返回upp_lett[foo-65]
#否则
返回“*”
def字母_至_ascii_十六进制(字母):
返回十六进制(ord(字母))[2:]上()
#返回一个字节(8位)
def hex_至_箱(foo):
myarr=[“0000”,
"0001",
"0010",
"0011",
"0100",
"0101",
"0110",
"0111",
"1000",
"1001",
"1010",
"1011",
"1100",
"1101",
"1110",
"1111"]
num2=foo[0]
如果num2==“A”:
num2=“1010”
elif num2==“B”:
num2=“1011”
elif num2==“C”:
num2=“1100”
elif num2==“D”:
num2=“1101”
elif num2==“E”:
num2=“1110”
elif num2==“F”:
num2=“1111”
其他:
num2=myarr[int(num2)]
num1=foo[1]
如果num1==“A”:
num1=“1010”
elif num1==“B”:
num1=“1011”
elif num1==“C”:
num1=“1100”
elif num1==“D”:
num1=“1101”
elif num1==“E”:
num1=“1110”
elif num1==“F”:
num1=“1111”
其他:
num1=myarr[int(num1)]
返回num2+num1
此外,我使用的图片如下:

如Mark Ransom所示-JPEG是有损文件格式。更改为png解决了这个问题。

正如Mark Ransom指出的那样-JPEG是有损文件格式。更改为png解决了问题。

我不知道这是否是您的问题,但JPEG图像有损,无法返回与保存时完全相同的像素值。哦,好的。这仍然是很好的了解,似乎是一种可能性。我将尝试PNG,也许这将纠正这个问题。这绝对是个问题。谢谢,我没有意识到JPEG是有损的。我不知道这是否是你的问题,但JPEG图像是有损的,不会返回与保存时完全相同的像素值。哦,好的。这仍然是很好的了解,似乎是一种可能性。我将尝试PNG,也许这将纠正这个问题。这绝对是个问题。谢谢,我不知道JPEG是有损的。