first commit
This commit is contained in:
commit
5e0ba19538
|
@ -0,0 +1,2 @@
|
|||
__pycache__
|
||||
settings.ini
|
|
@ -0,0 +1,135 @@
|
|||
import sys, io
|
||||
from PyQt4 import QtCore, QtGui, uic
|
||||
from PyQt4.QtGui import QPainter, QColor
|
||||
from os.path import expanduser
|
||||
import subprocess as sp
|
||||
import numpy
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
from PIL.ImageQt import ImageQt
|
||||
|
||||
class Core():
|
||||
|
||||
def __init__(self):
|
||||
self.lastBackgroundImage = ""
|
||||
self._image = None
|
||||
|
||||
if sys.platform == "win32":
|
||||
self.FFMPEG_BIN = "ffmpeg.exe"
|
||||
else:
|
||||
self.FFMPEG_BIN = "ffmpeg" # on Linux and Mac OS
|
||||
|
||||
def drawBaseImage(self, backgroundImage, titleText, titleFont):
|
||||
|
||||
if self._image == None or not self.lastBackgroundImage == backgroundImage:
|
||||
self.lastBackgroundImage = backgroundImage
|
||||
|
||||
if backgroundImage == "":
|
||||
im = Image.new("RGB", (1280, 720), "black")
|
||||
else:
|
||||
im = Image.open(backgroundImage)
|
||||
|
||||
# resize if necessary
|
||||
if not im.size == (1280, 720):
|
||||
im = im.resize((1280, 720), Image.ANTIALIAS)
|
||||
|
||||
self._image = ImageQt(im)
|
||||
|
||||
self._image1 = QtGui.QImage(self._image)
|
||||
painter = QPainter(self._image1)
|
||||
font = titleFont
|
||||
font.setPointSizeF(35)
|
||||
painter.setFont(font)
|
||||
painter.setPen(QColor(255, 255, 255))
|
||||
|
||||
painter.drawText(70, 375, titleText)
|
||||
painter.end()
|
||||
|
||||
buffer = QtCore.QBuffer()
|
||||
buffer.open(QtCore.QIODevice.ReadWrite)
|
||||
self._image1.save(buffer, "PNG")
|
||||
|
||||
strio = io.BytesIO()
|
||||
strio.write(buffer.data())
|
||||
buffer.close()
|
||||
strio.seek(0)
|
||||
return Image.open(strio)
|
||||
|
||||
def drawBars(self, spectrum, image):
|
||||
|
||||
imTop = Image.new("RGBA", (1280, 360))
|
||||
draw = ImageDraw.Draw(imTop)
|
||||
for j in range(0, 63):
|
||||
draw.rectangle((10 + j * 20, 325, 10 + j * 20 + 20, 325 - spectrum[j * 4] * 1 - 10), fill=(255, 255, 255, 50))
|
||||
draw.rectangle((15 + j * 20, 320, 15 + j * 20 + 10, 320 - spectrum[j * 4] * 1), fill="white")
|
||||
|
||||
|
||||
imBottom = imTop.transpose(Image.FLIP_TOP_BOTTOM)
|
||||
|
||||
im = Image.new("RGB", (1280, 720), "black")
|
||||
|
||||
im.paste(image, (0, 0))
|
||||
im.paste(imTop, (0, 0), mask=imTop)
|
||||
im.paste(imBottom, (0, 360), mask=imBottom)
|
||||
|
||||
return im
|
||||
|
||||
def readAudioFile(self, filename):
|
||||
command = [ self.FFMPEG_BIN,
|
||||
'-i', filename,
|
||||
'-f', 's16le',
|
||||
'-acodec', 'pcm_s16le',
|
||||
'-ar', '44100', # ouput will have 44100 Hz
|
||||
'-ac', '1', # mono (set to '2' for stereo)
|
||||
'-']
|
||||
in_pipe = sp.Popen(command, stdout=sp.PIPE, stderr=sp.DEVNULL, bufsize=10**8)
|
||||
|
||||
completeAudioArray = numpy.empty(0, dtype="int16")
|
||||
|
||||
while True:
|
||||
# read 2 seconds of audio
|
||||
raw_audio = in_pipe.stdout.read(88200*4)
|
||||
if len(raw_audio) == 0:
|
||||
break
|
||||
audio_array = numpy.fromstring(raw_audio, dtype="int16")
|
||||
completeAudioArray = numpy.append(completeAudioArray, audio_array)
|
||||
# print(audio_array)
|
||||
|
||||
in_pipe.kill()
|
||||
in_pipe.wait()
|
||||
|
||||
# add 0s the end
|
||||
completeAudioArrayCopy = numpy.zeros(len(completeAudioArray) + 44100, dtype="int16")
|
||||
completeAudioArrayCopy[:len(completeAudioArray)] = completeAudioArray
|
||||
completeAudioArray = completeAudioArrayCopy
|
||||
|
||||
return completeAudioArray
|
||||
|
||||
def transformData(self, i, completeAudioArray, sampleSize, smoothConstantDown, smoothConstantUp, lastSpectrum):
|
||||
if len(completeAudioArray) < (i + sampleSize):
|
||||
sampleSize = len(completeAudioArray) - i
|
||||
|
||||
window = numpy.hanning(sampleSize)
|
||||
data = completeAudioArray[i:i+sampleSize][::1] * window
|
||||
paddedSampleSize = 2048
|
||||
paddedData = numpy.pad(data, (0, paddedSampleSize - sampleSize), 'constant')
|
||||
spectrum = numpy.fft.fft(paddedData)
|
||||
sample_rate = 44100
|
||||
frequencies = numpy.fft.fftfreq(len(spectrum), 1./sample_rate)
|
||||
|
||||
y = abs(spectrum[0:paddedSampleSize/2 - 1])
|
||||
|
||||
# filter the noise away
|
||||
# y[y<80] = 0
|
||||
|
||||
y = 20 * numpy.log10(y)
|
||||
y[numpy.isinf(y)] = 0
|
||||
|
||||
if lastSpectrum is not None:
|
||||
lastSpectrum[y < lastSpectrum] = y[y < lastSpectrum] * smoothConstantDown + lastSpectrum[y < lastSpectrum] * (1 - smoothConstantDown)
|
||||
lastSpectrum[y >= lastSpectrum] = y[y >= lastSpectrum] * smoothConstantUp + lastSpectrum[y >= lastSpectrum] * (1 - smoothConstantUp)
|
||||
else:
|
||||
lastSpectrum = y
|
||||
|
||||
x = frequencies[0:paddedSampleSize/2 - 1]
|
||||
|
||||
return lastSpectrum
|
|
@ -0,0 +1,196 @@
|
|||
import sys, io, os
|
||||
from PyQt4 import QtCore, QtGui, uic
|
||||
from PyQt4.QtGui import QPainter, QColor, QFont
|
||||
from os.path import expanduser
|
||||
import subprocess as sp
|
||||
import numpy
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
from PIL.ImageQt import ImageQt
|
||||
import atexit
|
||||
from queue import Queue
|
||||
from PyQt4.QtCore import QSettings
|
||||
|
||||
import preview_thread, core
|
||||
|
||||
class Main(QtCore.QObject):
|
||||
|
||||
newTask = QtCore.pyqtSignal(str, str, QFont)
|
||||
processTask = QtCore.pyqtSignal()
|
||||
|
||||
def __init__(self, window):
|
||||
|
||||
QtCore.QObject.__init__(self)
|
||||
|
||||
# print('main thread id: {}'.format(QtCore.QThread.currentThreadId()))
|
||||
self.window = window
|
||||
self.core = core.Core()
|
||||
|
||||
self.settings = QSettings('settings.ini', QSettings.IniFormat)
|
||||
|
||||
self.previewQueue = Queue()
|
||||
|
||||
self.previewThread = QtCore.QThread(self)
|
||||
self.previewWorker = preview_thread.Worker(self, self.previewQueue)
|
||||
|
||||
self.previewWorker.moveToThread(self.previewThread)
|
||||
self.previewWorker.imageCreated.connect(self.showPreviewImage)
|
||||
|
||||
self.previewThread.start()
|
||||
|
||||
self.timer = QtCore.QTimer(self)
|
||||
self.timer.timeout.connect(self.processTask.emit)
|
||||
self.timer.start(500)
|
||||
|
||||
window.pushButton_selectInput.clicked.connect(self.openInputFileDialog)
|
||||
window.pushButton_selectOutput.clicked.connect(self.openOutputFileDialog)
|
||||
window.pushButton_createVideo.clicked.connect(self.createAudioVisualisation)
|
||||
window.pushButton_selectBackground.clicked.connect(self.openBackgroundFileDialog)
|
||||
|
||||
window.fontComboBox.currentFontChanged.connect(self.drawPreview)
|
||||
window.lineEdit_title.textChanged.connect(self.drawPreview)
|
||||
|
||||
window.progressBar_create.setValue(0)
|
||||
window.setWindowTitle("Audio Visualizer")
|
||||
window.pushButton_selectInput.setText("Select Input Music File")
|
||||
window.pushButton_selectOutput.setText("Select Output Video File")
|
||||
window.pushButton_selectBackground.setText("Select Background Image")
|
||||
window.label_font.setText("Title Font")
|
||||
window.label_title.setText("Title Text")
|
||||
window.pushButton_createVideo.setText("Create Video")
|
||||
window.groupBox_create.setTitle("Create")
|
||||
window.groupBox_settings.setTitle("Settings")
|
||||
window.groupBox_preview.setTitle("Preview")
|
||||
|
||||
titleFont = self.settings.value("titleFont")
|
||||
if not titleFont == None:
|
||||
window.fontComboBox.setCurrentFont(QFont(titleFont))
|
||||
|
||||
self.drawPreview()
|
||||
|
||||
window.show()
|
||||
|
||||
def cleanUp(self):
|
||||
self.timer.stop()
|
||||
self.previewThread.quit()
|
||||
self.previewThread.wait()
|
||||
|
||||
self.settings.setValue("titleFont", self.window.fontComboBox.currentFont().toString())
|
||||
|
||||
def openInputFileDialog(self):
|
||||
inputDir = self.settings.value("inputDir", expanduser("~"))
|
||||
|
||||
fileName = QtGui.QFileDialog.getOpenFileName(self.window,
|
||||
"Open Music File", inputDir, "Music Files (*.mp3 *.wav *.ogg *.flac)");
|
||||
|
||||
if not fileName == "":
|
||||
self.settings.setValue("inputDir", os.path.dirname(fileName))
|
||||
self.window.label_input.setText(fileName)
|
||||
|
||||
def openOutputFileDialog(self):
|
||||
outputDir = self.settings.value("outputDir", expanduser("~"))
|
||||
|
||||
fileName = QtGui.QFileDialog.getSaveFileName(self.window,
|
||||
"Set Output Video File", outputDir, "Video Files (*.mp4)");
|
||||
|
||||
if not fileName == "":
|
||||
self.settings.setValue("outputDir", os.path.dirname(fileName))
|
||||
self.window.label_output.setText(fileName)
|
||||
|
||||
def openBackgroundFileDialog(self):
|
||||
backgroundDir = self.settings.value("backgroundDir", expanduser("~"))
|
||||
|
||||
fileName = QtGui.QFileDialog.getOpenFileName(self.window,
|
||||
"Open Background Image", backgroundDir, "Image Files (*.jpg *.png)");
|
||||
|
||||
if not fileName == "":
|
||||
self.settings.setValue("backgroundDir", os.path.dirname(fileName))
|
||||
self.window.label_background.setText(fileName)
|
||||
self.drawPreview()
|
||||
|
||||
def createAudioVisualisation(self):
|
||||
|
||||
imBackground = self.core.drawBaseImage(
|
||||
self.window.label_background.text(),
|
||||
self.window.lineEdit_title.text(),
|
||||
self.window.fontComboBox.currentFont())
|
||||
|
||||
self.window.progressBar_create.setValue(0)
|
||||
|
||||
completeAudioArray = self.core.readAudioFile(self.window.label_input.text())
|
||||
|
||||
out_pipe = sp.Popen([ self.core.FFMPEG_BIN,
|
||||
'-y', # (optional) means overwrite the output file if it already exists.
|
||||
'-f', 'rawvideo',
|
||||
'-vcodec', 'rawvideo',
|
||||
'-s', '1280x720', # size of one frame
|
||||
'-pix_fmt', 'rgb24',
|
||||
'-r', '30', # frames per second
|
||||
'-i', '-', # The input comes from a pipe
|
||||
'-an',
|
||||
'-i', self.window.label_input.text(),
|
||||
'-acodec', "libmp3lame", # output audio codec
|
||||
self.window.label_output.text()],
|
||||
stdin=sp.PIPE,stdout=sp.DEVNULL, stderr=sp.DEVNULL)
|
||||
|
||||
smoothConstantDown = 0.08
|
||||
smoothConstantUp = 0.8
|
||||
lastSpectrum = None
|
||||
progressBarValue = 0
|
||||
sampleSize = 1470
|
||||
|
||||
numpy.seterr(divide='ignore')
|
||||
|
||||
for i in range(0, len(completeAudioArray), sampleSize):
|
||||
# create video for output
|
||||
lastSpectrum = self.core.transformData(
|
||||
i,
|
||||
completeAudioArray,
|
||||
sampleSize,
|
||||
smoothConstantDown,
|
||||
smoothConstantUp,
|
||||
lastSpectrum)
|
||||
im = self.core.drawBars(lastSpectrum, imBackground)
|
||||
|
||||
# write to out_pipe
|
||||
try:
|
||||
out_pipe.stdin.write(im.tostring())
|
||||
finally:
|
||||
True
|
||||
|
||||
# increase progress bar value
|
||||
if progressBarValue + 1 <= (i / len(completeAudioArray)) * 100:
|
||||
progressBarValue = numpy.floor((i / len(completeAudioArray)) * 100)
|
||||
self.window.progressBar_create.setValue(progressBarValue)
|
||||
|
||||
numpy.seterr(all='print')
|
||||
|
||||
out_pipe.stdin.close()
|
||||
if out_pipe.stderr is not None:
|
||||
print(out_pipe.stderr.read())
|
||||
out_pipe.stderr.close()
|
||||
out_pipe.terminate()
|
||||
out_pipe.wait()
|
||||
print("Video file created")
|
||||
self.window.progressBar_create.setValue(100)
|
||||
|
||||
def drawPreview(self):
|
||||
self.newTask.emit(self.window.label_background.text(),
|
||||
self.window.lineEdit_title.text(),
|
||||
self.window.fontComboBox.currentFont())
|
||||
# self.processTask.emit()
|
||||
|
||||
def showPreviewImage(self, image):
|
||||
self._scaledPreviewImage = image
|
||||
self._previewPixmap = QtGui.QPixmap.fromImage(self._scaledPreviewImage)
|
||||
|
||||
self.window.label_preview.setPixmap(self._previewPixmap)
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = QtGui.QApplication(sys.argv)
|
||||
window = uic.loadUi("main.ui")
|
||||
|
||||
main = Main(window)
|
||||
|
||||
atexit.register(main.cleanUp)
|
||||
|
||||
sys.exit(app.exec_())
|
|
@ -0,0 +1,312 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>635</width>
|
||||
<height>610</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>MainWindow</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_settings">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>200</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>200</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>GroupBox</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_selectInput">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>PushButton</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_input">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Box</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_selectOutput">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>PushButton</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_output">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Box</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_selectBackground">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>PushButton</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_background">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Box</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_font">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="baseSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFontComboBox" name="fontComboBox"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_title">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="baseSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEdit_title"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
<zorder>verticalLayoutWidget_2</zorder>
|
||||
<zorder>layoutWidget_2</zorder>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_preview">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>220</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>220</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>GroupBox</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_preview">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>320</width>
|
||||
<height>180</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>320</width>
|
||||
<height>180</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Box</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_create">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>100</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>GroupBox</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_7">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="QProgressBar" name="progressBar_create">
|
||||
<property name="value">
|
||||
<number>24</number>
|
||||
</property>
|
||||
<property name="textVisible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_createVideo">
|
||||
<property name="text">
|
||||
<string>PushButton</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -0,0 +1,58 @@
|
|||
from PyQt4 import QtCore, QtGui, uic
|
||||
from PyQt4.QtCore import pyqtSignal, pyqtSlot
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
from PIL.ImageQt import ImageQt
|
||||
import core
|
||||
import time
|
||||
from queue import Queue, Empty
|
||||
import numpy
|
||||
|
||||
class Worker(QtCore.QObject):
|
||||
|
||||
imageCreated = pyqtSignal(['QImage'])
|
||||
|
||||
def __init__(self, parent=None, queue=None):
|
||||
QtCore.QObject.__init__(self)
|
||||
parent.newTask.connect(self.createPreviewImage)
|
||||
parent.processTask.connect(self.process)
|
||||
self.core = core.Core()
|
||||
self.queue = queue
|
||||
|
||||
|
||||
@pyqtSlot(str, str, QtGui.QFont)
|
||||
def createPreviewImage(self, backgroundImage, titleText, titleFont):
|
||||
# print('worker thread id: {}'.format(QtCore.QThread.currentThreadId()))
|
||||
dic = {
|
||||
"backgroundImage": backgroundImage,
|
||||
"titleText": titleText,
|
||||
"titleFont": titleFont
|
||||
}
|
||||
self.queue.put(dic)
|
||||
|
||||
@pyqtSlot()
|
||||
def process(self):
|
||||
try:
|
||||
nextPreviewInformation = self.queue.get(block=False)
|
||||
while self.queue.qsize() >= 2:
|
||||
try:
|
||||
self.queue.get(block=False)
|
||||
except Empty:
|
||||
continue
|
||||
|
||||
im = self.core.drawBaseImage(
|
||||
nextPreviewInformation["backgroundImage"],
|
||||
nextPreviewInformation["titleText"],
|
||||
nextPreviewInformation["titleFont"])
|
||||
|
||||
spectrum = numpy.fromfunction(lambda x: 0.008*(x-128)**2, (255,), dtype="int16")
|
||||
|
||||
im = self.core.drawBars(spectrum, im)
|
||||
|
||||
self._image = ImageQt(im)
|
||||
self._previewImage = QtGui.QImage(self._image)
|
||||
|
||||
self._scaledPreviewImage = self._previewImage.scaled(320, 180, QtCore.Qt.IgnoreAspectRatio, QtCore.Qt.SmoothTransformation)
|
||||
|
||||
self.imageCreated.emit(self._scaledPreviewImage)
|
||||
except Empty:
|
||||
True
|
Reference in New Issue