aboutsummaryrefslogtreecommitdiff
path: root/src/avp/components/image.py
diff options
context:
space:
mode:
authorBrianna Rainey2026-01-13 19:34:55 -0500
committerGitHub2026-01-13 19:34:55 -0500
commit50f5a76603a3f97f2c6f6a1d3cefea88ed3497aa (patch)
tree226fe223b31af6f217b1dd413629ab2cf26964d4 /src/avp/components/image.py
parentb8703752ffc7768b0275897b3c2a869ff41504e5 (diff)
parentf975144f25d34f97329b2d4e52891061573cea08 (diff)
Merge pull request #85 from aeliton/add-pyproject
Use pyproject.toml + uv_build
Diffstat (limited to 'src/avp/components/image.py')
-rw-r--r--src/avp/components/image.py129
1 files changed, 129 insertions, 0 deletions
diff --git a/src/avp/components/image.py b/src/avp/components/image.py
new file mode 100644
index 0000000..2393611
--- /dev/null
+++ b/src/avp/components/image.py
@@ -0,0 +1,129 @@
+from PIL import Image, ImageDraw, ImageEnhance
+from PyQt6 import QtGui, QtCore, QtWidgets
+import os
+
+from ..component import Component
+from ..toolkit.frame import BlankFrame
+
+
+class Component(Component):
+ name = "Image"
+ version = "1.0.1"
+
+ def widget(self, *args):
+ super().widget(*args)
+ self.page.pushButton_image.clicked.connect(self.pickImage)
+ self.trackWidgets(
+ {
+ "imagePath": self.page.lineEdit_image,
+ "scale": self.page.spinBox_scale,
+ "stretchScale": self.page.spinBox_scale_stretch,
+ "rotate": self.page.spinBox_rotate,
+ "color": self.page.spinBox_color,
+ "xPosition": self.page.spinBox_x,
+ "yPosition": self.page.spinBox_y,
+ "stretched": self.page.checkBox_stretch,
+ "mirror": self.page.checkBox_mirror,
+ },
+ presetNames={
+ "imagePath": "image",
+ "xPosition": "x",
+ "yPosition": "y",
+ },
+ relativeWidgets=["xPosition", "yPosition", "scale"],
+ )
+
+ def previewRender(self):
+ return self.drawFrame(self.width, self.height)
+
+ def properties(self):
+ props = ["static"]
+ if not os.path.exists(self.imagePath):
+ props.append("error")
+ return props
+
+ def error(self):
+ if not self.imagePath:
+ return "There is no image selected."
+ if not os.path.exists(self.imagePath):
+ return "The image selected does not exist!"
+
+ def frameRender(self, frameNo):
+ return self.drawFrame(self.width, self.height)
+
+ def drawFrame(self, width, height):
+ frame = BlankFrame(width, height)
+ if self.imagePath and os.path.exists(self.imagePath):
+ scale = self.scale if not self.stretched else self.stretchScale
+ image = Image.open(self.imagePath)
+
+ # Modify image's appearance
+ if self.color != 100:
+ image = ImageEnhance.Color(image).enhance(float(self.color / 100))
+ if self.mirror:
+ image = image.transpose(Image.Transpose.FLIP_LEFT_RIGHT)
+ if self.stretched and image.size != (width, height):
+ image = image.resize((width, height), Image.Resampling.LANCZOS)
+ if scale != 100:
+ newHeight = int((image.height / 100) * scale)
+ newWidth = int((image.width / 100) * scale)
+ image = image.resize((newWidth, newHeight), Image.Resampling.LANCZOS)
+
+ # Paste image at correct position
+ frame.paste(image, box=(self.xPosition, self.yPosition))
+ if self.rotate != 0:
+ frame = frame.rotate(self.rotate)
+
+ return frame
+
+ def pickImage(self):
+ imgDir = self.settings.value("componentDir", os.path.expanduser("~"))
+ filename, _ = QtWidgets.QFileDialog.getOpenFileName(
+ self.page,
+ "Choose Image",
+ imgDir,
+ "Image Files (%s)" % " ".join(self.core.imageFormats),
+ )
+ if filename:
+ self.settings.setValue("componentDir", os.path.dirname(filename))
+ self.mergeUndo = False
+ self.page.lineEdit_image.setText(filename)
+ self.mergeUndo = True
+
+ def command(self, arg):
+ if "=" in arg:
+ key, arg = arg.split("=", 1)
+ if key == "path" and os.path.exists(arg):
+ try:
+ Image.open(arg)
+ self.page.lineEdit_image.setText(arg)
+ self.page.checkBox_stretch.setChecked(True)
+ return
+ except OSError as e:
+ print("Not a supported image format")
+ quit(1)
+ super().command(arg)
+
+ def commandHelp(self):
+ print("Load an image:\n path=/filepath/to/image.png")
+
+ def savePreset(self):
+ # Maintain the illusion that the scale spinbox is one widget
+ scaleBox = self.page.spinBox_scale
+ stretchScaleBox = self.page.spinBox_scale_stretch
+ if self.page.checkBox_stretch.isChecked():
+ scaleBox.setValue(stretchScaleBox.value())
+ else:
+ stretchScaleBox.setValue(scaleBox.value())
+ return super().savePreset()
+
+ def update(self):
+ # Maintain the illusion that the scale spinbox is one widget
+ scaleBox = self.page.spinBox_scale
+ stretchScaleBox = self.page.spinBox_scale_stretch
+ if self.page.checkBox_stretch.isChecked():
+ scaleBox.setVisible(False)
+ stretchScaleBox.setVisible(True)
+ else:
+ scaleBox.setVisible(True)
+ stretchScaleBox.setVisible(False)