patternpythonMinor
Writing data into an image
Viewed 0 times
intowritingimagedata
Problem
I've done a script that will write things as images, which can then be read elsewhere (eg. you could share an mp3 through imgur). This is the first one I've done where I've been trying to improve my writing style and make stuff run as efficient as possible, so if there is anything you see here that I can improve it'd be really helpful to know.
For the record, this is an old version, but after this part it got a lot more complicated. I kept the same writing style anyway, so this is a lot easier to understand. This version will make a grey noisy image, but I added some code to use custom images after (which is where it got more complicated).
```
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
#N
For the record, this is an old version, but after this part it got a lot more complicated. I kept the same writing style anyway, so this is a lot easier to understand. This version will make a grey noisy image, but I added some code to use custom images after (which is where it got more complicated).
```
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
#N
Solution
- First off, you seem very confused with your whitespace. In Python, you shouldn't have "padding" around the contents of braces,
{[()]}. For example, the line,xrange( 3-len( pixel_data ) )would becomexrange(3 - len(pixelData)).
- Secondly, you need whitespace between your operators. For example,
len( pixelData )/3would becomelen(pixel_data) / 3.
- Your naming violates the official style guidelines from PEP8. Variables and functions should be in
snake_case, and classes should be inPascalCase.
- Never use
exceptwithout knowing which specific error to catch. There could easily be an error that goes un-noticed because you weren't trying to catch a specific error.
-
Finally, the code below the comment
#Store pixel info, in the function read, can be shortened to this:rawData = [[pixels[rgb] for rgb in xrange(3)] for pixels in imageInput.getdata()]Code Snippets
rawData = [[pixels[rgb] for rgb in xrange(3)] for pixels in imageInput.getdata()]Context
StackExchange Code Review Q#83423, answer score: 7
Revisions (0)
No revisions yet.