mirror of
https://github.com/dnet/pySSTV.git
synced 2026-01-08 01:29:59 +01:00
moved implementation classes to separate modules
This commit is contained in:
parent
e0c95dc8c9
commit
c994e2bb2d
65
color.py
Normal file
65
color.py
Normal file
|
|
@ -0,0 +1,65 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
from __future__ import division
|
||||||
|
from sstv import FREQ_BLACK, FREQ_RANGE, FREQ_SYNC
|
||||||
|
from grayscale import GrayscaleSSTV
|
||||||
|
|
||||||
|
class ColorSSTV(GrayscaleSSTV):
|
||||||
|
RED, GREEN, BLUE = range(3)
|
||||||
|
|
||||||
|
def encode_line(self, line):
|
||||||
|
cs = self.COLOR_SEQ
|
||||||
|
msec_pixel = self.SCAN / self.WIDTH
|
||||||
|
image = self.image
|
||||||
|
for index in cs:
|
||||||
|
for item in self.before_channel(index):
|
||||||
|
yield item
|
||||||
|
for col in xrange(self.WIDTH):
|
||||||
|
pixel = image.getpixel((col, line))
|
||||||
|
value = pixel[index]
|
||||||
|
freq_pixel = FREQ_BLACK + FREQ_RANGE * value / 255
|
||||||
|
yield freq_pixel, msec_pixel
|
||||||
|
|
||||||
|
def before_channel(self, index):
|
||||||
|
return []
|
||||||
|
|
||||||
|
|
||||||
|
class MartinM1(ColorSSTV):
|
||||||
|
COLOR_SEQ = (ColorSSTV.GREEN, ColorSSTV.BLUE, ColorSSTV.RED)
|
||||||
|
VIS_CODE = 0x2c
|
||||||
|
WIDTH = 320
|
||||||
|
HEIGHT = 256
|
||||||
|
SYNC = 4.862
|
||||||
|
SCAN = 146.432
|
||||||
|
INTER_CH_GAP = 0.572
|
||||||
|
|
||||||
|
def before_channel(self, index):
|
||||||
|
if index != ColorSSTV.GREEN:
|
||||||
|
yield FREQ_BLACK, self.INTER_CH_GAP
|
||||||
|
|
||||||
|
|
||||||
|
class MartinM2(MartinM1):
|
||||||
|
VIS_CODE = 0x28
|
||||||
|
WIDTH = 160
|
||||||
|
SCAN = 73.216
|
||||||
|
|
||||||
|
|
||||||
|
class ScottieS1(MartinM1):
|
||||||
|
VIS_CODE = 0x3c
|
||||||
|
SYNC = 9
|
||||||
|
SCAN = 138.24
|
||||||
|
INTER_CH_GAP = 1.5
|
||||||
|
|
||||||
|
def horizontal_sync(self):
|
||||||
|
return []
|
||||||
|
|
||||||
|
def before_channel(self, index):
|
||||||
|
if index != ColorSSTV.RED:
|
||||||
|
yield FREQ_SYNC, self.SYNC
|
||||||
|
yield FREQ_BLACK, self.INTER_CH_GAP
|
||||||
|
|
||||||
|
|
||||||
|
class ScottieS2(ScottieS1):
|
||||||
|
VIS_CODE = 0x38
|
||||||
|
SCAN = 88.064
|
||||||
|
WIDTH = 160
|
||||||
42
grayscale.py
Normal file
42
grayscale.py
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
from __future__ import division
|
||||||
|
from sstv import FREQ_BLACK, FREQ_RANGE, FREQ_SYNC, SSTV
|
||||||
|
|
||||||
|
class GrayscaleSSTV(SSTV):
|
||||||
|
def gen_freq_bits(self):
|
||||||
|
for item in SSTV.gen_freq_bits(self):
|
||||||
|
yield item
|
||||||
|
for line in xrange(self.HEIGHT):
|
||||||
|
for item in self.horizontal_sync():
|
||||||
|
yield item
|
||||||
|
for item in self.encode_line(line):
|
||||||
|
yield item
|
||||||
|
|
||||||
|
def horizontal_sync(self):
|
||||||
|
yield FREQ_SYNC, self.SYNC
|
||||||
|
|
||||||
|
def encode_line(self, line):
|
||||||
|
msec_pixel = self.SCAN / self.WIDTH
|
||||||
|
image = self.image
|
||||||
|
for col in xrange(self.WIDTH):
|
||||||
|
pixel = image.getpixel((col, line))
|
||||||
|
value = sum(pixel) / len(pixel)
|
||||||
|
freq_pixel = FREQ_BLACK + FREQ_RANGE * value / 255
|
||||||
|
yield freq_pixel, msec_pixel
|
||||||
|
|
||||||
|
|
||||||
|
class Robot8BW(GrayscaleSSTV):
|
||||||
|
VIS_CODE = 0x02
|
||||||
|
WIDTH = 160
|
||||||
|
HEIGHT = 120
|
||||||
|
SYNC = 10
|
||||||
|
SCAN = 56
|
||||||
|
|
||||||
|
|
||||||
|
class Robot24BW(GrayscaleSSTV):
|
||||||
|
VIS_CODE = 0x0A
|
||||||
|
WIDTH = 320
|
||||||
|
HEIGHT = 240
|
||||||
|
SYNC = 12
|
||||||
|
SCAN = 93
|
||||||
101
sstv.py
101
sstv.py
|
|
@ -84,108 +84,9 @@ class SSTV(object):
|
||||||
yield FREQ_SYNC, MSEC_VIS_BIT # stop bit
|
yield FREQ_SYNC, MSEC_VIS_BIT # stop bit
|
||||||
|
|
||||||
|
|
||||||
class GrayscaleSSTV(SSTV):
|
|
||||||
def gen_freq_bits(self):
|
|
||||||
for item in SSTV.gen_freq_bits(self):
|
|
||||||
yield item
|
|
||||||
for line in xrange(self.HEIGHT):
|
|
||||||
for item in self.horizontal_sync():
|
|
||||||
yield item
|
|
||||||
for item in self.encode_line(line):
|
|
||||||
yield item
|
|
||||||
|
|
||||||
def horizontal_sync(self):
|
|
||||||
yield FREQ_SYNC, self.SYNC
|
|
||||||
|
|
||||||
def encode_line(self, line):
|
|
||||||
msec_pixel = self.SCAN / self.WIDTH
|
|
||||||
image = self.image
|
|
||||||
for col in xrange(self.WIDTH):
|
|
||||||
pixel = image.getpixel((col, line))
|
|
||||||
value = sum(pixel) / len(pixel)
|
|
||||||
freq_pixel = FREQ_BLACK + FREQ_RANGE * value / 255
|
|
||||||
yield freq_pixel, msec_pixel
|
|
||||||
|
|
||||||
|
|
||||||
class ColorSSTV(GrayscaleSSTV):
|
|
||||||
RED, GREEN, BLUE = range(3)
|
|
||||||
|
|
||||||
def encode_line(self, line):
|
|
||||||
cs = self.COLOR_SEQ
|
|
||||||
msec_pixel = self.SCAN / self.WIDTH
|
|
||||||
image = self.image
|
|
||||||
for index in cs:
|
|
||||||
for item in self.before_channel(index):
|
|
||||||
yield item
|
|
||||||
for col in xrange(self.WIDTH):
|
|
||||||
pixel = image.getpixel((col, line))
|
|
||||||
value = pixel[index]
|
|
||||||
freq_pixel = FREQ_BLACK + FREQ_RANGE * value / 255
|
|
||||||
yield freq_pixel, msec_pixel
|
|
||||||
|
|
||||||
def before_channel(self, index):
|
|
||||||
return []
|
|
||||||
|
|
||||||
|
|
||||||
class Robot8BW(GrayscaleSSTV):
|
|
||||||
VIS_CODE = 0x02
|
|
||||||
WIDTH = 160
|
|
||||||
HEIGHT = 120
|
|
||||||
SYNC = 10
|
|
||||||
SCAN = 56
|
|
||||||
|
|
||||||
|
|
||||||
class Robot24BW(GrayscaleSSTV):
|
|
||||||
VIS_CODE = 0x0A
|
|
||||||
WIDTH = 320
|
|
||||||
HEIGHT = 240
|
|
||||||
SYNC = 12
|
|
||||||
SCAN = 93
|
|
||||||
|
|
||||||
|
|
||||||
class MartinM1(ColorSSTV):
|
|
||||||
COLOR_SEQ = (ColorSSTV.GREEN, ColorSSTV.BLUE, ColorSSTV.RED)
|
|
||||||
VIS_CODE = 0x2c
|
|
||||||
WIDTH = 320
|
|
||||||
HEIGHT = 256
|
|
||||||
SYNC = 4.862
|
|
||||||
SCAN = 146.432
|
|
||||||
INTER_CH_GAP = 0.572
|
|
||||||
|
|
||||||
def before_channel(self, index):
|
|
||||||
if index != ColorSSTV.GREEN:
|
|
||||||
yield FREQ_BLACK, self.INTER_CH_GAP
|
|
||||||
|
|
||||||
|
|
||||||
class MartinM2(MartinM1):
|
|
||||||
VIS_CODE = 0x28
|
|
||||||
WIDTH = 160
|
|
||||||
SCAN = 73.216
|
|
||||||
|
|
||||||
|
|
||||||
class ScottieS1(MartinM1):
|
|
||||||
VIS_CODE = 0x3c
|
|
||||||
SYNC = 9
|
|
||||||
SCAN = 138.24
|
|
||||||
INTER_CH_GAP = 1.5
|
|
||||||
|
|
||||||
def horizontal_sync(self):
|
|
||||||
return []
|
|
||||||
|
|
||||||
def before_channel(self, index):
|
|
||||||
if index != ColorSSTV.RED:
|
|
||||||
yield FREQ_SYNC, self.SYNC
|
|
||||||
yield FREQ_BLACK, self.INTER_CH_GAP
|
|
||||||
|
|
||||||
|
|
||||||
class ScottieS2(ScottieS1):
|
|
||||||
VIS_CODE = 0x38
|
|
||||||
SCAN = 88.064
|
|
||||||
WIDTH = 160
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
from grayscale import Robot8BW
|
||||||
image = Image.open('160x120bw.png')
|
image = Image.open('160x120bw.png')
|
||||||
s = Robot8BW(image, 48000, 16)
|
s = Robot8BW(image, 48000, 16)
|
||||||
s.write_wav('test.wav')
|
s.write_wav('test.wav')
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue