A terminal-based image processing application written in modern C++17. Load any image, apply a rich set of filters one by one, undo/redo your changes, and save the result β all from a colourful, interactive command-line menu.
- Features
- Demo
- Project Structure
- Architecture
- Filters Reference
- Requirements
- Build Instructions
- Usage
- Supported Image Formats
- Adding a New Filter
- Contributors
- πΌοΈ Load & Save β Load images from the
assets/folder; save results anywhere (directories are created automatically). - π¨ 22 Built-in Filters β From basic colour adjustments to artistic effects (full list below).
- β©οΈ Undo / Redo β Full history stack lets you step backwards and forwards through every change.
- π Chained Filters β Apply any number of filters in sequence before saving.
- π₯οΈ Colourful CLI β ANSI-coloured prompts and status messages for a pleasant terminal experience.
- β»οΈ Scalable OOP Design β Adding a new filter requires only creating one new class; no other source files need to change.
cpp-image-processor/
βββ assets/ # Sample images (loaded at runtime)
βββ docs/ # Documentation assets
βββ include/
β βββ core/
β β βββ CurrentImage.h # Manages the active image & undo/redo stacks
β β βββ Menu.h # CLI menu logic
β βββ filters/
β β βββ Filter.h # Abstract base class for all filters
β β βββ ConvolutionFilter.h # Generic kernel-based convolution helper
β β βββ *.h # One header per filter
β βββ utils/
β βββ Colors.h # ANSI colour macros
β βββ Utils.h # Path resolution helpers
βββ src/
β βββ core/
β β βββ CurrentImage.cpp
β β βββ Menu.cpp
β βββ filters/
β β βββ *.cpp # One implementation file per filter
β βββ utils/
β β βββ Utils.cpp
β βββ main.cpp # Entry point
β βββ stb_image.cpp # stb_image compilation unit
βββ third_party/
β βββ Image_Class.h # Thin wrapper around stb for pixel access
β βββ stb_image.h
β βββ stb_image_write.h
βββ CMakeLists.txt
The application follows the Object-Oriented Programming paradigm with a clean separation of concerns.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β main.cpp β
β β’ Creates CurrentImage β
β β’ Instantiates all Filter objects (shared_ptr) β
β β’ Runs the main event loop via Menu β
ββββββββββββββββββ¬ββββββββββββββββββββββ¬ββββββββββββββββββββ
β β
ββββββββββββββΌβββββββ ββββββββββββΌβββββββββββ
β CurrentImage β β Menu β
β βββββββββββββ β β ββββββββββββββ β
β Image img β β showMenuOptions() β
β stack Undo β β setResponse() β
β stack Redo β β welcomeMsg() β
β load() / save() β ββββββββββββββββββββββ-β
β undo() / redo() β
βββββββββββββββββββββ
ββββββββββββββββββββββββββββββββββββββββββββ
β Filter (abstract) β
β βββββββββββββββββββββββββββββββββββββ β
β + apply() = 0 (pure virtual) β
β + getNeeds()= 0 (prompt for params) β
β + getName() = 0 β
β + static getId() β
β # Image& image β
ββββββββββββββββββββ¬ββββββββββββββββββββββββ
β inherits
βββββββββββββββββΌβββββββββββββββββββ
β β β
GreyScale Blur OilPainting
WhiteAndBlack EdgeDetection ArtisticBrush
Invert Frame (22 filters total)
β¦ etc. β¦ etc.
Each filter:
- Inherits from
Filterand overridesapply(),getNeeds(),getName(), andgetId(). - Holds a reference to the shared
Imageobject β no copies made during filtering. - Is registered once in
main.cpp; the menu dispatches bygetId()string.
| # | ID | Filter | Description |
|---|---|---|---|
| 1 | 1 |
Greyscale | Converts each pixel to the average of its RGB channels. |
| 2 | 2 |
Black & White | Applies a luminance threshold to produce a pure black-or-white image. |
| 3 | 3 |
Invert | Inverts every channel (255 - value). |
| 4 | 4 |
Merge | Blends the loaded image with a second image (pixel average). Supports stretch-to-fit or common-area merge for differently sized images. |
| 5 | 5 |
Flip | Flips the image horizontally (h) or vertically (v). |
| 6 | 6 |
Rotate | Rotates by 90Β°, 180Β°, or 270Β° using a centre-based affine transform. |
| 7 | 7 |
Brightness | Multiplies every channel by a user-supplied factor (e.g., 1.5 = +50% brightness, 0.5 = β50%). |
| 8 | 8 |
Crop | Crops a rectangular region given a starting corner and dimensions. |
| 9 | 9 |
Frame | Adds a solid-colour border. Optional decorative mode adds a contrasting inner white line. Accepts named colours or custom RGB. |
| 10 | 10 |
Edge Detection | Detects edges using Sobel kernels (horizontal + vertical), producing a greyscale edge map. |
| 11 | 11 |
Resize | Rescales the image to arbitrary dimensions using nearest-neighbour sampling. |
| 12 | 12 |
Blur | Fast box blur using a 2-D prefix-sum approach with a configurable radius. |
| 13 | 13 |
Sunlight | Simulates warm sunlight by boosting the red and green channels. |
| 14 | 14 |
Oil Painting | Stylises the image as an oil painting by sampling the most frequent intensity level in a neighbourhood. |
| 15 | 15 |
Old TV | Applies scan lines and noise to mimic a vintage CRT television effect. |
| 16 | 16 |
Night | Creates a blue-tinted low-light night vision effect. |
| 17 | 17 |
Infrared | Swaps channel intensities to simulate an infrared camera image. |
| 18 | 18 |
Horizontal Skew | Shears the image horizontally by a given angle using a tangent-based pixel shift. |
| 19 | 19 |
Bloody | Tints the image with deep red tones for a dramatic effect. |
| 20 | 20 |
Grass | Overlays a green grass-tinted effect on the lower portion of the image. |
| 21 | 21 |
Sky | Applies a sky-blue tint gradient to the upper portion of the image. |
| 22 | 22 |
Artistic Brush | An oil-painting variant with an adjustable brush radius for a looser, painterly look. |
| Tool | Minimum Version |
|---|---|
| C++ Compiler (GCC / Clang / MSVC) | C++17 |
| CMake | 3.15 |
No external libraries are required β image I/O is handled by the bundled stb_image headers in third_party/.
# 1. Clone the repository
git clone https://github.com/moabdulhakim/cpp-image-processor.git
cd cpp-image-processor
# 2. Configure with CMake
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
# 3. Build
cmake --build build --config Release
# 4. Run
./build/ImageProcessingcmake -S . -B build
cmake --build build --config Release
.\build\Release\ImageProcessing.exeNote: CMake automatically copies the
assets/folder next to the produced executable via a post-build step, so sample images are always available.
====================
Image Filters
=====================
[l] Load Image
[0] Exit
# l
Please enter image name you want to apply filter on: img.jpg
Once an image is loaded the full filter menu appears:
[l] Load Image
=====================
Choose Filters
======================
[1] Grey Scale Filter.
[2] White and Black Filter.
...
[s] Save the Image.
[u] Undo [r] Redo
[0] Exit
# 1 β apply Greyscale
# s β save result
Key commands
| Key | Action |
|---|---|
l |
Load an image from assets/ |
1β22 |
Apply the corresponding filter |
s |
Save the current image to output/ |
u |
Undo the last filter |
r |
Redo an undone filter |
0 |
Exit the application |
Saved images are written to an output/ directory (created automatically) next to the executable.
Any format supported by stb_image can be loaded:
- JPEG / JPG
- PNG
- BMP
- TGA
- GIF (first frame)
- PSD (flat composite)
- HDR
Saved output uses stb_image_write and supports JPEG, PNG, BMP, and TGA based on the file extension you provide.
The design makes adding filters straightforward β no existing files need to be modified except main.cpp.
-
Create a header
include/filters/MyFilter.hthat inheritsFilter:#pragma once #include "Filter.h" class MyFilter : public Filter { public: MyFilter(Image &img); std::string getName() override; static std::string getId(); void apply() override; void getNeeds() override; };
-
Create the implementation
src/filters/MyFilter.cppwith your pixel-manipulation logic. -
Register it in
main.cppby adding one line to thefiltersvector:{MyFilter::getId(), make_shared<MyFilter>(currentImage.img)},
The menu will automatically display and dispatch the new filter.
| Student ID | Name | Assigned Filters |
|---|---|---|
| 20242295 | Mohammad Abdulhakim Ramadan | White & Black, Flip, Crop, Resize, Oil Painting, Infrared, Artistic Brush, Bloody, Sky, Grass |
| 20242110 | Hamza Mohammad Zaki | Greyscale, Merge, Brightness (Darken/Lighten), Edge Detection |
| 20240588 | Mostafa Ahmed Ali | Invert, Rotate, Frame, Blur, Sunlight, Night, Old TV, Skew |
π Repository: https://github.com/moabdulhakim/cpp-image-processor
π¬ Demo Video: https://www.youtube.com/watch?v=BYMyUjpoP5g
π Documentation: Google Docs
