栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

比较原始图像和可能不需要原始图像的已编辑图像的另一种方法

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

比较原始图像和可能不需要原始图像的已编辑图像的另一种方法

这是一种使用PIL进行图像处理的方法,可将数据嵌入到每个通道8位RGB图像文件中像素的每个颜色通道的最低有效位。

下面的代码说明了Python中的位流处理。这是相当有效的(只要这样的操作 可以 使用Python高效的),但它牺牲效率使用的可读性和简单性,必要时。:)

#! /usr/bin/env python''' Steganography with PIL (really Pillow)    Enpres / depres bits of a binary data file into the LSB of each color     value of each pixel of a non-palette-mapped image.    Written by PM 2Ring 2015.02.03'''import sysimport getoptimport structfrom PIL import Imagedef readbits(bytes):    ''' Generate single bits from bytearray '''    r = range(7, -1, -1)    for n in bytes:        for m in r: yield (n>>m) & 1def enpre(image_bytes, mode, size, dname, oname):    print 'Encoding...'    with open(dname, 'rb') as dfile:        payload = bytearray(dfile.read())    #Prepend enpred data length to payload    datalen = len(payload)    print 'Data length:', datalen    #datalen = bytearray.fromhex(u'%06x' % datalen)    datalen = bytearray(struct.pack('>L', datalen)[1:])    payload = datalen + payload    databits = readbits(payload)    for i, b in enumerate(databits):        image_bytes[i] = (image_bytes[i] & 0xfe) | b    img = Image.frombytes(mode, size, str(image_bytes))    img.save(oname)def bin8(i):     return bin(i)[2:].zfill(8)bit_dict = dict((tuple(int(c) for c in bin8(i)), i) for i in xrange(256))def depre_bytes(data):    return [bit_dict[t] for t in zip(*[iter(c&1 for c in data)] * 8)]def depre(image_bytes, dname):    print 'Decoding...'    t = depre_bytes(image_bytes[:24])    datalen = (t[0] << 16) | (t[1] << 8) | t[2]    print 'Data length:', datalen    t = depre_bytes(image_bytes[24:24 + 8*datalen])    with open(dname, 'wb') as dfile:        dfile.write(str(bytearray(t)))def process(iname, dname, oname):    with Image.open(iname) as img:        mode = img.mode        if mode == 'P': raise ValueError, '%s is a palette-mapped image' % fname        size = img.size        image_bytes = bytearray(img.tobytes())    #del img    print 'Data capacity:', len(image_bytes) // 8 - 24    if oname:        enpre(image_bytes, mode, size, dname, oname)    elif dname:        depre(image_bytes, dname)def main():    #input image filename    iname = None    #data filename    dname = None    #output image filename    oname = None    def usage(msg=None):        s = msg + 'nn' if msg else ''        s += '''Embed data into or extract data from the low-order bits of an image file.Usage:%s [-h] -i input_image [-d data_file] [-o output_image]To enpre, you must specify all 3 file names.To depre, just specify the input image and the data file names.If only the the input image is given, its capacity will be printed,i.e., the maximum size (in bytes) of data that it can hold.Uses PIL (Pillow) to read and write the image data.Do NOT use lossy image formats for output, eg JPEG, or the data WILL get scrambled.The program will abort if the input image is palette-mapped, as such imagesare not suitable.'''        print >>sys.stderr, s % sys.argv[0]        raise SystemExit, msg!=None    try:        opts, args = getopt.getopt(sys.argv[1:], "hi:d:o:")    except getopt.GetoptError, e:        usage(e.msg)    for o, a in opts:        if o == '-h': usage(None)        elif o == '-i': iname = a        elif o == '-d': dname = a        elif o == '-o': oname = a    if iname:        print 'Input image:', iname    else:        usage('No input image specified!')    if dname:        print 'Data file:', dname    if oname:        print 'Output image:', oname    process(iname, dname, oname)if __name__ == '__main__':    main()


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/647346.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号