Reputation: 71
I have Pillow 2.4.0 installed (both in a virtual env on OS X and on a Ubuntu 14.04 EC2). I wrote the following script to generate a visualization of a waveform (drawing some inspiration from Jiaaro). It uses the Pydub library to analyze the waveform and the ImageDraw function from PIL/Pillow to draw the lines. The wav variable is an audiosegment() (from the Pydub library), imgname is a string:
def draw_waveform(wav, imgname, color="#000000", w=400, h=40):
sound = wav
name = imgname
width = w
height = h
color = color
chunk_length = len(sound) / width
loudness_of_chunks = [
sound[ i*chunk_length : (i+1)*chunk_length ].rms
for i in range(width)]
max_rms = max(loudness_of_chunks)
scale = max_rms/(height/2)
size = (width,height)
im = Image.new('RGBA', size, (255, 255, 255, 255))
draw = ImageDraw.Draw(im)
for i in range(1, width):
pos = (width - i, height/2 + loudness_of_chunks[i]/scale-4)
draw.line((width - i,height/2) + pos, fill=color)
pos = (width - i, height/2 - loudness_of_chunks[i]/scale+4)
draw.line((width - i,height/2) + pos, fill=color)
del draw
im.rotate(180).save(app.config['UPLOAD_FOLDER'] + '/' + name, 'GIF', transparency=0) #, transparency=0
return app.config['UPLOAD_FOLDER'] + '/' + name
All's groovy, most of the time. On some waveforms, particularly, it seems, the ones that are closest to peaking, PIL will output a GIF that has flipped transparency - the waveform will be transparent and the space around it will be white. Normally the background's transparent and the waveform is black (#000000).
Here is a picture of the expected output:
And the incorrect (right click save-as and open in an image editor, as its background is white and the middle is transparent):
Has anyone experienced a similar issue? Am I missing something obvious (likely)?
Upvotes: 4
Views: 1179
Reputation: 71
Turns out this is simpler than I imagined it to be (surprise surprise). Thanks to @MarkRansom for inspiration here.
Instantiate the image with 'P' rather than 'RGBA',
im = Image.new('P', size, 255)
Define your color (for black, 0)
color=0
Ensure that the save call defines the white area as transparent rather than the black:
im.save(name, 'GIF', transparency=255)
Still a little curious why it would only fail some of the time with the original code...
Upvotes: 3