diff --git a/.github/test/Dockerfile-alpine b/.github/test/Dockerfile-alpine index c037dc6c..44fc34d2 100644 --- a/.github/test/Dockerfile-alpine +++ b/.github/test/Dockerfile-alpine @@ -27,7 +27,12 @@ RUN \ file \ nodejs \ poppler-utils \ - python3 && \ + python3 \ + # OpenCV dependencies for image processing + glib \ + libsm \ + libxext \ + libxrender && \ echo "**** pip3 install test of changedetection.io ****" && \ python3 -m venv /lsiopy && \ pip install -U pip wheel setuptools && \ diff --git a/Dockerfile b/Dockerfile index 144f5b4e..c4877b39 100644 --- a/Dockerfile +++ b/Dockerfile @@ -43,6 +43,11 @@ RUN --mount=type=cache,id=pip,sharing=locked,target=/tmp/pip-cache \ --cache-dir=/tmp/pip-cache \ -r /requirements.txt +# Copy installed packages from system Python to /dependencies for final image +ARG PYTHON_VERSION +RUN mkdir -p /dependencies && \ + cp -r /usr/local/lib/python${PYTHON_VERSION}/site-packages/* /dependencies/ + # Playwright is an alternative to Selenium # Excluded this package from requirements.txt to prevent arm/v6 and arm/v7 builds from failing diff --git a/changedetectionio/processors/image_ssim_diff/difference.py b/changedetectionio/processors/image_ssim_diff/difference.py index feba8d2b..7adbd753 100644 --- a/changedetectionio/processors/image_ssim_diff/difference.py +++ b/changedetectionio/processors/image_ssim_diff/difference.py @@ -241,9 +241,9 @@ def generate_diff_image_opencv(img_bytes_to, diff_mask): # Convert back to PIL Image diff_img = Image.fromarray(result_array.astype(np.uint8)) - # Save to bytes as PNG (faster rendering than JPEG for diff images) + # Save to bytes as JPEG (smaller and faster than PNG for diff visualization) buf = io.BytesIO() - diff_img.save(buf, format='PNG', optimize=True) + diff_img.save(buf, format='JPEG', quality=85, optimize=True) diff_bytes = buf.getvalue() # Explicit memory cleanup - close files and buffers, delete large objects @@ -264,14 +264,17 @@ def generate_diff_image_pixelmatch(diff_array): diff_array: RGBA diff array from pixelmatch (4D numpy array) Returns: - bytes: PNG image with highlighted differences + bytes: JPEG image with highlighted differences """ - # Convert diff array to PIL Image + # Convert diff array to PIL Image (RGBA) diff_img = Image.fromarray(diff_array.astype(np.uint8), mode='RGBA') - # Save to bytes as PNG + # Convert RGBA to RGB for JPEG (JPEG doesn't support transparency) + diff_img = diff_img.convert('RGB') + + # Save to bytes as JPEG (smaller and faster than PNG) buf = io.BytesIO() - diff_img.save(buf, format='PNG', optimize=True) + diff_img.save(buf, format='JPEG', quality=85, optimize=True) diff_bytes = buf.getvalue() # Explicit memory cleanup - close files first, then delete diff --git a/changedetectionio/processors/image_ssim_diff/templates/image_ssim_diff/diff.html b/changedetectionio/processors/image_ssim_diff/templates/image_ssim_diff/diff.html index 92bd169b..5d212795 100644 --- a/changedetectionio/processors/image_ssim_diff/templates/image_ssim_diff/diff.html +++ b/changedetectionio/processors/image_ssim_diff/templates/image_ssim_diff/diff.html @@ -157,7 +157,16 @@