Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 17 additions & 17 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,11 @@ repos:
- id: check-symlinks
- id: check-added-large-files

- repo: https://github.com/myint/docformatter
rev: v1.4
hooks:
- id: docformatter

- repo: https://github.com/myint/rstcheck
rev: '3f92957478422df87bd730abde66f089cc1ee19b'
- repo: https://gitlab.com/PyCQA/flake8
rev: 3.9.0
hooks:
- id: rstcheck
args: [
"--report", "warning",
"--ignore-roles", "class",
"--ignore-directives", "autoclass,automodule",
]
- id: flake8
args: ["--max-line-length=150"]

- repo: https://github.com/pre-commit/mirrors-autopep8
rev: v1.5.6
Expand All @@ -48,8 +39,17 @@ repos:
"--ignore", "E226,E24,W50,W690,E402"
]

- repo: https://github.com/PyCQA/flake8
rev: 3.9.0
- repo: https://github.com/myint/docformatter
rev: v1.4
hooks:
- id: flake8
args: ["--max-line-length=150"]
- id: docformatter

- repo: https://github.com/myint/rstcheck
rev: '3f92957478422df87bd730abde66f089cc1ee19b'
hooks:
- id: rstcheck
args: [
"--report", "warning",
"--ignore-roles", "class",
"--ignore-directives", "autoclass,automodule",
]
9 changes: 6 additions & 3 deletions pitop/camera/camera.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
FrameHandler,
CameraTypes)
from .core.capture_actions import CaptureActions
from pitop.core import ImageFunctions
from pitop.core.functions import (
image_format_check,
image_convert,
)
from pitop.core.mixins import (
Stateful,
Recreatable,
Expand Down Expand Up @@ -95,7 +98,7 @@ def format(self):

@format.setter
def format(self, format_value):
ImageFunctions.image_format_check(format_value)
image_format_check(format_value)
self._format = format_value.lower()

@classmethod
Expand Down Expand Up @@ -251,7 +254,7 @@ def __get_processed_current_frame(self):
image = self.__frame_handler.frame

if self.format.lower() == "opencv":
image = ImageFunctions.convert(image, format="opencv")
image = image_convert(image, format="opencv")

return image

Expand Down
4 changes: 2 additions & 2 deletions pitop/camera/core/cameras/file_system_camera.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
from pitop.core import ImageFunctions
from pitop.core.functions import get_pil_image_from_path
import os


class FsImage:
def __init__(self, path: str):
self.path = path
self.data = ImageFunctions.get_pil_image_from_path(self.path)
self.data = get_pil_image_from_path(self.path)
if self.data is None:
raise AttributeError(f"Couldn't load image {path}")

Expand Down
4 changes: 2 additions & 2 deletions pitop/camera/core/capture_actions/generic_action.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from .capture_action_base import CaptureActionBase

from pitop.core import ImageFunctions
from pitop.core.functions import image_convert

from concurrent.futures import ThreadPoolExecutor
from inspect import signature
Expand Down Expand Up @@ -29,7 +29,7 @@ def __del__(self):

def process(self, frame):
if isinstance(self.__format, str) and self.__format.lower() == 'opencv':
frame = ImageFunctions.convert(frame, format="opencv")
frame = image_convert(frame, format="opencv")

if self.__elapsed_frames % self.__frame_interval == 0:
if self.callback_has_argument:
Expand Down
65 changes: 0 additions & 65 deletions pitop/core/ImageFunctions.py

This file was deleted.

125 changes: 125 additions & 0 deletions pitop/core/functions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
from numpy import (
asarray,
ndarray,
)
from PIL import Image, ImageFont
from re import split
from urllib.request import urlopen

from pitopcommon.formatting import is_url


def get_text_size(font_filename, font_size, text):
return ImageFont.truetype(font_filename, font_size).getsize(text)


def get_word_wrapped_text(text, font_filename, font_size, max_width):
# Push and pop each line to stack
output_text = list()

# TODO: add height support
remaining = max_width

# Split up text based on all whitespace
for field in split(r'(\s+)', text):
# Get text size
field_width, field_height = get_text_size(font_filename, font_size, str(field))
if field_width > remaining:
# Update remaining width
remaining = max_width - field_width

# Not enough space to add to current line - start new one
output_text.append(field)
else:
# Update remaining width
remaining = remaining - field_width

# Is enough space
if not output_text:
# First time - just append
output_text.append(field)
else:
# Pop latest line from list
# Append the field with a space
# Add back to list
output_text.append(output_text.pop() + f" {field}")

return "\n".join(output_text)


def get_font_size(text, font_filename, word_wrap, max_width=None, max_height=None):
if max_width is None and max_height is None:
raise ValueError('You need to pass max_width or max_height')

font_size = 1
text_width, text_height = get_text_size(font_filename, font_size, text)

if (max_width is not None and text_width > max_width) or \
(max_height is not None and text_height > max_height):
raise ValueError("Text can't be filled in only (%dpx, %dpx)" % (text_width, text_height))

# Increase font size until width or height exceeds box
# TODO: add word wrapping
while True:
if (max_width is not None and text_width >= max_width) or \
(max_height is not None and text_height >= max_height):
return font_size - 1
font_size += 1
text_width, text_height = get_text_size(font_filename, font_size, text)


def image_format_check(format):
assert isinstance(format, str)
assert format.lower() in ("pil", "opencv")


def image_convert(image, format="PIL"):

try:
from cv2 import (
cvtColor,
COLOR_BGR2RGB,
COLOR_RGB2BGR,
)
except (ImportError, ModuleNotFoundError):
raise ModuleNotFoundError(
"OpenCV Python library is not installed. You can install it by running 'sudo apt install python3-opencv libatlas-base-dev'.") from None

image_format_check(format)
format = format.lower()

# Image type is already correct - return image
if any([
isinstance(image, Image.Image) and format == "pil",
isinstance(image, ndarray) and format == "opencv"
]):
return image
elif isinstance(image, Image.Image) and format == "opencv":
# Convert PIL to OpenCV
cv_image = asarray(image)
if image.mode == "RGB":
cv_image = cvtColor(cv_image, COLOR_RGB2BGR)
return cv_image
elif isinstance(image, ndarray) and format == "pil":
# Convert OpenCV to PIL
if len(image.shape) > 2 and image.shape[2] == 3:
# If incoming image has 3 channels, convert from BGR to RGB
image = cvtColor(image, COLOR_BGR2RGB)
return Image.fromarray(image)


def get_pil_image_from_path(file_path_or_url):
if is_url(file_path_or_url):
image_path = urlopen(file_path_or_url)
else:
image_path = file_path_or_url

image = Image.open(image_path)

# Verify on deep copy to avoid needing to close and
# re-open after verifying...
test_image = image.copy()
# Raise exception if there's an issue with the image
test_image.verify()

return image
Loading