利用python的PIL函数提取各个像素,例如(255,255,255),转换成二进制例如(1111111,1111111,1111111),修改后一位至两位的话肉眼几乎无法辨别。
把所想隐含的信息转换成二进制ascall码分别填入每个像素的最后一位(可以是最后两位,或者一个像素每一种颜色都填入,在不影响的情况下随意修改)
大概代码如下
原理很简单,但其中最后生成的图片只能是png格式,一开始jpg格式的图片怎么都不对,官方文档只用了png做栗子,所以这也算个缺陷吧。
from PIL import Image
import math
from operator import mod
import binascii
def takeInfo(url):
hide = Image.open(url)
c, d = hide.size
sumx = []
for i in range(0, c):
for k in range(0, d):
x = hide.getpixel((i, k))
x = list(x)
sumx.append(x)
return sumx
def binToOct(s):
count=len(s)-1
var = 0
for i in s:
if(i=='1'):
var = var + math.pow(2,count)
count = count - 1
return var
def makeInfo(myInfo,sum): #1001010111
s = ''
s= str(s)
for i in myInfo:
i = bin(ord(i)).lstrip('0b')
s = s + i
s = list(s)
count = 0
for pix in sum:
pix[2] = bin(pix[2])
pix[2] = list(pix[2])
pix[2][len(pix[2])-1] = s[count]
sum[count][2] = int(binToOct(pix[2]))
count = count + 1
if(count == len(s)-1):
break
return sum
def makePic(sum,url,newUrlxxx):
hide = Image.open(url)
c, d = hide.size
img = Image.new('RGB',(c,d))
count = 0
for i in range(0,c):
for k in range(0,d):
sum[count] = tuple(sum[count])
img.putpixel((i,k),sum[count])
count = count + 1
img.save(newUrlxxx)
sumx = takeInfo(newUrlxxx)
def decipher(url):
sum = takeInfo(url)
x = []
x = list(x)
count = 0
for pix in sum:
count = count + 1
pix[2] = bin(pix[2]).lstrip('0b')
x.append(pix[2][len(pix[2])-1])
if(len(x)==7):
var = int(binToOct(x))
print chr(var)
x = []
if(count == 1400):
break
def encrypt(info,oldImg,newImg):
sum = takeInfo(oldImg)
sum = makeInfo(info, sum)
makePic(sum, oldImg, newUrlx)
if __name__=='__main__':
imageUrl = "d:girl.jpg"
newUrlx = "d:codeGirl.png"
encrypt('ILoveYouSL',imageUrl,newUrlx)
decipher(imageUrl)