A Qt 6 desktop app and a companion CLI that showcase classic image-processing filters written in portable C. Load any bitmap, apply a filter such as blur or Sobel edges, and export the transformed result with either a GUI workflow or a terminal command.
- Highlights
- Screens & Samples
- Filter Catalog
- Architecture
- Getting Started
- Project Layout
- Extending the Filters
- Troubleshooting
- License
- Two front-ends, one core – the same
helpers.c
kernels drive both a Qt Widgets GUI and a minimalist command-line utility. - Pixel-perfect control – each effect manipulates tightly packed
RGBTRIPLE
buffers with no framework-specific abstractions in the way. - Teaching friendly – clear C implementations of grayscale, sepia, reflection, box blur, and Sobel edge detection.
- Ready-to-run assets – sample BMPs (
courtyard.bmp
,sample1.bmp
) are included for quick experimentation.
Sample bitmaps live at the repo root for manual testing. Capture and add your own before/after screenshots in this section to document results over time.
All filters share the signature void filter(int height, int width, RGBTRIPLE *image)
, operate in-place on a row-major buffer, and clamp every channel to
Filter | Flag | Description |
---|---|---|
Grayscale | g |
Averages each pixel's RGB channels to produce a luminance-only image. |
Sepia | s |
Applies the classic sepia-tone matrix with saturation clamping. |
Reflect | r |
Mirrors the image along its vertical axis by swapping pixels left-to-right. |
Blur | b |
Uses a 3×3 box blur; copies the original buffer to avoid read/write conflicts. |
Edges | e |
Runs Sobel edge detection with |
- Kernel layer (
helpers.c/.h
,bmp.h
): pure C code that owns the filter logic and pixel representations. - Qt GUI (
DAA_Final/
):MainWindow
managesQImage
instances for the original and processed frames.- On Apply, the GUI flattens the image into a contiguous
RGBTRIPLE
array, invokes the selected filter, then hydrates a newQImage
for display. CMakeLists.txt
bundles the Qt dependencies and copies the required MinGW DLLs alongside the built executable for easy distribution.
- CLI reference (
DAA_Orignal/
): reads/writes 24-bit BMPs directly, applies a single filter selected by a short flag, and preserves BMP padding.
- Windows with the Qt 6.9.1 MinGW 64-bit toolchain installed (adjust paths in
CMakeLists.txt
if your Qt lives elsewhere). - CMake 3.16+
- Ninja (or adjust the generator at configure time).
- Clang (for the CLI Makefile) or adapt the command to your preferred compiler.
Configure once (update the Qt path if needed), then build:
cmake -S DAA_Final -B DAA_Final/build -G Ninja -DCMAKE_PREFIX_PATH="C:/Qt/6.9.1/mingw_64"
cmake --build DAA_Final/build
The post-build steps copy qt6core.dll
, qt6gui.dll
, qt6widgets.dll
, libgcc_s_seh-1.dll
, and the platforms/qwindows.dll
plugin into the output directory. Add any missing DLLs if the app complains at runtime (e.g., libstdc++-6.dll
, libwinpthread-1.dll
).
After a successful build, launch the app from the build tree:
DAA_Final/build/Desktop_Qt_6_9_1_MinGW_64_bit-Debug/ImageProcessor.exe
Workflow:
- Load an image (BMP, PNG, or JPEG) via Load.
- Pick a filter from the dropdown.
- Apply to preview the processed result.
- Save to export the transformed image.
From DAA_Orignal/
, compile with the provided Makefile (clang command shown; substitute another compiler if preferred):
cd DAA_Orignal
make
This produces filter.exe
alongside the sources.
Invoke the tool with one of the filter flags and provide input/output BMP paths:
./filter -g courtyard.bmp grayscale.bmp
Flags map one-to-one to the GUI filters: -g
(grayscale), -s
(sepia), -r
(reflect), -b
(blur), -e
(edges).
Image Filters Algorithms in C/
├── DAA_Final/ # Qt 6 GUI front-end, CMake project
│ ├── helpers.c/.h # Filter kernels shared between GUI and CLI
│ ├── main.cpp # QApplication entry point
│ ├── mainwindow.* # Qt Widgets UI logic and layout
│ └── build/ # Generated build tree (outside of Git is recommended)
├── DAA_Orignal/ # CLI reference implementation with Makefile
│ ├── filter.c # BMP reader/writer + filter dispatcher
│ └── helpers.* # Same kernels, included for standalone build
├── courtyard.bmp # Sample input image
└── sample1.bmp # Additional sample
- Add your new kernel to
helpers.c
and declare it inhelpers.h
with the same(height, width, RGBTRIPLE *)
signature. - GUI: append the filter name and short flag to
MainWindow
's combo box (constructor) and extend theswitch
inon_btnApply_clicked()
. - CLI: update
filters
inDAA_Orignal/filter.c
, add a matchingcase
, and rebuild. - If the filter needs access to the original pixels while writing results (e.g., convolution), follow the
blur
/edges
pattern: allocate a temporary copy, guardmalloc
, andfree
it before returning.
- Missing DLLs: confirm the
QT_DEPENDENT_DLL_NAMES
list inCMakeLists.txt
matches your Qt/MinGW installation. Copy any extra DLLs the runtime reports as missing. - Unsupported BMP: the CLI expects uncompressed 24-bit BMP 4.0 files. Convert other formats before running through the terminal tool.
- Memory errors: both blur and edges allocate copies of the image. Low-memory environments should detect the failure and skip filtering gracefully.
- Build directory noise: keep the
DAA_Final/build/
directory out of version control; regenerate freely when switching Qt versions or compilers.
Released under the Apache License 2.0. When contributing, include the Apache header in new source files and keep attribution notices intact.