Skip to content

Commit 4e1b864

Browse files
authored
Merge pull request #59 from anpawo/feature/zoom
Feature/zoom
2 parents 9e91237 + 8abedfd commit 4e1b864

File tree

8 files changed

+133
-28
lines changed

8 files changed

+133
-28
lines changed

.github/workflows/ci-build.yaml

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,13 @@ jobs:
2222
run: echo "VCPKG_ROOT=$HOME/vcpkg" >> $GITHUB_ENV
2323

2424
- name: Install dependencies
25-
run: sudo apt-get update && sudo apt-get install -y build-essential cmake libopencv-dev python3-dev ffmpeg
25+
run: sudo apt-get update && sudo apt-get install -y build-essential cmake python3-dev ffmpeg libopencv-dev g++-13 gcc-13
26+
27+
- name: Set CXX environment variable
28+
run: |
29+
g++-13 --version
30+
g++ --version
31+
echo "CXX=$(which g++-13)" >> $GITHUB_ENV
2632
2733
- name: Install Qt
2834
uses: jurplel/install-qt-action@v4
@@ -33,34 +39,25 @@ jobs:
3339
arch: 'gcc_64'
3440

3541
- name: Configure CMake
36-
run: cmake -S . -B build
42+
run: cmake -S . -B build -DCMAKE_CXX_COMPILER=$(which g++-13) -DCI_BUILD=ON
3743

3844
- name: Build the project
3945
run: make -C build
4046

4147
- name: copy executable
4248
run: cp build/video-code video-code
4349

44-
- name: Run help
45-
run: |
46-
./video-code --help
47-
if [ $? -ne 0 ]; then
48-
echo "Error: video-code failed to run."
49-
exit 1
50-
fi
51-
5250
- name: Run video-code
5351
run: |
5452
./video-code --generate out.mp4
5553
if [ $? -ne 0 ] || [ ! -f "out.mp4" ]; then
5654
echo "Error: video-code failed to generate out.mp4."
5755
exit 1
5856
fi
59-
57+
6058
# - name: Run functional tests
6159
# run: |
6260
# ./tests/functional_tests.sh
6361
# if [ $? -ne 0 ]; then
6462
# echo "Error: Functional tests failed."
6563
# exit 1
66-
# fi

CMakeLists.txt

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
cmake_minimum_required(VERSION 3.21)
22
project(video-code VERSION 1.0.0 LANGUAGES CXX)
33

4+
option(CI_BUILD "CI Build" OFF)
5+
46
set(CMAKE_CXX_STANDARD 20)
57
set(CMAKE_CXX_STANDARD_REQUIRED ON)
68
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++20 -Wall -Wextra -Wno-deprecated -pipe -O2 -D_REENTRANT -DVC_DEBUG_ON -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_NO_KEYWORDS")
79

810
set_property(GLOBAL PROPERTY CXX_STANDARD 20)
911

10-
if (UNIX AND NOT APPLE)
12+
if (UNIX AND NOT APPLE AND NOT DEFINED CMAKE_CXX_COMPILER)
1113
set(CMAKE_CXX_COMPILER "g++-13")
1214
endif()
1315

@@ -34,12 +36,30 @@ if (NOT DEFINED ENV{Qt6_DIR})
3436
set(Qt6_DIR "/usr/include/qt6/6.8.2/gcc_64/lib/cmake/Qt6")
3537
endif()
3638

39+
if (CI_BUILD)
40+
message(STATUS "CI_BUILD is defined")
41+
include(FetchContent)
42+
FetchContent_Declare(
43+
argparse
44+
GIT_REPOSITORY https://github.com/p-ranav/argparse.git
45+
)
46+
FetchContent_MakeAvailable(argparse)
47+
48+
FetchContent_Declare(
49+
nlohmann_json
50+
GIT_REPOSITORY https://github.com/nlohmann/json.git
51+
)
52+
FetchContent_MakeAvailable(nlohmann_json)
53+
endif()
54+
3755
find_package(OpenCV REQUIRED)
3856
find_package(Python3 3.12 REQUIRED COMPONENTS Development Development.Module Development.Embed)
3957
find_package(Qt6 REQUIRED COMPONENTS Widgets Core Gui)
40-
find_package(nlohmann_json CONFIG REQUIRED)
41-
set(argparse_DIR "${VCPKG_ROOT}/installed/${VCPKG_TARGET_TRIPLET}/share/argparse")
42-
find_package(argparse CONFIG REQUIRED)
58+
if (NOT CI_BUILD)
59+
find_package(nlohmann_json CONFIG REQUIRED)
60+
set(argparse_DIR "${VCPKG_ROOT}/installed/${VCPKG_TARGET_TRIPLET}/share/argparse")
61+
find_package(argparse CONFIG REQUIRED)
62+
endif()
4363

