├── .gitignore ├── CMakeLists.txt ├── README.md ├── cmake_modules └── FindSFML.cmake └── src └── Main.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | ### CMake ### 2 | CMakeCache.txt 3 | CMakeFiles 4 | Makefile 5 | cmake_install.cmake 6 | 7 | #exe 8 | pixelator 9 | 10 | #vscode stuff 11 | settings.json 12 | .vscode 13 | 14 | #Testing 15 | *.jpg 16 | *.jpeg 17 | *.png 18 | *.bmp 19 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.1) 2 | 3 | project(pixelator) 4 | set (CMAKE_CXX_STANDARD 17) 5 | 6 | #Find the SFML package 7 | set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake_modules" ${CMAKE_MODULE_PATH}) 8 | find_package(SFML REQUIRED graphics window system) 9 | 10 | set(CMAKE_CXX_FLAGS "-Wall -Wextra") 11 | set(CMAKE_CXX_FLAGS_DEBUG "-g") 12 | set(CMAKE_CXX_FLAGS_RELEASE "-O3") 13 | 14 | 15 | #Define the executable 16 | add_executable( 17 | ${PROJECT_NAME} 18 | src/Main.cpp 19 | ) 20 | 21 | SET(ADDITIONAL_LINK_FLAGS) 22 | if(UNIX) 23 | list(APPEND ADDITIONAL_LINK_FLAGS dl) 24 | endif(UNIX) 25 | 26 | find_package(Threads) 27 | target_link_libraries(${PROJECT_NAME} Threads::Threads ${SFML_LIBRARIES} ${SFML_DEPENDENCIES} ${ADDITIONAL_LINK_FLAGS}) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Pixelator 2 | 3 | Simple program to take an image and pixelate it. 4 | 5 | It works by taking the average colour around an area, and then filling that area with that colour 6 | 7 | ## Building 8 | 9 | Requires SFML library 10 | 11 | On Ubuntu: 12 | 13 | ``` 14 | sudo apt-get install libsfml-dev 15 | ``` 16 | 17 | Building: 18 | 19 | ``` 20 | git clone https://github.com/Hopson97/Pixelator.git 21 | cd Pixelator 22 | cmake . 23 | make 24 | ``` 25 | 26 | ## Running 27 | 28 | ``` 29 | ./pixelator 30 | ``` 31 | 32 | The pixel size must be a number divisible exactly by both the image width and height 33 | 34 | ## Example 35 | 36 | ``` 37 | ./pixelator monalisa.jpg 12 38 | ``` 39 | 40 | Output: 41 | 42 | ![MonaLisaPixel](https://i.imgur.com/w2MMtSv.png) 43 | -------------------------------------------------------------------------------- /cmake_modules/FindSFML.cmake: -------------------------------------------------------------------------------- 1 | # This script locates the SFML library 2 | # ------------------------------------ 3 | # 4 | # Usage 5 | # ----- 6 | # 7 | # When you try to locate the SFML libraries, you must specify which modules you want to use (system, window, graphics, network, audio, main). 8 | # If none is given, the SFML_LIBRARIES variable will be empty and you'll end up linking to nothing. 9 | # example: 10 | # find_package(SFML COMPONENTS graphics window system) # find the graphics, window and system modules 11 | # 12 | # You can enforce a specific version, either MAJOR.MINOR or only MAJOR. 13 | # If nothing is specified, the version won't be checked (i.e. any version will be accepted). 14 | # example: 15 | # find_package(SFML COMPONENTS ...) # no specific version required 16 | # find_package(SFML 2 COMPONENTS ...) # any 2.x version 17 | # find_package(SFML 2.4 COMPONENTS ...) # version 2.4 or greater 18 | # 19 | # By default, the dynamic libraries of SFML will be found. To find the static ones instead, 20 | # you must set the SFML_STATIC_LIBRARIES variable to TRUE before calling find_package(SFML ...). 21 | # Since you have to link yourself all the SFML dependencies when you link it statically, the following 22 | # additional variables are defined: SFML_XXX_DEPENDENCIES and SFML_DEPENDENCIES (see their detailed 23 | # description below). 24 | # In case of static linking, the SFML_STATIC macro will also be defined by this script. 25 | # example: 26 | # set(SFML_STATIC_LIBRARIES TRUE) 27 | # find_package(SFML 2 COMPONENTS network system) 28 | # 29 | # On Mac OS X if SFML_STATIC_LIBRARIES is not set to TRUE then by default CMake will search for frameworks unless 30 | # CMAKE_FIND_FRAMEWORK is set to "NEVER" for example. Please refer to CMake documentation for more details. 31 | # Moreover, keep in mind that SFML frameworks are only available as release libraries unlike dylibs which 32 | # are available for both release and debug modes. 33 | # 34 | # If SFML is not installed in a standard path, you can use the SFML_ROOT CMake (or environment) variable 35 | # to tell CMake where SFML is. 36 | # 37 | # Output 38 | # ------ 39 | # 40 | # This script defines the following variables: 41 | # - For each specified module XXX (system, window, graphics, network, audio, main): 42 | # - SFML_XXX_LIBRARY_DEBUG: the name of the debug library of the xxx module (set to SFML_XXX_LIBRARY_RELEASE is no debug version is found) 43 | # - SFML_XXX_LIBRARY_RELEASE: the name of the release library of the xxx module (set to SFML_XXX_LIBRARY_DEBUG is no release version is found) 44 | # - SFML_XXX_LIBRARY: the name of the library to link to for the xxx module (includes both debug and optimized names if necessary) 45 | # - SFML_XXX_FOUND: true if either the debug or release library of the xxx module is found 46 | # - SFML_XXX_DEPENDENCIES: the list of libraries the module depends on, in case of static linking 47 | # - SFML_LIBRARIES: the list of all libraries corresponding to the required modules 48 | # - SFML_FOUND: true if all the required modules are found 49 | # - SFML_INCLUDE_DIR: the path where SFML headers are located (the directory containing the SFML/Config.hpp file) 50 | # - SFML_DEPENDENCIES: the list of libraries SFML depends on, in case of static linking 51 | # 52 | # example: 53 | # find_package(SFML 2 COMPONENTS system window graphics audio REQUIRED) 54 | # include_directories(${SFML_INCLUDE_DIR}) 55 | # add_executable(myapp ...) 56 | # target_link_libraries(myapp ${SFML_LIBRARIES}) 57 | 58 | # define the SFML_STATIC macro if static build was chosen 59 | if(SFML_STATIC_LIBRARIES) 60 | add_definitions(-DSFML_STATIC) 61 | endif() 62 | 63 | # define the list of search paths for headers and libraries 64 | set(FIND_SFML_PATHS 65 | ${SFML_ROOT} 66 | $ENV{SFML_ROOT} 67 | ~/Library/Frameworks 68 | /Library/Frameworks 69 | /usr/local 70 | /usr 71 | /sw 72 | /opt/local 73 | /opt/csw 74 | /opt) 75 | 76 | # find the SFML include directory 77 | find_path(SFML_INCLUDE_DIR SFML/Config.hpp 78 | PATH_SUFFIXES include 79 | PATHS ${FIND_SFML_PATHS}) 80 | 81 | # check the version number 82 | set(SFML_VERSION_OK TRUE) 83 | if(SFML_FIND_VERSION AND SFML_INCLUDE_DIR) 84 | # extract the major and minor version numbers from SFML/Config.hpp 85 | # we have to handle framework a little bit differently: 86 | if("${SFML_INCLUDE_DIR}" MATCHES "SFML.framework") 87 | set(SFML_CONFIG_HPP_INPUT "${SFML_INCLUDE_DIR}/Headers/Config.hpp") 88 | else() 89 | set(SFML_CONFIG_HPP_INPUT "${SFML_INCLUDE_DIR}/SFML/Config.hpp") 90 | endif() 91 | FILE(READ "${SFML_CONFIG_HPP_INPUT}" SFML_CONFIG_HPP_CONTENTS) 92 | STRING(REGEX REPLACE ".*#define SFML_VERSION_MAJOR ([0-9]+).*" "\\1" SFML_VERSION_MAJOR "${SFML_CONFIG_HPP_CONTENTS}") 93 | STRING(REGEX REPLACE ".*#define SFML_VERSION_MINOR ([0-9]+).*" "\\1" SFML_VERSION_MINOR "${SFML_CONFIG_HPP_CONTENTS}") 94 | STRING(REGEX REPLACE ".*#define SFML_VERSION_PATCH ([0-9]+).*" "\\1" SFML_VERSION_PATCH "${SFML_CONFIG_HPP_CONTENTS}") 95 | if (NOT "${SFML_VERSION_PATCH}" MATCHES "^[0-9]+$") 96 | set(SFML_VERSION_PATCH 0) 97 | endif() 98 | math(EXPR SFML_REQUESTED_VERSION "${SFML_FIND_VERSION_MAJOR} * 10000 + ${SFML_FIND_VERSION_MINOR} * 100 + ${SFML_FIND_VERSION_PATCH}") 99 | 100 | # if we could extract them, compare with the requested version number 101 | if (SFML_VERSION_MAJOR) 102 | # transform version numbers to an integer 103 | math(EXPR SFML_VERSION "${SFML_VERSION_MAJOR} * 10000 + ${SFML_VERSION_MINOR} * 100 + ${SFML_VERSION_PATCH}") 104 | 105 | # compare them 106 | if(SFML_VERSION LESS SFML_REQUESTED_VERSION) 107 | set(SFML_VERSION_OK FALSE) 108 | endif() 109 | else() 110 | # SFML version is < 2.0 111 | if (SFML_REQUESTED_VERSION GREATER 10900) 112 | set(SFML_VERSION_OK FALSE) 113 | set(SFML_VERSION_MAJOR 1) 114 | set(SFML_VERSION_MINOR x) 115 | set(SFML_VERSION_PATCH x) 116 | endif() 117 | endif() 118 | endif() 119 | 120 | # find the requested modules 121 | set(SFML_FOUND TRUE) # will be set to false if one of the required modules is not found 122 | foreach(FIND_SFML_COMPONENT ${SFML_FIND_COMPONENTS}) 123 | string(TOLOWER ${FIND_SFML_COMPONENT} FIND_SFML_COMPONENT_LOWER) 124 | string(TOUPPER ${FIND_SFML_COMPONENT} FIND_SFML_COMPONENT_UPPER) 125 | set(FIND_SFML_COMPONENT_NAME sfml-${FIND_SFML_COMPONENT_LOWER}) 126 | 127 | # no suffix for sfml-main, it is always a static library 128 | if(FIND_SFML_COMPONENT_LOWER STREQUAL "main") 129 | # release library 130 | find_library(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE 131 | NAMES ${FIND_SFML_COMPONENT_NAME} 132 | PATH_SUFFIXES lib64 lib 133 | PATHS ${FIND_SFML_PATHS}) 134 | 135 | # debug library 136 | find_library(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG 137 | NAMES ${FIND_SFML_COMPONENT_NAME}-d 138 | PATH_SUFFIXES lib64 lib 139 | PATHS ${FIND_SFML_PATHS}) 140 | else() 141 | # static release library 142 | find_library(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_STATIC_RELEASE 143 | NAMES ${FIND_SFML_COMPONENT_NAME}-s 144 | PATH_SUFFIXES lib64 lib 145 | PATHS ${FIND_SFML_PATHS}) 146 | 147 | # static debug library 148 | find_library(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_STATIC_DEBUG 149 | NAMES ${FIND_SFML_COMPONENT_NAME}-s-d 150 | PATH_SUFFIXES lib64 lib 151 | PATHS ${FIND_SFML_PATHS}) 152 | 153 | # dynamic release library 154 | find_library(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DYNAMIC_RELEASE 155 | NAMES ${FIND_SFML_COMPONENT_NAME} 156 | PATH_SUFFIXES lib64 lib 157 | PATHS ${FIND_SFML_PATHS}) 158 | 159 | # dynamic debug library 160 | find_library(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DYNAMIC_DEBUG 161 | NAMES ${FIND_SFML_COMPONENT_NAME}-d 162 | PATH_SUFFIXES lib64 lib 163 | PATHS ${FIND_SFML_PATHS}) 164 | 165 | # choose the entries that fit the requested link type 166 | if(SFML_STATIC_LIBRARIES) 167 | if(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_STATIC_RELEASE) 168 | set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_STATIC_RELEASE}) 169 | endif() 170 | if(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_STATIC_DEBUG) 171 | set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_STATIC_DEBUG}) 172 | endif() 173 | else() 174 | if(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DYNAMIC_RELEASE) 175 | set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DYNAMIC_RELEASE}) 176 | endif() 177 | if(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DYNAMIC_DEBUG) 178 | set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DYNAMIC_DEBUG}) 179 | endif() 180 | endif() 181 | endif() 182 | 183 | if (SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG OR SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE) 184 | # library found 185 | set(SFML_${FIND_SFML_COMPONENT_UPPER}_FOUND TRUE) 186 | 187 | # if both are found, set SFML_XXX_LIBRARY to contain both 188 | if (SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG AND SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE) 189 | set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY debug ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG} 190 | optimized ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE}) 191 | endif() 192 | 193 | # if only one debug/release variant is found, set the other to be equal to the found one 194 | if (SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG AND NOT SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE) 195 | # debug and not release 196 | set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG}) 197 | set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG}) 198 | endif() 199 | if (SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE AND NOT SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG) 200 | # release and not debug 201 | set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE}) 202 | set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE}) 203 | endif() 204 | else() 205 | # library not found 206 | set(SFML_FOUND FALSE) 207 | set(SFML_${FIND_SFML_COMPONENT_UPPER}_FOUND FALSE) 208 | set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY "") 209 | set(FIND_SFML_MISSING "${FIND_SFML_MISSING} SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY") 210 | endif() 211 | 212 | # mark as advanced 213 | MARK_AS_ADVANCED(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY 214 | SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE 215 | SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG 216 | SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_STATIC_RELEASE 217 | SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_STATIC_DEBUG 218 | SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DYNAMIC_RELEASE 219 | SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DYNAMIC_DEBUG) 220 | 221 | # add to the global list of libraries 222 | set(SFML_LIBRARIES ${SFML_LIBRARIES} "${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY}") 223 | endforeach() 224 | 225 | # in case of static linking, we must also define the list of all the dependencies of SFML libraries 226 | if(SFML_STATIC_LIBRARIES) 227 | 228 | # detect the OS 229 | if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") 230 | set(FIND_SFML_OS_WINDOWS 1) 231 | elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux") 232 | set(FIND_SFML_OS_LINUX 1) 233 | elseif(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") 234 | set(FIND_SFML_OS_FREEBSD 1) 235 | elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") 236 | set(FIND_SFML_OS_MACOSX 1) 237 | endif() 238 | 239 | # start with an empty list 240 | set(SFML_DEPENDENCIES) 241 | set(FIND_SFML_DEPENDENCIES_NOTFOUND) 242 | 243 | # macro that searches for a 3rd-party library 244 | macro(find_sfml_dependency output friendlyname) 245 | # No lookup in environment variables (PATH on Windows), as they may contain wrong library versions 246 | find_library(${output} NAMES ${ARGN} PATHS ${FIND_SFML_PATHS} PATH_SUFFIXES lib NO_SYSTEM_ENVIRONMENT_PATH) 247 | if(${${output}} STREQUAL "${output}-NOTFOUND") 248 | unset(output) 249 | set(FIND_SFML_DEPENDENCIES_NOTFOUND "${FIND_SFML_DEPENDENCIES_NOTFOUND} ${friendlyname}") 250 | endif() 251 | endmacro() 252 | 253 | # sfml-system 254 | list(FIND SFML_FIND_COMPONENTS "system" FIND_SFML_SYSTEM_COMPONENT) 255 | if(NOT ${FIND_SFML_SYSTEM_COMPONENT} EQUAL -1) 256 | 257 | # update the list -- these are only system libraries, no need to find them 258 | if(FIND_SFML_OS_LINUX OR FIND_SFML_OS_FREEBSD OR FIND_SFML_OS_MACOSX) 259 | set(SFML_SYSTEM_DEPENDENCIES "pthread") 260 | endif() 261 | if(FIND_SFML_OS_LINUX) 262 | set(SFML_SYSTEM_DEPENDENCIES ${SFML_SYSTEM_DEPENDENCIES} "rt") 263 | endif() 264 | if(FIND_SFML_OS_WINDOWS) 265 | set(SFML_SYSTEM_DEPENDENCIES "winmm") 266 | endif() 267 | set(SFML_DEPENDENCIES ${SFML_SYSTEM_DEPENDENCIES} ${SFML_DEPENDENCIES}) 268 | endif() 269 | 270 | # sfml-network 271 | list(FIND SFML_FIND_COMPONENTS "network" FIND_SFML_NETWORK_COMPONENT) 272 | if(NOT ${FIND_SFML_NETWORK_COMPONENT} EQUAL -1) 273 | 274 | # update the list -- these are only system libraries, no need to find them 275 | if(FIND_SFML_OS_WINDOWS) 276 | set(SFML_NETWORK_DEPENDENCIES "ws2_32") 277 | endif() 278 | set(SFML_DEPENDENCIES ${SFML_NETWORK_DEPENDENCIES} ${SFML_DEPENDENCIES}) 279 | endif() 280 | 281 | # sfml-window 282 | list(FIND SFML_FIND_COMPONENTS "window" FIND_SFML_WINDOW_COMPONENT) 283 | if(NOT ${FIND_SFML_WINDOW_COMPONENT} EQUAL -1) 284 | 285 | # find libraries 286 | if(FIND_SFML_OS_LINUX OR FIND_SFML_OS_FREEBSD) 287 | find_sfml_dependency(X11_LIBRARY "X11" X11) 288 | find_sfml_dependency(XRANDR_LIBRARY "Xrandr" Xrandr) 289 | endif() 290 | 291 | if(FIND_SFML_OS_LINUX) 292 | find_sfml_dependency(UDEV_LIBRARIES "UDev" udev libudev) 293 | endif() 294 | 295 | # update the list 296 | if(FIND_SFML_OS_WINDOWS) 297 | set(SFML_WINDOW_DEPENDENCIES ${SFML_WINDOW_DEPENDENCIES} "opengl32" "winmm" "gdi32") 298 | elseif(FIND_SFML_OS_LINUX) 299 | set(SFML_WINDOW_DEPENDENCIES ${SFML_WINDOW_DEPENDENCIES} "GL" ${X11_LIBRARY} ${XRANDR_LIBRARY} ${UDEV_LIBRARIES}) 300 | elseif(FIND_SFML_OS_FREEBSD) 301 | set(SFML_WINDOW_DEPENDENCIES ${SFML_WINDOW_DEPENDENCIES} "GL" ${X11_LIBRARY} ${XRANDR_LIBRARY} "usbhid") 302 | elseif(FIND_SFML_OS_MACOSX) 303 | set(SFML_WINDOW_DEPENDENCIES ${SFML_WINDOW_DEPENDENCIES} "-framework OpenGL -framework Foundation -framework AppKit -framework IOKit -framework Carbon") 304 | endif() 305 | set(SFML_DEPENDENCIES ${SFML_WINDOW_DEPENDENCIES} ${SFML_DEPENDENCIES}) 306 | endif() 307 | 308 | # sfml-graphics 309 | list(FIND SFML_FIND_COMPONENTS "graphics" FIND_SFML_GRAPHICS_COMPONENT) 310 | if(NOT ${FIND_SFML_GRAPHICS_COMPONENT} EQUAL -1) 311 | 312 | # find libraries 313 | find_sfml_dependency(FREETYPE_LIBRARY "FreeType" freetype) 314 | find_sfml_dependency(JPEG_LIBRARY "libjpeg" jpeg) 315 | 316 | # update the list 317 | set(SFML_GRAPHICS_DEPENDENCIES ${FREETYPE_LIBRARY} ${JPEG_LIBRARY}) 318 | set(SFML_DEPENDENCIES ${SFML_GRAPHICS_DEPENDENCIES} ${SFML_DEPENDENCIES}) 319 | endif() 320 | 321 | # sfml-audio 322 | list(FIND SFML_FIND_COMPONENTS "audio" FIND_SFML_AUDIO_COMPONENT) 323 | if(NOT ${FIND_SFML_AUDIO_COMPONENT} EQUAL -1) 324 | 325 | # find libraries 326 | find_sfml_dependency(OPENAL_LIBRARY "OpenAL" openal openal32) 327 | find_sfml_dependency(OGG_LIBRARY "Ogg" ogg) 328 | find_sfml_dependency(VORBIS_LIBRARY "Vorbis" vorbis) 329 | find_sfml_dependency(VORBISFILE_LIBRARY "VorbisFile" vorbisfile) 330 | find_sfml_dependency(VORBISENC_LIBRARY "VorbisEnc" vorbisenc) 331 | find_sfml_dependency(FLAC_LIBRARY "FLAC" FLAC) 332 | 333 | # update the list 334 | set(SFML_AUDIO_DEPENDENCIES ${OPENAL_LIBRARY} ${FLAC_LIBRARY} ${VORBISENC_LIBRARY} ${VORBISFILE_LIBRARY} ${VORBIS_LIBRARY} ${OGG_LIBRARY}) 335 | set(SFML_DEPENDENCIES ${SFML_DEPENDENCIES} ${SFML_AUDIO_DEPENDENCIES}) 336 | endif() 337 | 338 | endif() 339 | 340 | # handle errors 341 | if(NOT SFML_VERSION_OK) 342 | # SFML version not ok 343 | set(FIND_SFML_ERROR "SFML found but version too low (requested: ${SFML_FIND_VERSION}, found: ${SFML_VERSION_MAJOR}.${SFML_VERSION_MINOR}.${SFML_VERSION_PATCH})") 344 | set(SFML_FOUND FALSE) 345 | elseif(SFML_STATIC_LIBRARIES AND FIND_SFML_DEPENDENCIES_NOTFOUND) 346 | set(FIND_SFML_ERROR "SFML found but some of its dependencies are missing (${FIND_SFML_DEPENDENCIES_NOTFOUND})") 347 | set(SFML_FOUND FALSE) 348 | elseif(NOT SFML_FOUND) 349 | # include directory or library not found 350 | set(FIND_SFML_ERROR "Could NOT find SFML (missing: ${FIND_SFML_MISSING})") 351 | endif() 352 | if (NOT SFML_FOUND) 353 | if(SFML_FIND_REQUIRED) 354 | # fatal error 355 | message(FATAL_ERROR ${FIND_SFML_ERROR}) 356 | elseif(NOT SFML_FIND_QUIETLY) 357 | # error but continue 358 | message("${FIND_SFML_ERROR}") 359 | endif() 360 | endif() 361 | 362 | # handle success 363 | if(SFML_FOUND AND NOT SFML_FIND_QUIETLY) 364 | message(STATUS "Found SFML ${SFML_VERSION_MAJOR}.${SFML_VERSION_MINOR}.${SFML_VERSION_PATCH} in ${SFML_INCLUDE_DIR}") 365 | endif() 366 | -------------------------------------------------------------------------------- /src/Main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | namespace { 9 | std::mutex mutex; 10 | 11 | bool isValidSize(unsigned size, unsigned pixelSize, const char* desc) { 12 | if (size % pixelSize != 0) { 13 | std::cout << "ERROR: Image " << desc << " is not divisible by pixel size.\n"; 14 | std::cout << desc << " is " << size << '\n'; 15 | std::cout << "Division result: " << size % pixelSize << "\n"; 16 | return false; 17 | } 18 | return true; 19 | } 20 | 21 | void visualise(const sf::Image& ogImage, const sf::Image& newImage) { 22 | mutex.lock(); 23 | float w = (float)ogImage.getSize().x; 24 | float h = (float)ogImage.getSize().y; 25 | 26 | sf::RenderWindow window({(unsigned)w, (unsigned)h}, "Pixelator"); 27 | window.setFramerateLimit(60); 28 | 29 | 30 | sf::RectangleShape ogImageRect({w, h}); 31 | sf::RectangleShape newImageRect({w, h}); 32 | 33 | sf::Texture ogTex; 34 | ogTex.loadFromImage(ogImage); 35 | ogImageRect.setTexture(&ogTex); 36 | 37 | sf::Texture newTex; 38 | newTex.loadFromImage(newImage); 39 | newImageRect.setTexture(&newTex); 40 | mutex.unlock(); 41 | 42 | while (window.isOpen()) { 43 | sf::Event e; 44 | while (window.pollEvent(e)) { 45 | if (e.type == sf::Event::Closed) window.close(); 46 | } 47 | window.clear(); 48 | 49 | mutex.lock(); 50 | newTex.loadFromImage(newImage); 51 | mutex.unlock(); 52 | 53 | window.draw(ogImageRect); 54 | window.draw(newImageRect); 55 | 56 | window.display(); 57 | } 58 | } 59 | } 60 | 61 | int main(int argc, char** argv) { 62 | std::string fileName; 63 | unsigned pixelSize = 0; 64 | if (argc > 2) { 65 | fileName = argv[1]; 66 | std::string pxString = argv[2]; 67 | pixelSize = std::stoi(pxString); //TODO Error check 68 | } 69 | else { 70 | std::cout << "Too few arguments.\nUsage: \n"; 71 | std::cout << "pixelator \n"; 72 | return 0; 73 | } 74 | 75 | std::cout << "Loading image...\n"; 76 | sf::Image image; 77 | image.loadFromFile(fileName); 78 | 79 | std::cout << "Validating image size to pixel size ratio...\n"; 80 | if (!isValidSize(image.getSize().x, pixelSize, "width") || 81 | !isValidSize(image.getSize().y, pixelSize, "height")) { 82 | return -1; 83 | } 84 | 85 | unsigned width = image.getSize().x; 86 | unsigned height = image.getSize().y; 87 | 88 | std::cout << "Creating new image...\n"; 89 | sf::Image newImage; 90 | newImage.create(width, height, sf::Color::Transparent); 91 | 92 | std::thread visualiseThread([&]() { 93 | visualise(image, newImage); 94 | }); 95 | 96 | std::vector pxlPositions; 97 | for (unsigned y = 0; y < height / pixelSize; y++) { 98 | for (unsigned x = 0; x < width / pixelSize; x++) { 99 | pxlPositions.emplace_back(x, y); 100 | } 101 | } 102 | 103 | std::random_device rd; 104 | std::mt19937 rng(rd()); 105 | std::shuffle(pxlPositions.begin(), pxlPositions.end(), rng); 106 | 107 | std::vector colours; 108 | for (auto& pos : pxlPositions) { 109 | unsigned x = pos.x; 110 | unsigned y = pos.y; 111 | colours.clear(); 112 | for (unsigned oy = 0; oy < pixelSize; oy++) { 113 | for (unsigned ox = 0; ox < pixelSize; ox++) { 114 | unsigned localX = ox + x * pixelSize; 115 | unsigned localY = oy + y * pixelSize; 116 | colours.push_back(image.getPixel(localX, localY)); 117 | } 118 | } 119 | 120 | unsigned totalRed = 0; 121 | unsigned totalGreen = 0; 122 | unsigned totalBlue = 0; 123 | for (auto c : colours) { 124 | totalRed += c.r; 125 | totalGreen += c.g; 126 | totalBlue += c.b; 127 | } 128 | auto total = colours.size(); 129 | sf::Color avgColour{ 130 | uint8_t(totalRed / total), 131 | uint8_t(totalGreen / total), 132 | uint8_t(totalBlue / total)}; 133 | 134 | for (unsigned oy = 0; oy < pixelSize; oy++) { 135 | for (unsigned ox = 0; ox < pixelSize; ox++) { 136 | unsigned localX = ox + x * pixelSize; 137 | unsigned localY = oy + y * pixelSize; 138 | mutex.lock(); 139 | newImage.setPixel(localX, localY, avgColour); 140 | mutex.unlock(); 141 | } 142 | } 143 | std::this_thread::sleep_for(std::chrono::milliseconds(1)); 144 | } 145 | std::cout << "Saving image...\n"; 146 | newImage.saveToFile("out.jpg"); 147 | std::cout << "Complete!\n"; 148 | visualiseThread.join(); 149 | } --------------------------------------------------------------------------------