Skip to content

Latest commit

 

History

History
113 lines (81 loc) · 4.55 KB

README.md

File metadata and controls

113 lines (81 loc) · 4.55 KB

Resize Picture By Libpng OpenCV OpenCL

Load images using libpng, resize them, and save them using OpenCV/OpenCL.

Todo List:

  • Multi Thread
  • Unit tests
  • Use premake5
  • Github action for auto run test/build/ralease
  • Bulk resizing
  • More data param like scaleFactor, keepAspect

How to Build:

  • Clone the repository.
  • Open the Visual Studio solution.
  • Build the project in x64 platform (either debug or release mode).
  • Run the application from the bin/ directory.

All dependencies required for this project are included in the repository under the Dependencies folder. You do not need to fetch them from external sources.

How to Use:

Pass Input Data as Command-Line Arguments:

You can provide all the required data as command-line arguments, but in this mode, you need to prepare all the arguments.

Argument Data
-s Source image path (e.g., c:\test\img.png)
-t Target image path (the target file should not exist, e.g., c:\test\img-res.png)
-w Target image width size as a number
-h Target image height size as a number

Usage Example:

./ResizePictureLibpngOpenCV.exe -s c:\\test\\img.png -t c:\\test\\img-res.png -w 800 -h 600 

Pass Input Data in Console:

If you execute the application without providing all the arguments correctly, you can enter the data in the console.

How It Was Developed:

Preparing Dependencies:

libpng :

  • Clone the libpng repository at https://github.com/winlibs/libpng.
  • Search for the Visual Studio project and build it in x86 platform, encountering an error due to a missing zlib library. After careful reading of the libpng readme file, I discovered that zlib should be available in the same place as libpng.
  • Download zlib and add it inside the libpng project, resolving the missing zlib error. The correct path is indicated in the error message (c1: fatal error C1083: Cannot open source file: '..\..\..\..\zlib\adler32.c': No such file or directory).
  • Successfully build in the x86 platform independently, but when attempting to use OpenCV, encountered platform mismatch issues (libpng->x86 vs. OpenCV->x64). Created a configuration in the libpng project for x64 and rebuilt it in this platform.

openCV :

  • Downloaded the OpenCV project and added include and lib files to my project.
  • This library requires precompiled DLL files, so I added a Post-Build Event for copying DLL files during each build to the target build path alongside the application executable.
  • Faced challenges with different DLL files for debug and release modes, resulting in different Post-Build Event configurations for each.

openCL :

  • Since the implementation of this library is in device drivers, we can use the implementation of Intel or AMD or Nvidia, which I have used. Note: To get the OpenCL runtime library, I installed CUDA Toolkit, but because it had a large volume, I got its installer and installed only the library I needed.

For the convenience of using the project, I have added this library in my project, but you should keep in mind that you need an Nvidia graphics card and its updated driver to use this program.


Also, to use this library, I have used its implemented C++ wrapper.

Code Overview:

  • main.cpp: Entry point that initializes and runs the image resizer.
  • image_resizer.cpp: Implements image loading, resizing, and saving functionality.

1 - Instantiate ImageResizer Class:

ChistaGame::ImageResizer imageResizer;

2 - Call Resize Method:

  • Without Data: (get data in console)
imageResizer.Resize();
  • With Data Class:
ChistaGame::ImageResizerInputData inputData("source_path", "target_path", width, height);
imageResizer.Resize(inputData);
  • With Console Args:
int argc = /* Number of arguments */;
const char* argv[] = {/* Argument strings */};
imageResizer.Resize(argc, argv);

openCL Kernel Code Implementation Of Resizing

There are several methods for image resizing.Each method has its own advantages and disadvantages.

  • Nearest-Neighbor Interpolation: Assigns the value of the nearest pixel to the new pixel location.
  • Bilinear Interpolation: Linearly interpolates pixel values based on the weighted average of the four nearest neighboring pixels.
  • Bicubic Interpolation: Uses a cubic polynomial to interpolate pixel values based on 16 neighboring pixels.

Reasons for choosing bilinear interpolation:

  • Easy to Understand
  • Balanced between quality and performance
  • Works Well on Graphics Cards (can be easily parallelized)