首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将数据写入图像

将数据写入图像
EN

Code Review用户
提问于 2015-03-06 18:28:49
回答 1查看 104关注 0票数 9

我已经完成了一个脚本,它将把事情写成图像,然后可以在其他地方阅读(例如。您可以通过imgur共享一个mp3 )。这是我第一次尝试改进我的写作风格,使我的写作尽可能高效,所以如果你在这里看到什么,我可以改进,这将是非常有帮助的知道。

作为记录,这是一个旧的版本,但在这部分之后,它变得更加复杂。无论如何,我保持了同样的写作风格,所以这更容易理解。这个版本将产生一个灰色噪声图像,但是我在后面添加了一些代码来使用自定义图像(这是它变得更复杂的地方)。

代码语言:javascript
复制
from PIL import Image
import cPickle, base64

class ImageStore:

    def __init__( self, imageName="ImageDataStore" ):
        self.imageDataPadding = [116, 64, 84, 123, 93, 73, 106]
        self.imageName = imageName

    def __repr__( self ):
        return "Use this to store or read data from an image.\nUsage:\n - ImageStore().write(input), ImageStore().read()\nYou can also define the name and location of the image.\n - ImageStore( 'C:\filename )'"

    def write( self, input, widthRatio=0.52 ):

        encodedData = base64.b64encode( cPickle.dumps( input ) )
        pixelData = [int( format( ord( letter ) ) ) for letter in encodedData]
        pixelData += imageDataPadding
        #Pad to end with multiple of 3
        for i in xrange( 3-len( pixelData ) ):
            rawData += [255]

        #Set image info
        minimumWidth = 8
        minimumHeight = 8
        currentPixels = len( pixelData )/3

        #Calculate width and height
        if currentPixels <= minimumWidth*minimumHeight:
            #Set to minimum values
            width = minimumWidth
            height = minimumHeight
        else:
            #Calculate based on ratio
            width = int( round( pow( currentPixels, ratioWidth ), -1 ) )
            #Make sure it is divisable by 3
            width /= 3
            width *= 3
            #Note: height is now calculated to be as small as possible while still containing all the data, this is just the old way
            height = int( round( pow( width, 1/( 1/( 1-ratioWidth )-1 ) ), -1 ) )

        #Draw image
        imageOutput = Image.new("RGB", ( width, height ) )
        imageData = imageOutput.load()

        #Assign pixel colours
        numbersToAddIncrement = 0
        for y in range( height ):
            for x in range( width ):
                try:
                    for i in xrange( 3 ):
                        dataRGB[i] = inputData[numbersToAddIncrement]
                        numbersToAddIncrement += 1
                except:
                    for i in xrange( 3 ):
                        dataRGB[i] = rd.randint( 52, 128 )

                dataRGB = [number[1] for number in dataRGB.items()]

                imageData[x,y] = tuple( dataRGB )

        #Save image
        imageOutput.save( str( self.imageName ) + ".png", "PNG" )
        return "Saved file: " + str( self.imageName ) + ".png"

    def read( self ):

        #Read image
        try:
            imageInput = Image.open( str( self.imageName ) + ".png" )
        except:
            return "No image found."

        #Store pixel info
        rawData = []
        for pixels in imageInput.getdata():
            for rgb in xrange( 3 ):
                rawData.append( pixels[rgb] )

        #Truncate end of file
        try:
            for i in xrange( len( rawData ) ):
                j = 0
                while rawData[i+j] == imageDataPadding[j]:
                    j += 1
                    if j == len( imageDataPadding ):
                        rawData = rawData[0:i]
                        break
                if j == len( imageDataPadding ):
                    break
        except:
            print "File is probably corrupted."

        #Decode data    
        encodedData = "".join( [chr( pixel ) for pixel in rawData] )
        outputData = cPickle.loads( base64.b64decode( encodedData ) )

        return outputData

另外,对于定制的图片,我对它的工作方式不太满意。基本上,我修改图像上的像素来存储数据,并读取它,您将修改后的图像与原始图像进行比较。有人能想到一种不需要原始图像的方法吗?

现在的情况是这样的(尽管我尽了最大的努力,事情还是一团糟)-- http://pastebin.com/e1VUTPb5

EN

回答 1

Code Review用户

回答已采纳

发布于 2015-06-29 22:05:38

  1. 首先,你似乎对你的空格很困惑。在Python中,您不应该在大括号( {[()]} )的内容上“填充”。例如,行,xrange( 3-len( pixel_data ) )将变成xrange(3 - len(pixelData))
  2. 其次,您需要您的运营商之间的空白。例如,len( pixelData )/3将变成len(pixel_data) / 3
  3. 您的命名违反了PEP8的正式样式指南。变量和函数应该在snake_case中,类应该在PascalCase中。
  4. 不要在不知道要捕获哪个特定错误的情况下使用except。很容易就会出现一个不被注意到的错误,因为您没有试图捕获特定的错误。
  5. 最后,在函数#Store pixel info中,注释read下面的代码可以缩短为: rawData =[imageInput.getdata()中像素的rgb =[imageInput.getdata(3)中的像素rgb]]
票数 7
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/83423

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档