From 3a6d7ae421ad2b650cac7f17d43be313787f0e61 Mon Sep 17 00:00:00 2001 From: tassaron Date: Sun, 2 Jul 2017 21:38:19 -0400 Subject: frame-drawing tools for components to share --- src/component.py | 10 ++++------ src/components/color.py | 27 +++++++++++++-------------- src/components/image.py | 3 ++- src/components/original.py | 5 +++-- src/components/text.py | 23 +++++++---------------- src/components/video.py | 9 +++++---- src/frame.py | 42 ++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 76 insertions(+), 43 deletions(-) create mode 100644 src/frame.py diff --git a/src/component.py b/src/component.py index b5e7d93..6637eac 100644 --- a/src/component.py +++ b/src/component.py @@ -1,11 +1,12 @@ +''' + Base classes for components to import. +''' from PyQt5 import uic, QtCore, QtWidgets -from PIL import Image import os class Component(QtCore.QObject): - '''A base class for components to inherit from''' - + ''' A class for components to inherit.''' # modified = QtCore.pyqtSignal(int, bool) def __init__(self, moduleIndex, compPos, core): @@ -82,9 +83,6 @@ class Component(QtCore.QObject): def commandHelp(self): '''Print help text for this Component's commandline arguments''' - def blankFrame(self, width, height): - return Image.new("RGBA", (width, height), (0, 0, 0, 0)) - def pickColor(self): '''Use color picker to get color input from the user, and return this as an RGB string and QPushButton stylesheet. diff --git a/src/components/color.py b/src/components/color.py index bd45951..4a10263 100644 --- a/src/components/color.py +++ b/src/components/color.py @@ -5,6 +5,7 @@ from PIL.ImageQt import ImageQt import os from component import Component +from frame import BlankFrame, FloodFrame, FramePainter, PaintColor class Component(Component): @@ -128,20 +129,19 @@ class Component(Component): # in default state, skip all this logic and return a plain fill if self.fillType == 0 and shapeSize == (width, height) \ and self.x == 0 and self.y == 0: - return Image.new("RGBA", (width, height), (r, g, b, 255)) - - frame = self.blankFrame(width, height) + return FloodFrame(width, height, (r, g, b, 255)) # Return a solid image at x, y if self.fillType == 0: + frame = BlankFrame(width, height) image = Image.new("RGBA", shapeSize, (r, g, b, 255)) frame.paste(image, box=(self.x, self.y)) return frame # Now fills that require using Qt... elif self.fillType > 0: - image = ImageQt(frame) - painter = QtGui.QPainter(image) + image = FramePainter(width, height) + if self.stretch: w = width h = height @@ -164,21 +164,20 @@ class Component(Component): self.RG_centre) brush.setSpread(self.spread) - brush.setColorAt(0.0, QColor(*self.color1)) + brush.setColorAt(0.0, PaintColor(*self.color1)) if self.trans: - brush.setColorAt(1.0, QColor(0, 0, 0, 0)) + brush.setColorAt(1.0, PaintColor(0, 0, 0, 0)) elif self.fillType == 1 and self.stretch: - brush.setColorAt(0.2, QColor(*self.color2)) + brush.setColorAt(0.2, PaintColor(*self.color2)) else: - brush.setColorAt(1.0, QColor(*self.color2)) - painter.setBrush(brush) - painter.drawRect( + brush.setColorAt(1.0, PaintColor(*self.color2)) + image.setBrush(brush) + image.drawRect( self.x, self.y, self.sizeWidth, self.sizeHeight ) - painter.end() - imBytes = image.bits().asstring(image.byteCount()) - return Image.frombytes('RGBA', (width, height), imBytes) + + return image.finalize() def loadPreset(self, pr, presetName=None): super().loadPreset(pr, presetName) diff --git a/src/components/image.py b/src/components/image.py index ba99113..1aae51b 100644 --- a/src/components/image.py +++ b/src/components/image.py @@ -3,6 +3,7 @@ from PyQt5 import QtGui, QtCore, QtWidgets import os from component import Component +from frame import BlankFrame class Component(Component): @@ -53,7 +54,7 @@ class Component(Component): return self.drawFrame(width, height) def drawFrame(self, width, height): - frame = self.blankFrame(width, height) + frame = BlankFrame(width, height) if self.imagePath and os.path.exists(self.imagePath): image = Image.open(self.imagePath) if self.stretched and image.size != (width, height): diff --git a/src/components/original.py b/src/components/original.py index 42049f3..82cdc1d 100644 --- a/src/components/original.py +++ b/src/components/original.py @@ -7,6 +7,7 @@ import time from copy import copy from component import Component +from frame import BlankFrame class Component(Component): @@ -162,7 +163,7 @@ class Component(Component): bF = width / 64 bH = bF / 2 bQ = bF / 4 - imTop = self.blankFrame(width, height) + imTop = BlankFrame(width, height) draw = ImageDraw.Draw(imTop) r, g, b = color color2 = (r, g, b, 125) @@ -180,7 +181,7 @@ class Component(Component): imBottom = imTop.transpose(Image.FLIP_TOP_BOTTOM) - im = self.blankFrame(width, height) + im = BlankFrame(width, height) if layout == 0: # Classic y = self.y - int(height/100*43) diff --git a/src/components/text.py b/src/components/text.py index 6be3120..97d7d07 100644 --- a/src/components/text.py +++ b/src/components/text.py @@ -1,11 +1,10 @@ from PIL import Image, ImageDraw -from PyQt5.QtGui import QPainter, QColor, QFont +from PyQt5.QtGui import QColor, QFont from PyQt5 import QtGui, QtCore, QtWidgets -from PIL.ImageQt import ImageQt import os -import sys from component import Component +from frame import FramePainter class Component(Component): @@ -131,22 +130,14 @@ class Component(Component): def addText(self, width, height): x, y = self.getXY() - im = self.blankFrame(width, height) - image = ImageQt(im) + image = FramePainter(width, height) - painter = QPainter(image) self.titleFont.setPixelSize(self.fontSize) - painter.setFont(self.titleFont) - if sys.byteorder == 'big': - painter.setPen(QColor(*self.textColor)) - else: - painter.setPen(QColor(*self.textColor[::-1])) - painter.drawText(x, y, self.title) - painter.end() + image.setFont(self.titleFont) + image.setPen(self.textColor) + image.drawText(x, y, self.title) - imBytes = image.bits().asstring(image.byteCount()) - - return Image.frombytes('RGBA', (width, height), imBytes) + return image.finalize() def pickColor(self): RGBstring, btnStyle = super().pickColor() diff --git a/src/components/video.py b/src/components/video.py index c5649c5..175cf29 100644 --- a/src/components/video.py +++ b/src/components/video.py @@ -7,6 +7,7 @@ import threading from queue import PriorityQueue from component import Component, BadComponentInit +from frame import BlankFrame class Video: @@ -145,7 +146,7 @@ class Component(Component): self.updateChunksize(width, height) frame = self.getPreviewFrame(width, height) if not frame: - return self.blankFrame(width, height) + return BlankFrame(width, height) else: return frame @@ -153,7 +154,7 @@ class Component(Component): super().preFrameRender(**kwargs) width = int(self.worker.core.settings.value('outputWidth')) height = int(self.worker.core.settings.value('outputHeight')) - self.blankFrame_ = self.blankFrame(width, height) + self.blankFrame_ = BlankFrame(width, height) self.updateChunksize(width, height) self.video = Video( ffmpeg=self.parent.core.FFMPEG_BIN, videoPath=self.videoPath, @@ -279,11 +280,11 @@ def finalizeFrame(self, imageData, width, height): '### BAD VIDEO SELECTED ###\n' 'Video will not export with these settings' ) - return self.blankFrame(width, height) + return BlankFrame(width, height) if self.scale != 100 \ or self.xPosition != 0 or self.yPosition != 0: - frame = self.blankFrame(width, height) + frame = BlankFrame(width, height) frame.paste(image, box=(self.xPosition, self.yPosition)) else: frame = image diff --git a/src/frame.py b/src/frame.py new file mode 100644 index 0000000..6d6d299 --- /dev/null +++ b/src/frame.py @@ -0,0 +1,42 @@ +''' + Common tools for drawing compatible frames in a Component's frameRender() +''' +from PyQt5 import QtGui +from PIL import Image +from PIL.ImageQt import ImageQt +import sys + + +class FramePainter(QtGui.QPainter): + def __init__(self, width, height): + image = BlankFrame(width, height) + self.image = ImageQt(image) + super().__init__(self.image) + + def setPen(self, RgbTuple): + if sys.byteorder == 'big': + color = QtGui.QColor(*RgbTuple) + else: + color = QtGui.QColor(*RgbTuple[::-1]) + super().setPen(QtGui.QColor(color)) + + def finalize(self): + self.end() + imBytes = self.image.bits().asstring(self.image.byteCount()) + + return Image.frombytes( + 'RGBA', (self.image.width(), self.image.height()), imBytes + ) + +class PaintColor(QtGui.QColor): + def __init__(self, r, g, b, a=255): + if sys.byteorder == 'big': + super().__init__(r, g, b, a) + else: + super().__init__(b, g, r, a) + +def FloodFrame(width, height, RgbaTuple): + return Image.new("RGBA", (width, height), RgbaTuple) + +def BlankFrame(width, height): + return FloodFrame(width, height, (0, 0, 0, 0)) -- cgit v1.2.3