A simple image to sound conversion python script.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

122 lignes
4.3 KiB

  1. #!/usr/bin/env python
  2. from PIL import Image, ImageOps
  3. import wave, math, array, argparse, sys, timeit
  4. def parser():
  5. parser = argparse.ArgumentParser()
  6. # Specified command options and its helps message
  7. parser.add_argument ("INPUT_FILE", help="Name of the image to be converted.")
  8. parser.add_argument ("-r", "--rotate", help="Rotate image 90 degrees for more sexy spectograph looks and sound", action='store_true')
  9. parser.add_argument ("-i", "--invert", help="Invert image colors.", action='store_true')
  10. parser.add_argument ("-o", "--output", help="Name of the output wav file. Default value: out.wav).")
  11. parser.add_argument ("-b", "--bottom", help="Bottom frequency range. Default value: 200.", type=int)
  12. parser.add_argument ("-t", "--top", help="Top frequency range. Default value: 20000.", type=int)
  13. parser.add_argument ("-p", "--pixels", help="Pixels per second. Default value: 30.", type=int)
  14. parser.add_argument ("-s", "--sampling", help="Sample rate. Default value: 44100.", type=int)
  15. # Create "arguments" object based on user input
  16. arguments = parser.parse_args()
  17. # Default values
  18. min_freq = 200
  19. max_freq = 20000
  20. sample_rate = 44100
  21. pixels = 30
  22. output = "out.wav"
  23. rotate = False
  24. invert = False
  25. # Check arguments values
  26. if arguments.output:
  27. output = arguments.output
  28. if arguments.bottom:
  29. min_freq = arguments.bottom
  30. if arguments.top:
  31. max_freq = arguments.top
  32. if arguments.pixels:
  33. pixels = arguments.pixels
  34. if arguments.sampling:
  35. sample_rate = arguments.sampling
  36. if arguments.rotate:
  37. rotate = True
  38. if arguments.invert:
  39. invert = True
  40. print ("------------------------------------ Simple Image To Sound Script ------------------------------------\n")
  41. print ('Input file: %s.' % arguments.INPUT_FILE)
  42. print ('Frequency range: %d - %d.' % (min_freq, max_freq))
  43. print ('Pixels per second: %d.' % pixels)
  44. print ('Sampling rate: %d.' % sample_rate)
  45. print ('Rotate Image: %s.' % ('Yes' if rotate else 'No'))
  46. return (arguments.INPUT_FILE, output, min_freq, max_freq, pixels, sample_rate, rotate, invert)
  47. def convert (INPUT_FILE, output, min_freq, max_freq, pixels, sample_rate, rotate, invert):
  48. image = Image.open (INPUT_FILE).convert ('L')
  49. # rotate image if requested
  50. if rotate:
  51. image = image.rotate (90)
  52. # invert image if requested
  53. if invert:
  54. image = ImageOps.invert (image)
  55. output = wave.open (output, 'w')
  56. output.setparams ((1, 2, sample_rate, 0, 'NONE', 'not compressed'))
  57. freq_range = max_freq - min_freq
  58. interval = freq_range / image.size[1]
  59. samples = sample_rate // pixels
  60. data = array.array ('h')
  61. # Converting process start
  62. time_start = timeit.default_timer()
  63. for x in range (image.size[0]):
  64. row = []
  65. for y in range (image.size[1]):
  66. yinv = image.size[1] - y - 1
  67. amplitude = image.getpixel ((x,y))
  68. if (amplitude > 0):
  69. row.append (gen_wave (yinv * interval + min_freq, amplitude, samples, sample_rate))
  70. for i in range(samples):
  71. for j in row:
  72. try:
  73. data[i + x * samples] += j[i]
  74. except (IndexError):
  75. data.insert (i + x * samples, j[i])
  76. except (OverflowError):
  77. if j[i] > 0:
  78. data[i + x * samples] = 32767
  79. else:
  80. data[i + x * samples] = -32768
  81. sys.stdout.write ("Conversion progress: %d%% \r" % (float(x) / image.size[0] * 100))
  82. sys.stdout.flush()
  83. output.writeframes (data.tobytes())
  84. output.close()
  85. # Converting process end
  86. time_end = timeit.default_timer()
  87. print ("Conversion progress: 100%")
  88. print ("Success. Completed in %d seconds." % int(time_end - time_start))
  89. def gen_wave (frequency, amplitude, samples, sample_rate):
  90. cycles = samples * frequency / sample_rate
  91. wave = []
  92. for i in range(samples):
  93. x = math.sin (float (cycles) * 2 * math.pi * i / float (samples)) * float (amplitude)
  94. wave.append (int (math.floor (x)))
  95. return wave
  96. if __name__ == '__main__':
  97. input_choice = parser()
  98. convert (*input_choice)