4464
include_directories(
4565
${OpenCV_INCLUDE_DIRS}
@@ -65,6 +85,7 @@ set(SOURCES
6585
src/transformation/color/grayscale.cpp
6686
src/transformation/other/overlay.cpp
6787
src/transformation/other/repeat.cpp
88+
src/transformation/other/zoom.cpp
6889
)
6990

7091
add_executable(${PROJECT_NAME} ${SOURCES})

include/transformation/transformation.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ namespace transformation
2929
// Other
3030
transformation(overlay);
3131
transformation(repeat);
32+
transformation(zoom);
33+
3234
/***
3335
TODO: transformation(concat);
3436
TODO: transformation(merge);
@@ -44,5 +46,6 @@ namespace transformation
4446
// Other
4547
{"overlay", overlay},
4648
{"repeat", repeat},
49+
{"zoom", zoom},
4750
};
48-
};
51+
}

src/transformation/other/zoom.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
** EPITECH PROJECT, 2025
3+
** eip [WSL: Ubuntu]
4+
** File description:
5+
** zoom
6+
*/
7+
8+
#include <memory>
9+
10+
#include "input/IInput.hpp"
11+
#include "transformation/transformation.hpp"
12+
13+
void transformation::zoom(std::shared_ptr<IInput> input, [[maybe_unused]] Register &reg, const json::object_t &args)
14+
{
15+
const float zoomFactor = args.at("zoomFactor");
16+
const std::pair<float, float> zoomCenter = args.at("zoomCenter");
17+
const bool staticZoom = args.at("mode") == "static";
18+
const float startZoomFactor = args.at("zoomstart");
19+
const float endZoomFactor = args.at("zoomend");
20+
const int nbFrames = input->size();
21+
int i = 0;
22+
23+
for (auto &[frame, _] : *input)
24+
{
25+
float currentZoomFactor;
26+
27+
if (staticZoom)
28+
currentZoomFactor = zoomFactor;
29+
else
30+
currentZoomFactor = startZoomFactor + (endZoomFactor - startZoomFactor) * (static_cast<float>(i) / (nbFrames - 1));
31+
32+
cv::Mat zoomedFrame;
33+
cv::Point2f center(frame.cols * zoomCenter.first, frame.rows * zoomCenter.second);
34+
cv::Mat zoomMatrix = cv::getRotationMatrix2D(center, 0, currentZoomFactor);
35+
cv::warpAffine(frame, zoomedFrame, zoomMatrix, frame.size());
36+
frame = zoomedFrame;
37+
i++;
38+
}
39+
}

video.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,21 @@
33
x = 700
44
y = 10
55

6-
# text: Video-Code
7-
t = text("Video-Code", 3).apply(translate(x, y), repeat(24 * 4))
8-
t[: 24 * 3].apply(fadeIn(LEFT))
9-
t.add()
10-
t.keep()
6+
# # text: Video-Code
7+
# t = text("Video-Code", 3).apply(translate(x, y), repeat(24 * 4))
8+
# t[: 24 * 3].apply(fadeIn(LEFT))
9+
# t.add()
10+
# t.keep()
1111

12-
# text: Made by
13-
t = text("made by", 3).apply(translate(x, y + 80), repeat(24 * 4))
14-
t[: 24 * 3].apply(fadeIn(LEFT))
15-
t.add()
16-
t.keep()
12+
# # text: Made by
13+
# t = text("made by", 3).apply(translate(x, y + 80), repeat(24 * 4))
14+
# t[: 24 * 3].apply(fadeIn(LEFT))
15+
# t.add()
16+
# t.keep()
1717

1818

1919
# Me
2020
v = video("video/v.mp4").apply(translate(x, y + 175))
21-
v.apply(grayscale())
21+
v.apply(zoomOut(4, (0.1,0.1)))
2222
v.add()
2323
v.keep()

videocode/Constant.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
# unsigned int
1010
uint = Annotated[int, "unsigned"]
1111

12+
# modes
13+
type mode = Literal["static", "dynamic"]
1214

1315
# sides
1416
type side = Literal["left", "right", "up", "down"]

videocode/transformation/_AllTransformation.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,4 @@
2020
from videocode.transformation.other.Merge import *
2121
from videocode.transformation.other.Overlay import *
2222
from videocode.transformation.other.Repeat import *
23+
from videocode.transformation.other.Zoom import *
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#!/usr/bin/env python3
2+
3+
from videocode.transformation.Transformation import Transformation
4+
5+
from videocode.Constant import *
6+
7+
class zoom(Transformation):
8+
"""
9+
`Zoom` `Transformation`.
10+
"""
11+
12+
def __init__(self, zoomFactor: float = 1.0, zoomCenter: tuple[float, float] = (0.5, 0.5), mode: mode = "static", zoomstart: float = 1.0, zoomend: float = 1.0) -> None:
13+
"""
14+
:param zoomFactor: zoom factor must be greater than 0, 1.0 = no zoom, 2.0 = 2x zoom
15+
:param zoomCenter: center of zoom, (0.5, 0.5) = center of the image
16+
:param mode: static or dynamic
17+
:param zoomstart: start zoom factor
18+
:param zoomend: end zoom factor
19+
"""
20+
if zoomFactor < 1:
21+
raise ValueError("zoomFactor must be greater than 0")
22+
self.zoomFactor = zoomFactor
23+
self.zoomCenter = zoomCenter
24+
self.mode = mode
25+
self.zoomstart = zoomstart
26+
self.zoomend = zoomend
27+
28+
class zoomIn:
29+
"""
30+
`Zoom in` `Transformation`.
31+
"""
32+
33+
def __new__(cls, zoomFactor: float = 1.0, zoomCenter: tuple[float, float] = (0.5, 0.5)) -> zoom:
34+
return zoom(zoomFactor, zoomCenter, "dynamic", zoomstart=1.0, zoomend=zoomFactor)
35+
36+
class zoomOut:
37+
"""
38+
`Zoom out` `Transformation`.
39+
"""
40+
41+
def __new__(cls, zoomFactor: float = 1.0, zoomCenter: tuple[float, float] = (0.5, 0.5)) -> zoom:
42+
return zoom(zoomFactor, zoomCenter, "dynamic", zoomstart=zoomFactor, zoomend=1.0)

0 commit comments

Comments
 (0)