From dedfa08c62332a2b69c08e65b6e46c0c4010242d Mon Sep 17 00:00:00 2001 From: lostjared Date: Fri, 8 Mar 2019 14:12:12 -0800 Subject: [PATCH] added Windows source --- .../Acid.Cam.Qt.Windows.March.2019/.gitignore | 1 + .../AcidCam.pro | 17 + .../AcidCam.pro.user | 318 +++ .../Acid.Cam.Qt.Windows.March.2019/Makefile | 461 ++++ .../Acid.Cam.Qt.Windows.March.2019/README.md | 12 + .../ac-alpha.cpp | 511 +++++ .../ac-basic.cpp | 988 +++++++++ .../Acid.Cam.Qt.Windows.March.2019/ac-box.cpp | 103 + .../ac-filter1.cpp | 273 +++ .../ac-filter10.cpp | 1146 ++++++++++ .../ac-filter11.cpp | 1013 +++++++++ .../ac-filter12.cpp | 1114 ++++++++++ .../ac-filter13.cpp | 1094 ++++++++++ .../ac-filter14.cpp | 1109 ++++++++++ .../ac-filter15.cpp | 1062 ++++++++++ .../ac-filter16.cpp | 1154 ++++++++++ .../ac-filter17.cpp | 157 ++ .../ac-filter2.cpp | 911 ++++++++ .../ac-filter3.cpp | 1882 +++++++++++++++++ .../ac-filter4.cpp | 1241 +++++++++++ .../ac-filter5.cpp | 1275 +++++++++++ .../ac-filter6.cpp | 1287 +++++++++++ .../ac-filter7.cpp | 1047 +++++++++ .../ac-filter8.cpp | 1220 +++++++++++ .../ac-filter9.cpp | 1061 ++++++++++ .../ac-filtercat.cpp | 128 ++ .../ac-filtercat.h | 90 + .../ac-grid.cpp | 285 +++ .../ac-image.cpp | 614 ++++++ .../Acid.Cam.Qt.Windows.March.2019/ac-obj.cpp | 173 ++ .../ac-particle.cpp | 336 +++ .../ac-square.cpp | 309 +++ .../ac-util.cpp | 716 +++++++ windows/Acid.Cam.Qt.Windows.March.2019/ac.h | 1543 ++++++++++++++ .../acidcam.ifp | Bin 0 -> 3747 bytes .../chroma_window.cpp | 458 ++++ .../chroma_window.h | 51 + .../display_window.cpp | 42 + .../display_window.h | 26 + .../fractal.cpp | 157 ++ .../Acid.Cam.Qt.Windows.March.2019/fractal.h | 61 + .../goto_window.cpp | 98 + .../goto_window.h | 38 + .../Acid.Cam.Qt.Windows.March.2019/main.cpp | 29 + .../main_window.cpp | 1556 ++++++++++++++ .../main_window.h | 149 ++ .../new_dialog.cpp | 167 ++ .../new_dialog.h | 56 + .../playback_thread.cpp | 407 ++++ .../playback_thread.h | 84 + .../Acid.Cam.Qt.Windows.March.2019/plugin.cpp | 128 ++ .../Acid.Cam.Qt.Windows.March.2019/plugin.h | 39 + .../qresource.qrc | 5 + .../qtheaders.h | 64 + .../search_box.cpp | 90 + .../search_box.h | 27 + .../select_image.cpp | 1 + .../select_image.h | 6 + .../Acid.Cam.Qt.Windows.March.2019/tokenize.h | 111 + .../tokenize.hpp | 112 + .../user_define.cpp | 126 ++ .../user_define.h | 28 + .../win-icon.ico | Bin 0 -> 280982 bytes .../win-icon.rc | 1 + 64 files changed, 28768 insertions(+) create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/.gitignore create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/AcidCam.pro create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/AcidCam.pro.user create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/Makefile create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/README.md create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/ac-alpha.cpp create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/ac-basic.cpp create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/ac-box.cpp create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/ac-filter1.cpp create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/ac-filter10.cpp create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/ac-filter11.cpp create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/ac-filter12.cpp create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/ac-filter13.cpp create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/ac-filter14.cpp create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/ac-filter15.cpp create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/ac-filter16.cpp create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/ac-filter17.cpp create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/ac-filter2.cpp create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/ac-filter3.cpp create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/ac-filter4.cpp create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/ac-filter5.cpp create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/ac-filter6.cpp create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/ac-filter7.cpp create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/ac-filter8.cpp create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/ac-filter9.cpp create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/ac-filtercat.cpp create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/ac-filtercat.h create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/ac-grid.cpp create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/ac-image.cpp create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/ac-obj.cpp create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/ac-particle.cpp create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/ac-square.cpp create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/ac-util.cpp create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/ac.h create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/acidcam.ifp create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/chroma_window.cpp create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/chroma_window.h create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/display_window.cpp create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/display_window.h create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/fractal.cpp create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/fractal.h create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/goto_window.cpp create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/goto_window.h create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/main.cpp create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/main_window.cpp create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/main_window.h create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/new_dialog.cpp create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/new_dialog.h create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/playback_thread.cpp create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/playback_thread.h create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/plugin.cpp create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/plugin.h create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/qresource.qrc create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/qtheaders.h create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/search_box.cpp create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/search_box.h create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/select_image.cpp create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/select_image.h create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/tokenize.h create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/tokenize.hpp create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/user_define.cpp create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/user_define.h create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/win-icon.ico create mode 100755 windows/Acid.Cam.Qt.Windows.March.2019/win-icon.rc diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/.gitignore b/windows/Acid.Cam.Qt.Windows.March.2019/.gitignore new file mode 100755 index 0000000..c17485e --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/.gitignore @@ -0,0 +1 @@ +*DS_Store diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/AcidCam.pro b/windows/Acid.Cam.Qt.Windows.March.2019/AcidCam.pro new file mode 100755 index 0000000..29fabd7 --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/AcidCam.pro @@ -0,0 +1,17 @@ +###################################################################### +# Automatically generated by qmake (2.01a) Wed Feb 1 02:31:01 2017 +###################################################################### + +TEMPLATE = app +TARGET = Acid.Cam.v2.Qt +RC_FILE = win-icon.rc +QT += core gui widgets +DEPENDPATH += . +INCLUDEPATH += . C:\OpenCV\opencv\build\include /usr/include/ /usr/local/include +LIBS += C:/OpenCV/opencv/build/x64/vc15/lib/opencv_world341.lib -luser32 -lgdi32 +#QMAKE_CXXFLAGS += -std=c++11 +RESOURCES += qresource.qrc + +# Input +HEADERS += main_window.h new_dialog.h plugin.h qtheaders.h select_image.h ac.h fractal.h display_window.h playback_thread.h ac.h fractal.h search_box.h goto_window.h chroma_window.h user_define.h ac-filtercat.h +SOURCES += main.cpp main_window.cpp new_dialog.cpp plugin.cpp select_image.cpp fractal.cpp display_window.cpp playback_thread.cpp search_box.cpp user_define.cpp fractal.cpp ac-alpha.cpp ac-obj.cpp ac-util.cpp ac-square.cpp ac-particle.cpp ac-grid.cpp ac-basic.cpp ac-filter1.cpp ac-filter2.cpp ac-filter3.cpp ac-filter4.cpp ac-filter5.cpp ac-filter6.cpp ac-filter7.cpp ac-filter8.cpp ac-filter9.cpp ac-filter10.cpp ac-filter11.cpp ac-filter12.cpp ac-filter13.cpp ac-filter14.cpp ac-filter15.cpp ac-filter16.cpp ac-filter17.cpp ac-image.cpp ac-box.cpp chroma_window.cpp goto_window.cpp ac-filtercat.cpp diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/AcidCam.pro.user b/windows/Acid.Cam.Qt.Windows.March.2019/AcidCam.pro.user new file mode 100755 index 0000000..a1df151 --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/AcidCam.pro.user @@ -0,0 +1,318 @@ + + + + + + EnvironmentId + {9c760219-7f46-4776-929b-24f16573a356} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 1 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.10.1 MSVC2015 64bit + Desktop Qt 5.10.1 MSVC2015 64bit + qt.qt5.5101.win64_msvc2015_64_kit + 1 + 0 + 0 + + C:/build-AcidCam-Desktop_Qt_5_10_1_MSVC2015_64bit-Debug + + + true + qmake + + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Make + + Qt4ProjectManager.MakeStep + + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + true + clean + + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + true + + + C:/build-AcidCam-Desktop_Qt_5_10_1_MSVC2015_64bit-Release + + + true + qmake + + QtProjectManager.QMakeBuildStep + false + + false + false + false + + + true + Make + + Qt4ProjectManager.MakeStep + + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + true + clean + + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + + C:/build-AcidCam-Desktop_Qt_5_10_1_MSVC2015_64bit-Profile + + + true + qmake + + QtProjectManager.QMakeBuildStep + true + + false + true + false + + + true + Make + + Qt4ProjectManager.MakeStep + + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + true + clean + + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + 3 + + + 0 + Deploy + + ProjectExplorer.BuildSteps.Deploy + + 1 + Deploy Configuration + + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + AcidCam + AcidCam2 + Qt4ProjectManager.Qt4RunConfiguration:C:/Acid.Cam.New/NewOne/Acid.Cam.Build/AcidCam.pro + true + + AcidCam.pro + false + + + 3768 + false + true + false + false + true + + 1 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.FileVersion + 18 + + + Version + 18 + + diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/Makefile b/windows/Acid.Cam.Qt.Windows.March.2019/Makefile new file mode 100755 index 0000000..8ff61a7 --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/Makefile @@ -0,0 +1,461 @@ +############################################################################# +# Makefile for building: Acid_Cam_v2_Qt.app/Contents/MacOS/Acid_Cam_v2_Qt +# Generated by qmake (2.01a) (Qt 4.8.7) on: Tue Feb 12 18:32:55 2019 +# Project: Acid.Cam.v2.Linux.Qt.pro +# Template: app +# Command: /usr/local/bin/qmake -o Makefile Acid.Cam.v2.Linux.Qt.pro +############################################################################# + +####### Compiler, tools and options + +CC = clang +CXX = clang++ +DEFINES = -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED +CFLAGS = -pipe -mmacosx-version-min=10.7 -O2 -arch x86_64 -Wall -W $(DEFINES) +CXXFLAGS = -pipe -stdlib=libc++ -mmacosx-version-min=10.7 -std=c++11 `pkg-config acidcam opencv --cflags` -O2 -arch x86_64 -Wall -W $(DEFINES) +INCPATH = -I/Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/unsupported/macx-clang-libc++ -I. -I/Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/lib/QtCore.framework/Versions/4/Headers -I/Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/lib/QtCore.framework/Versions/4/Headers -I/Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/lib/QtGui.framework/Versions/4/Headers -I/Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/lib/QtGui.framework/Versions/4/Headers -I/Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/include -I. -I/usr/include -I/Volumes/LostDrive-6/Users/jared/usr.local/local/include -I. -F/Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/lib +LINK = clang++ +LFLAGS = -headerpad_max_install_names -stdlib=libc++ -mmacosx-version-min=10.7 -arch x86_64 +LIBS = $(SUBLIBS) -F/Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/lib -L/Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/lib `pkg-config acidcam opencv --libs` -framework QtGui -L/Volumes/LostDrive-6/Users/jared/usr.local/local/opt/openssl/lib -L/Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/lib -F/Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/lib -framework QtCore +AR = ar cq +RANLIB = ranlib -s +QMAKE = /usr/local/bin/qmake +TAR = tar -cf +COMPRESS = gzip -9f +COPY = cp -f +SED = sed +COPY_FILE = cp -f +COPY_DIR = cp -f -R +STRIP = +INSTALL_FILE = $(COPY_FILE) +INSTALL_DIR = $(COPY_DIR) +INSTALL_PROGRAM = $(COPY_FILE) +DEL_FILE = rm -f +SYMLINK = ln -f -s +DEL_DIR = rmdir +MOVE = mv -f +CHK_DIR_EXISTS= test -d +MKDIR = mkdir -p +export MACOSX_DEPLOYMENT_TARGET = 10.7 + +####### Output directory + +OBJECTS_DIR = ./ + +####### Files + +SOURCES = main.cpp \ + main_window.cpp \ + new_dialog.cpp \ + plugin.cpp \ + select_image.cpp \ + display_window.cpp \ + playback_thread.cpp \ + search_box.cpp \ + goto_window.cpp \ + chroma_window.cpp \ + user_define.cpp moc_main_window.cpp \ + moc_new_dialog.cpp \ + moc_display_window.cpp \ + moc_playback_thread.cpp \ + moc_search_box.cpp \ + moc_goto_window.cpp \ + moc_chroma_window.cpp \ + moc_user_define.cpp \ + qrc_qresource.cpp +OBJECTS = main.o \ + main_window.o \ + new_dialog.o \ + plugin.o \ + select_image.o \ + display_window.o \ + playback_thread.o \ + search_box.o \ + goto_window.o \ + chroma_window.o \ + user_define.o \ + moc_main_window.o \ + moc_new_dialog.o \ + moc_display_window.o \ + moc_playback_thread.o \ + moc_search_box.o \ + moc_goto_window.o \ + moc_chroma_window.o \ + moc_user_define.o \ + qrc_qresource.o +DIST = /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/common/unix.conf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/common/mac.conf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/common/gcc-base.conf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/common/gcc-base-macx.conf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/common/clang.conf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/qconfig.pri \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/modules/qt_webkit_version.pri \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/qt_functions.prf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/qt_config.prf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/exclusive_builds.prf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/default_pre.prf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/mac/default_pre.prf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/release.prf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/default_post.prf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/mac/default_post.prf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/mac/x86_64.prf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/mac/objective_c.prf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/shared.prf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/warn_on.prf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/qt.prf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/unix/thread.prf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/moc.prf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/mac/rez.prf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/mac/sdk.prf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/resources.prf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/uic.prf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/yacc.prf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/lex.prf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/include_source_dir.prf \ + Acid.Cam.v2.Linux.Qt.pro +QMAKE_TARGET = Acid_Cam_v2_Qt +DESTDIR = +TARGET = Acid_Cam_v2_Qt.app/Contents/MacOS/Acid_Cam_v2_Qt + +####### Custom Compiler Variables +QMAKE_COMP_QMAKE_OBJECTIVE_CFLAGS = -pipe \ + -O2 \ + -arch \ + x86_64 \ + -Wall \ + -W + + +first: all +####### Implicit rules + +.SUFFIXES: .o .c .cpp .cc .cxx .C + +.cpp.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<" + +.cc.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<" + +.cxx.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<" + +.C.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<" + +.c.o: + $(CC) -c $(CFLAGS) $(INCPATH) -o "$@" "$<" + +####### Build rules + +all: Makefile Acid_Cam_v2_Qt.app/Contents/PkgInfo Acid_Cam_v2_Qt.app/Contents/Resources/empty.lproj Acid_Cam_v2_Qt.app/Contents/Info.plist $(TARGET) + +$(TARGET): $(OBJECTS) + @$(CHK_DIR_EXISTS) Acid_Cam_v2_Qt.app/Contents/MacOS/ || $(MKDIR) Acid_Cam_v2_Qt.app/Contents/MacOS/ + $(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJCOMP) $(LIBS) + +Makefile: Acid.Cam.v2.Linux.Qt.pro /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/unsupported/macx-clang-libc++/qmake.conf /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/common/unix.conf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/common/mac.conf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/common/gcc-base.conf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/common/gcc-base-macx.conf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/common/clang.conf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/qconfig.pri \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/modules/qt_webkit_version.pri \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/qt_functions.prf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/qt_config.prf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/exclusive_builds.prf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/default_pre.prf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/mac/default_pre.prf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/release.prf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/default_post.prf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/mac/default_post.prf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/mac/x86_64.prf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/mac/objective_c.prf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/shared.prf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/warn_on.prf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/qt.prf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/unix/thread.prf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/moc.prf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/mac/rez.prf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/mac/sdk.prf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/resources.prf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/uic.prf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/yacc.prf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/lex.prf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/include_source_dir.prf \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/lib/QtGui.framework/QtGui.prl \ + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/lib/QtCore.framework/QtCore.prl + $(QMAKE) -o Makefile Acid.Cam.v2.Linux.Qt.pro +/Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/common/unix.conf: +/Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/common/mac.conf: +/Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/common/gcc-base.conf: +/Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/common/gcc-base-macx.conf: +/Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/common/clang.conf: +/Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/qconfig.pri: +/Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/modules/qt_webkit_version.pri: +/Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/qt_functions.prf: +/Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/qt_config.prf: +/Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/exclusive_builds.prf: +/Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/default_pre.prf: +/Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/mac/default_pre.prf: +/Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/release.prf: +/Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/default_post.prf: +/Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/mac/default_post.prf: +/Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/mac/x86_64.prf: +/Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/mac/objective_c.prf: +/Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/shared.prf: +/Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/warn_on.prf: +/Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/qt.prf: +/Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/unix/thread.prf: +/Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/moc.prf: +/Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/mac/rez.prf: +/Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/mac/sdk.prf: +/Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/resources.prf: +/Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/uic.prf: +/Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/yacc.prf: +/Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/lex.prf: +/Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/features/include_source_dir.prf: +/Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/lib/QtGui.framework/QtGui.prl: +/Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/lib/QtCore.framework/QtCore.prl: +qmake: FORCE + @$(QMAKE) -o Makefile Acid.Cam.v2.Linux.Qt.pro + +Acid_Cam_v2_Qt.app/Contents/PkgInfo: + @$(CHK_DIR_EXISTS) Acid_Cam_v2_Qt.app/Contents || $(MKDIR) Acid_Cam_v2_Qt.app/Contents + @$(DEL_FILE) Acid_Cam_v2_Qt.app/Contents/PkgInfo + @echo "APPL????" >Acid_Cam_v2_Qt.app/Contents/PkgInfo +Acid_Cam_v2_Qt.app/Contents/Resources/empty.lproj: + @$(CHK_DIR_EXISTS) Acid_Cam_v2_Qt.app/Contents/Resources || $(MKDIR) Acid_Cam_v2_Qt.app/Contents/Resources + @touch Acid_Cam_v2_Qt.app/Contents/Resources/empty.lproj + +Acid_Cam_v2_Qt.app/Contents/Info.plist: + @$(CHK_DIR_EXISTS) Acid_Cam_v2_Qt.app/Contents || $(MKDIR) Acid_Cam_v2_Qt.app/Contents + @$(DEL_FILE) Acid_Cam_v2_Qt.app/Contents/Info.plist + @sed -e "s,@SHORT_VERSION@,1.0,g" -e "s,@TYPEINFO@,????,g" -e "s,@ICON@,,g" -e "s,@EXECUTABLE@,Acid_Cam_v2_Qt,g" -e "s,@TYPEINFO@,????,g" /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/mkspecs/unsupported/macx-clang-libc++/Info.plist.app >Acid_Cam_v2_Qt.app/Contents/Info.plist +dist: + @$(CHK_DIR_EXISTS) .tmp/Acid_Cam_v2_Qt1.0.0 || $(MKDIR) .tmp/Acid_Cam_v2_Qt1.0.0 + $(COPY_FILE) --parents $(SOURCES) $(DIST) .tmp/Acid_Cam_v2_Qt1.0.0/ && $(COPY_FILE) --parents main_window.h new_dialog.h plugin.h qtheaders.h select_image.h display_window.h playback_thread.h search_box.h goto_window.h chroma_window.h user_define.h .tmp/Acid_Cam_v2_Qt1.0.0/ && $(COPY_FILE) --parents qresource.qrc .tmp/Acid_Cam_v2_Qt1.0.0/ && $(COPY_FILE) --parents main.cpp main_window.cpp new_dialog.cpp plugin.cpp select_image.cpp display_window.cpp playback_thread.cpp search_box.cpp goto_window.cpp chroma_window.cpp user_define.cpp .tmp/Acid_Cam_v2_Qt1.0.0/ && (cd `dirname .tmp/Acid_Cam_v2_Qt1.0.0` && $(TAR) Acid_Cam_v2_Qt1.0.0.tar Acid_Cam_v2_Qt1.0.0 && $(COMPRESS) Acid_Cam_v2_Qt1.0.0.tar) && $(MOVE) `dirname .tmp/Acid_Cam_v2_Qt1.0.0`/Acid_Cam_v2_Qt1.0.0.tar.gz . && $(DEL_FILE) -r .tmp/Acid_Cam_v2_Qt1.0.0 + + +clean:compiler_clean + -$(DEL_FILE) $(OBJECTS) + -$(DEL_FILE) *~ core *.core + + +####### Sub-libraries + +distclean: clean + -$(DEL_FILE) -r Acid_Cam_v2_Qt.app + -$(DEL_FILE) Makefile + + +check: first + +mocclean: compiler_moc_header_clean compiler_moc_source_clean + +mocables: compiler_moc_header_make_all compiler_moc_source_make_all + +compiler_objective_c_make_all: +compiler_objective_c_clean: +compiler_moc_header_make_all: moc_main_window.cpp moc_new_dialog.cpp moc_display_window.cpp moc_playback_thread.cpp moc_search_box.cpp moc_goto_window.cpp moc_chroma_window.cpp moc_user_define.cpp +compiler_moc_header_clean: + -$(DEL_FILE) moc_main_window.cpp moc_new_dialog.cpp moc_display_window.cpp moc_playback_thread.cpp moc_search_box.cpp moc_goto_window.cpp moc_chroma_window.cpp moc_user_define.cpp +moc_main_window.cpp: qtheaders.h \ + new_dialog.h \ + display_window.h \ + playback_thread.h \ + search_box.h \ + main_window.h \ + goto_window.h \ + chroma_window.h \ + user_define.h \ + main_window.h + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/bin/moc $(DEFINES) $(INCPATH) -D__APPLE__ -D__GNUC__ main_window.h -o moc_main_window.cpp + +moc_new_dialog.cpp: qtheaders.h \ + new_dialog.h + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/bin/moc $(DEFINES) $(INCPATH) -D__APPLE__ -D__GNUC__ new_dialog.h -o moc_new_dialog.cpp + +moc_display_window.cpp: qtheaders.h \ + display_window.h + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/bin/moc $(DEFINES) $(INCPATH) -D__APPLE__ -D__GNUC__ display_window.h -o moc_display_window.cpp + +moc_playback_thread.cpp: qtheaders.h \ + playback_thread.h + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/bin/moc $(DEFINES) $(INCPATH) -D__APPLE__ -D__GNUC__ playback_thread.h -o moc_playback_thread.cpp + +moc_search_box.cpp: qtheaders.h \ + main_window.h \ + new_dialog.h \ + display_window.h \ + playback_thread.h \ + search_box.h \ + goto_window.h \ + chroma_window.h \ + user_define.h \ + search_box.h + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/bin/moc $(DEFINES) $(INCPATH) -D__APPLE__ -D__GNUC__ search_box.h -o moc_search_box.cpp + +moc_goto_window.cpp: qtheaders.h \ + display_window.h \ + playback_thread.h \ + goto_window.h + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/bin/moc $(DEFINES) $(INCPATH) -D__APPLE__ -D__GNUC__ goto_window.h -o moc_goto_window.cpp + +moc_chroma_window.cpp: qtheaders.h \ + chroma_window.h + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/bin/moc $(DEFINES) $(INCPATH) -D__APPLE__ -D__GNUC__ chroma_window.h -o moc_chroma_window.cpp + +moc_user_define.cpp: qtheaders.h \ + user_define.h + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/bin/moc $(DEFINES) $(INCPATH) -D__APPLE__ -D__GNUC__ user_define.h -o moc_user_define.cpp + +compiler_rcc_make_all: qrc_qresource.cpp +compiler_rcc_clean: + -$(DEL_FILE) qrc_qresource.cpp +qrc_qresource.cpp: qresource.qrc \ + images/icon.png + /Volumes/LostDrive-6/Users/jared/usr.local/local/Cellar/qt/4.8.7_2/bin/rcc -name qresource qresource.qrc -o qrc_qresource.cpp + +compiler_image_collection_make_all: qmake_image_collection.cpp +compiler_image_collection_clean: + -$(DEL_FILE) qmake_image_collection.cpp +compiler_moc_source_make_all: +compiler_moc_source_clean: +compiler_rez_source_make_all: +compiler_rez_source_clean: +compiler_uic_make_all: +compiler_uic_clean: +compiler_yacc_decl_make_all: +compiler_yacc_decl_clean: +compiler_yacc_impl_make_all: +compiler_yacc_impl_clean: +compiler_lex_make_all: +compiler_lex_clean: +compiler_clean: compiler_moc_header_clean compiler_rcc_clean + +####### Compile + +main.o: main.cpp qtheaders.h \ + main_window.h \ + new_dialog.h \ + display_window.h \ + playback_thread.h \ + search_box.h \ + goto_window.h \ + chroma_window.h \ + user_define.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o main.o main.cpp + +main_window.o: main_window.cpp main_window.h \ + qtheaders.h \ + new_dialog.h \ + display_window.h \ + playback_thread.h \ + search_box.h \ + goto_window.h \ + chroma_window.h \ + user_define.h \ + plugin.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o main_window.o main_window.cpp + +new_dialog.o: new_dialog.cpp new_dialog.h \ + qtheaders.h \ + main_window.h \ + display_window.h \ + playback_thread.h \ + search_box.h \ + goto_window.h \ + chroma_window.h \ + user_define.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o new_dialog.o new_dialog.cpp + +plugin.o: plugin.cpp plugin.h \ + qtheaders.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o plugin.o plugin.cpp + +select_image.o: select_image.cpp select_image.h \ + qtheaders.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o select_image.o select_image.cpp + +display_window.o: display_window.cpp display_window.h \ + qtheaders.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o display_window.o display_window.cpp + +playback_thread.o: playback_thread.cpp playback_thread.h \ + qtheaders.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o playback_thread.o playback_thread.cpp + +search_box.o: search_box.cpp search_box.h \ + qtheaders.h \ + main_window.h \ + new_dialog.h \ + display_window.h \ + playback_thread.h \ + goto_window.h \ + chroma_window.h \ + user_define.h \ + tokenize.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o search_box.o search_box.cpp + +goto_window.o: goto_window.cpp goto_window.h \ + qtheaders.h \ + display_window.h \ + playback_thread.h \ + main_window.h \ + new_dialog.h \ + search_box.h \ + chroma_window.h \ + user_define.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o goto_window.o goto_window.cpp + +chroma_window.o: chroma_window.cpp chroma_window.h \ + qtheaders.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o chroma_window.o chroma_window.cpp + +user_define.o: user_define.cpp user_define.h \ + qtheaders.h \ + main_window.h \ + new_dialog.h \ + display_window.h \ + playback_thread.h \ + search_box.h \ + goto_window.h \ + chroma_window.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o user_define.o user_define.cpp + +moc_main_window.o: moc_main_window.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_main_window.o moc_main_window.cpp + +moc_new_dialog.o: moc_new_dialog.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_new_dialog.o moc_new_dialog.cpp + +moc_display_window.o: moc_display_window.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_display_window.o moc_display_window.cpp + +moc_playback_thread.o: moc_playback_thread.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_playback_thread.o moc_playback_thread.cpp + +moc_search_box.o: moc_search_box.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_search_box.o moc_search_box.cpp + +moc_goto_window.o: moc_goto_window.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_goto_window.o moc_goto_window.cpp + +moc_chroma_window.o: moc_chroma_window.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_chroma_window.o moc_chroma_window.cpp + +moc_user_define.o: moc_user_define.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_user_define.o moc_user_define.cpp + +qrc_qresource.o: qrc_qresource.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o qrc_qresource.o qrc_qresource.cpp + +####### Install + +install: FORCE + +uninstall: FORCE + +FORCE: + diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/README.md b/windows/Acid.Cam.Qt.Windows.March.2019/README.md new file mode 100755 index 0000000..a14f974 --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/README.md @@ -0,0 +1,12 @@ +# Example pro file for Windows + +Replace the hardcoded paths with the ones you have for your current version of OpenCV compiled with Visual Studio. +Copy this pro into a new directory with the source files and qrc file. + +Also copy ac.h ac.cpp fractal.h fractal.cpp from libacidcam into the directory as well they can be found here: + +https://github.com/lostjared/libacidcam/tree/master/source + +Using Qt Creator call qmake on the file and it will build Makefiles for Visual Studio. + + diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/ac-alpha.cpp b/windows/Acid.Cam.Qt.Windows.March.2019/ac-alpha.cpp new file mode 100755 index 0000000..c159367 --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/ac-alpha.cpp @@ -0,0 +1,511 @@ +/* + * Software written by Jared Bruni https://github.com/lostjared + + This software is dedicated to all the people that experience mental illness. + + Website: http://lostsidedead.com + YouTube: http://youtube.com/LostSideDead + Instagram: http://instagram.com/jaredbruni + Twitter: http://twitter.com/jaredbruni + Facebook: http://facebook.com/LostSideDead0x + + You can use this program free of charge and redistrubute it online as long + as you do not charge anything for this program. This program is meant to be + 100% free. + + BSD 2-Clause License + + Copyright (c) 2019, Jared Bruni + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + */ + + +#include "ac.h" + +// variables for changePixel +int current_filterx = 0; +int bytesPerSample = 0; +int bytesPerRow = 0; +int width = 0; +int height = 0; +int red = 0; +int green = 0; +int blue = 0; +int offset = 0; +int randomNumber = 0; +int reverse = 0; +bool negate = false; + +// changePixel for Alpha Flame Filters +// this function is called once for each pixel in the source image +void changePixel(cv::Mat &full_buffer, int i, int z, cv::Vec3b &buffer, double pos, double *count) { + //each case is a different operation on the RGB pixel values stored in buffer + switch(current_filterx) { + case 0: + { + double value = pos; + buffer[0] = static_cast(value*buffer[0]); + buffer[1] = static_cast(value*buffer[1]); + buffer[2] = static_cast(value*buffer[2]); + } + break; + case 1: + { + double value = pos; + buffer[0] = static_cast(value*buffer[0]); + buffer[1] = static_cast((-value)*buffer[1]); + buffer[2] = static_cast(value*buffer[2]); + } + break; + case 2: + { + buffer[0] += static_cast(buffer[0]*-pos); + buffer[1] += static_cast(buffer[1]*pos); + buffer[2] += static_cast(buffer[2]*-pos); + } + break; + case 3: + { + int current_pos = static_cast(pos*0.2f); + buffer[0] = static_cast((i*current_pos)+buffer[0]); + buffer[2] = static_cast((z*current_pos)+buffer[2]); + buffer[1] = static_cast((current_pos*buffer[1])); + } + break; + case 4: + { + int current_pos = static_cast(pos*0.2f); + buffer[0] = static_cast((z*current_pos)+buffer[0]); + buffer[1] = static_cast((i*current_pos)+buffer[1]); + buffer[2] = static_cast(((i+z)*current_pos)+buffer[2]); + } + break; + case 5: + { + int current_pos = static_cast(pos*0.2f); + buffer[0] = static_cast(-(z*current_pos)+buffer[0]); + buffer[1] = static_cast(-(i*current_pos)+buffer[1]); + buffer[2] = static_cast(-((i+z)*current_pos)+buffer[2]); + } + break; + + case 6: + { + int zq = z+1, iq = i+1; + if(zq > height-1 || iq > width-1) return; + cv::Vec3b &temp = full_buffer.at(zq, iq); + buffer[0] += static_cast((i*pos)+temp[0]); + buffer[1] += static_cast((z*pos)+temp[1]); + buffer[2] += static_cast((i/(z+1))+temp[2]); + } + break; + case 7: + { + unsigned char colv[4], cola[4]; + colv[0] = buffer[0]; + colv[1] = buffer[1]; + colv[2] = buffer[2]; + cola[0] = buffer[2]; + cola[1] = buffer[1]; + cola[2] = buffer[0]; + int alpha = (int)pos; + int red_values[] = { colv[0]+cola[2], colv[1]+cola[1], colv[2]+cola[0], 0 }; + int green_values[] = { colv[2]+cola[0], colv[1]+cola[1], colv[0]+cola[2], 0 }; + int blue_values[] = { colv[1]+cola[1], colv[0]+cola[2], colv[2]+cola[0], 0 }; + unsigned char R = 0,G = 0,B = 0; + for(int iq = 0; iq <= 2; ++iq) { + R += red_values[iq]; + R /= 3; + G += green_values[iq]; + G /= 3; + B += blue_values[iq]; + B /= 3; + } + buffer[0] += static_cast(alpha*R); + buffer[1] += static_cast(alpha*G); + buffer[2] += static_cast(alpha*B); + } + break; + case 8: + { + unsigned char colv[4], cola[4]; + colv[0] = buffer[0]; + colv[1] = buffer[1]; + colv[2] = buffer[2]; + int iq = (width-i-1); + int zq = (height-z-1); + cv::Vec3b &t = full_buffer.at(zq, iq); + cola[0] = t[0]; + cola[1] = t[1]; + cola[2] = t[2]; + int alpha = (int)pos; + int red_values[] = { colv[0]+cola[2], colv[1]+cola[1], colv[2]+cola[0], 0 }; + int green_values[] = { colv[2]+cola[0], colv[1]+cola[1], colv[0]+cola[2], 0 }; + int blue_values[] = { colv[1]+cola[1], colv[0]+cola[2], colv[2]+cola[0], 0 }; + unsigned char R = 0,G = 0,B = 0; + for(int iq = 0; iq <= 2; ++iq) { + R += red_values[iq]; + R /= 3; + G += green_values[iq]; + G /= 3; + B += blue_values[iq]; + B /= 3; + } + buffer[0] += static_cast(alpha*R); + buffer[1] += static_cast(alpha*G); + buffer[2] += static_cast(alpha*B); + } + break; + case 9: + { + double alpha = pos; + unsigned char colorz[3][3]; + colorz[0][0] = buffer[0]; + colorz[0][1] = buffer[1]; + colorz[0][2] = buffer[2]; + int total_r = colorz[0][0] +colorz[0][1]+colorz[0][2]; + total_r /= 3; + total_r *= static_cast(alpha); + int iq = i+1; + if(iq > width) return; + int zq = z; + cv::Vec3b &temp = full_buffer.at(zq, iq); + colorz[1][0] = temp[0]; + colorz[1][1] = temp[1]; + colorz[1][2] = temp[2]; + int total_g = colorz[1][0]+colorz[1][1]+colorz[1][2]; + total_g /= 3; + total_g *= static_cast(alpha); + buffer[0] = static_cast(total_r); + buffer[1] = static_cast(total_g); + buffer[2] = static_cast(total_r+total_g*alpha); + + } + break; + case 10: + { + buffer[0] = static_cast(((i+z)*pos)/(i+z+1)+buffer[0]*pos); + buffer[1] += static_cast(((i*pos)/(z+1))+buffer[1]); + buffer[2] += static_cast(((z*pos)/(i+1))+buffer[2]); + } + break; + case 11: + { + buffer[0] += static_cast((buffer[2]+(i*pos))/(pos+1)); + buffer[1] += static_cast((buffer[1]+(z*pos))/(pos+1)); + buffer[2] += buffer[0]; + } + break; + case 12: + { + buffer[0] += static_cast((i/(z+1))*pos+buffer[0]); + buffer[1] += static_cast((z/(i+1))*pos+buffer[1]); + buffer[2] += static_cast(((i+z)/(pos+1)+buffer[2])); + } + break; + case 13: + { + buffer[0] += static_cast((pos*(i/(pos+1))+buffer[2])); + buffer[1] += static_cast((pos*(z/(pos+1))+buffer[1])); + buffer[2] += static_cast((pos*((i*z)/(pos+1)+buffer[0]))); + } + break; + case 14: + { + buffer[0] = static_cast(((i+z)*pos)/(i+z+1)+buffer[0]*pos); + buffer[1] += static_cast((buffer[1]+(z*pos))/(pos+1)); + buffer[2] += static_cast(((i+z)/(pos+1)+buffer[2])); + } + break; + case 15: + { + buffer[0] = static_cast((i%(z+1))*pos+buffer[0]); + buffer[1] = static_cast((z%(i+1))*pos+buffer[1]); + buffer[2] = static_cast((i+z%((int)pos+1))+buffer[2]); + } + break; + case 16: + { + int r = 0; + r = (buffer[0]+buffer[1]+buffer[2])/3; + buffer[0] += static_cast(pos*r); + buffer[1] += static_cast(-(pos*r)); + buffer[2] += static_cast(pos*r); + } + break; + case 17: + { + unsigned long r = 0;; + r = static_cast((buffer[0]+buffer[1]+buffer[2])/(pos+1)); + buffer[0] += static_cast(r*pos); + r = (buffer[0]+buffer[1]+buffer[2])/3; + buffer[1] += static_cast(r*pos); + r = (buffer[0]+buffer[1]+buffer[2])/5; + buffer[2] += static_cast(r*pos); + } + break; + case 18: + { + buffer[0] += static_cast(1+(sin(pos))*z); + buffer[1] += static_cast((1+cos(pos))*i); + buffer[2] += static_cast(((buffer[0]+buffer[1]+buffer[2])/3)); + } + break; + case 19: + { + buffer[0] += static_cast(((buffer[2]-i)*((((int)pos+1)%15)+2))); + buffer[1] += static_cast(((buffer[1]-z)*((((int)pos+1)%15)+2))); + buffer[2] += static_cast((buffer[0]-(i+z)*((((int)pos+1)%15)+2))); + } + break; + case 20: + { + buffer[0] += static_cast((buffer[0]+buffer[1]-buffer[2])/3*pos); + buffer[1] -= static_cast((buffer[0]-buffer[1]+buffer[2])/6*pos); + buffer[2] += static_cast((buffer[0]-buffer[1]-buffer[2])/9*pos); + } + break; + case 21: + { + int iq = i, zq = z+1; + if(zq > height-2) return; + cv::Vec3b &temp = full_buffer.at(zq, iq); + zq = z+2; + if(zq > height-2) return; + cv::Vec3b &temp2 = full_buffer.at(zq, iq); + int ir, ig, ib; + ir = buffer[0]+temp[0]-temp2[0]; + ig = buffer[1]-temp[1]+temp2[1]; + ib = buffer[2]-temp[2]-temp2[2]; + if(z%2 == 0) { + if(i%2 == 0) { + buffer[0] = static_cast(ir+(0.5*pos)); + buffer[1] = static_cast(ig+(0.5*pos)); + buffer[2] = static_cast(ib+(0.5*pos)); + } else { + buffer[0] = static_cast(ir+(1.5*pos)); + buffer[1] = static_cast(ig+(1.5*pos)); + buffer[2] = static_cast(ib+(1.5*pos)); + } + } else { + if(i%2 == 0) { + buffer[0] += static_cast(ir+(0.1*pos)); + buffer[1] += static_cast(ig+(0.1*pos)); + buffer[2] += static_cast(ib+(0.1*pos)); + } else { + buffer[0] -= static_cast(ir+(i*pos)); + buffer[1] -= static_cast(ig+(z*pos)); + buffer[2] -= static_cast(ib+(0.1*pos)); + } + } + } + break; + case 22: + { + if((i%2) == 0) { + if((z%2) == 0) { + buffer[0] = static_cast(1-pos*buffer[0]); + buffer[2] = static_cast((i+z)*pos); + } else { + buffer[0] = static_cast(pos*buffer[0]-z); + buffer[2] = static_cast((i-z)*pos); + } + } else { + if((z%2) == 0) { + buffer[0] = static_cast(pos*buffer[0]-i); + buffer[2] = static_cast((i-z)*pos); + } else { + buffer[0] = static_cast(pos*buffer[0]-z); + buffer[2] = static_cast((i+z)*pos); + } + } + } + break; + case 23: + { + buffer[0] = static_cast(buffer[0]+buffer[1]*2+pos); + buffer[1] = static_cast(buffer[1]+buffer[0]*2+pos); + buffer[2] = static_cast(buffer[2]+buffer[0]+pos); + } + break; + case 24: + { + buffer[0] += static_cast(buffer[2]+pos); + buffer[1] += static_cast(buffer[1]+pos); + buffer[2] += static_cast(buffer[0]+pos); + } + break; + case 25: + { + buffer[0] += static_cast((buffer[2]*pos)); + buffer[1] += static_cast((buffer[0]*pos)); + buffer[2] += static_cast((buffer[1]*pos)); + } + break; + case 26: + { + buffer[0] += static_cast((buffer[2]*pos)+i); + buffer[1] += static_cast((buffer[0]*pos)+z); + buffer[2] += static_cast((buffer[1]*pos)+i-z); + } + break; + case 27: + { + buffer[0] = static_cast((-buffer[2])+z); + buffer[1] = static_cast((-buffer[0])+i); + buffer[2] = static_cast((-buffer[1])+pos); + } + break; + case 28: + { + buffer[0] = static_cast(buffer[2]+(1+(i*z)/pos)); + buffer[1] = static_cast(buffer[1]+(1+(i*z)/pos)); + buffer[2] = static_cast(buffer[0]+(1+(i*z)/pos)); + } + break; + case 29: + { + int iq = i, zq = z+1; + if(zq > height-2) return; + cv::Vec3b &temp = full_buffer.at(zq, iq); + zq = z+2; + if(zq > height-2) return; + cv::Vec3b &temp2 = full_buffer.at(zq, iq); + zq = z+3; + if(zq > height-2) return; + cv::Vec3b &temp3 = full_buffer.at(zq, iq); + zq = z+4; + if(zq > height-2) return; + cv::Vec3b &temp4 = full_buffer.at(zq, iq); + unsigned char col[4]; + col[0] = static_cast((temp[0]+temp2[0]+temp3[0]+temp4[0])/4); + col[1] = static_cast((temp[1]+temp2[1]+temp3[1]+temp4[1])/4); + col[2] = static_cast((temp[2]+temp2[2]+temp3[2]+temp4[2])/4); + buffer[0] = static_cast(col[0]*pos); + buffer[1] = static_cast(col[1]*pos); + buffer[2] = static_cast(col[2]*pos); + } + break; + case 30: + { + double rad = 100.0; + double degree = 0.01*pos; + int x = static_cast(rad * (cos(degree))); + int y = static_cast(rad * sin(degree)); + int z = static_cast(rad * tan(degree)); + buffer[0] = static_cast(buffer[0]+x); + buffer[2] = static_cast(buffer[1]+y); + buffer[1] = static_cast(buffer[1]+z); + } + break; + case 31: + { + int average= static_cast((buffer[0]+buffer[1]+buffer[2]+1)/3); + buffer[0] += static_cast(buffer[2]+average*(pos)); + buffer[1] += static_cast(buffer[0]+average*(pos)); + buffer[2] += static_cast(buffer[1]+average*(pos)); + } + break; + case 32: + { + int value = 0; + value = ~buffer[0] + ~buffer[1] + ~buffer[2]; + value /= 2; + buffer[0] = static_cast(buffer[0]+value*pos); + value /= 2; + buffer[1] = static_cast(buffer[1]+value*pos); + value /= 2; + buffer[2] = static_cast(buffer[2]+value*pos); + } + break; + case 33: + { + buffer[0] += static_cast(*count*pos); + buffer[1] += static_cast(*count*pos); + buffer[2] += static_cast(*count*pos); + *count += 0.00001f; + if(*count > 255) *count = 0; + } + break; + case 34: + { + buffer[0] += static_cast(pos*(randomNumber+pos)); + buffer[1] += static_cast(pos*(randomNumber+z)); + buffer[2] += static_cast(pos*(randomNumber+i)); + } + break; + case 35: + { + buffer[0] += static_cast(*count *z); + buffer[1] += static_cast(*count *pos); + buffer[2] += static_cast(*count *z); + *count += 0.0000001f; + } + break; + case 36: + { + buffer[0] += static_cast(sin(3.14+pos)*pos); + buffer[1] += static_cast(cos(3.14+pos)*pos); + buffer[2] += static_cast(tan(3.14+pos)*pos); + } + break; + } + buffer[0] += red; + buffer[1] += green; + buffer[2] += blue; + if(negate == true) { + buffer[0] = ~buffer[0]; + buffer[1] = ~buffer[1]; + buffer[2] = ~buffer[2]; + } + unsigned char buf[3]; + buf[0] = buffer[0]; + buf[1] = buffer[1]; + buf[2] = buffer[2]; + switch(reverse) { + case 0://normal + break; + case 1: + buffer[0] = buf[2]; + buffer[1] = buf[1]; + buffer[2] = buf[0]; + break; + case 2: + buffer[0] = buf[1]; + buffer[1] = buf[2]; + buffer[2] = buf[0]; + break; + case 3: + buffer[0] = buf[2]; + buffer[1] = buf[0]; + buffer[2] = buf[1]; + break; + case 4: + buffer[0] = buf[1]; + buffer[1] = buf[0]; + buffer[2] = buf[2]; + break; + } +} diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/ac-basic.cpp b/windows/Acid.Cam.Qt.Windows.March.2019/ac-basic.cpp new file mode 100755 index 0000000..bc61a18 --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/ac-basic.cpp @@ -0,0 +1,988 @@ +/* + * Software written by Jared Bruni https://github.com/lostjared + + This software is dedicated to all the people that experience mental illness. + + Website: http://lostsidedead.com + YouTube: http://youtube.com/LostSideDead + Instagram: http://instagram.com/jaredbruni + Twitter: http://twitter.com/jaredbruni + Facebook: http://facebook.com/LostSideDead0x + + You can use this program free of charge and redistrubute it online as long + as you do not charge anything for this program. This program is meant to be + 100% free. + + BSD 2-Clause License + + Copyright (c) 2019, Jared Bruni + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + */ + +#include"ac.h" +#include"fractal.h" + +// SelfAlphaBlend - Perform out of Bounds AlphaBlend on source image +void ac::SelfAlphaBlend(cv::Mat &frame) { + double alpha_inc = 0.1; + if(alpha_increase != 0) { + alpha_inc = alpha_increase; + } else { + alpha_inc = 0.1; + } + for(int z = 0; z < frame.rows; ++z) {// from top to bottom + for(int i = 0; i < frame.cols; ++i) {// from left to right + cv::Vec3b &colorval = frame.at(z, i);// at x,y + colorval[0] += static_cast(colorval[0]*alpha); + colorval[1] += static_cast(colorval[1]*alpha); + colorval[2] += static_cast(colorval[2]*alpha); + swapColors(frame, z, i);// swap colors + if(isNegative == true) { // if negative + invert(frame, z, i);// invert + } + } + } + static int direction = 1;// direction equals 1 + if(direction == 1) {// if direction equals 1 + alpha += alpha_inc; // plus equal 0.1 + // if alpha greater than 10 + if(alpha > 10) { alpha = 10; direction = 2; } + } else { + alpha -= alpha_inc; // minus equal 0.05 + // if alpha <= 0.1f + if(alpha <= 0.1f) { alpha = 0.1f; direction = 1; } + } + resetAlpha(direction, alpha); +} +// Self Scale - Scale pixel values by double +// Takes cv::Mat reference +void ac::SelfScale(cv::Mat &frame) { + double inc_alpha = 0.05; + if(alpha_increase != 0) + inc_alpha = alpha_increase; + else + inc_alpha = 0.05; + static double pos = 1.0; // pos the scale + int w = frame.cols; // width variable + int h = frame.rows; // height variable + for(int z = 0; z < h; ++z) {// top to bottom + for(int i = 0; i < w; ++i) { // left to right + // current pixel at x,y + cv::Vec3b &pixel = frame.at(z, i); + // scale each rgb value by pos + pixel[0] = static_cast(pixel[0] * pos); + pixel[1] = static_cast(pixel[1] * pos); + pixel[2] = static_cast(pixel[2] * pos); + swapColors(frame, z, i);// swap colors + // if is negative set, invert pixel + if(isNegative) invert(frame, z, i); + } + } + // static direction variable + static int direction = 1; + static double pos_max = 7.0f; // position max + if(direction == 1) { // direction equals 1 + pos += inc_alpha; // pos plus equal 0.05 + if(pos > pos_max) { // pos greater than pos_max + pos = pos_max; // set pos to pos_max + direction = 0; // set direction to zero + pos_max += 0.5f; // add 0.5 to pos_max + } + } else if(direction == 0) { // direction is zero + pos += -inc_alpha; // minus equal 0.05 + if(pos <= 1.0) { // pos <= 1.0 + if(pos_max > 15) pos_max = 1.0f; // reset pos if greater than 15 + direction = 1;// set direction to 1 + } + } + resetAlpha(direction, pos); +} +// StrobeEffect - Change frame values by passIndex, incrememnt each frame +void ac::StrobeEffect(cv::Mat &frame) { + static int passIndex = 0;// passIndex variable + static double alpha = 1.0f;// alpha is 1.0 + for (int z = 0; z < frame.cols - 2; ++z) { + for (int i = 0; i < frame.rows - 2; ++i) { + + cv::Vec3b &colors = frame.at(i, z); // current pixel + + switch (passIndex) { + case 0: // pass 0 set color values + colors[0] = static_cast(colors[0] * (-alpha)); + colors[1] = static_cast(colors[1] * alpha); + colors[2] = static_cast(colors[2] * alpha); + break; + case 1: // pass 1 set color values + colors[0] += static_cast(colors[0] * alpha); + colors[1] += static_cast(colors[1] * (-alpha)); + colors[2] += static_cast(colors[2] * alpha); + break; + case 2: // pass 2 set color values + colors[0] = static_cast(colors[0] * alpha); + colors[1] = static_cast(colors[1] * alpha); + colors[2] = static_cast(colors[2] * (-alpha)); + break; + case 3: { // pass 3 grab pixels +1, and +2 ahead and use for colors + cv::Vec3b &color1 = frame.at(i + 1, z);// x,y + 1 + cv::Vec3b &color2 = frame.at(i + 2, z);// x,y + 2 + // set colors accordingly + colors[0] += static_cast(colors[0] * alpha); + colors[1] += static_cast(color1[1] * alpha); + colors[2] += static_cast(color2[2] * alpha); + break; + } + } + // swap colors + swapColors(frame, i, z); + if(isNegative == true) { // if negative variable set + invert(frame, i, z);//invert pixel + } + } + } + ++passIndex; // pass index increased once each frame + if(passIndex > 3) passIndex = 0; // if greater than 3 set back to zero + static double max = 4.0f;// max + if(alpha < 0) // alpha less than zero + tr = translation_variable; // set as translation variable + else if(alpha > max) { // greater than max + tr = -translation_variable; // negative translation variable + max += 3.0f;// max plus equal 3.0 + if(max > 23) max = 4.0f;// max greater than twenty three max equal four + } + alpha += tr; // change position +} + +// Blend3 +// takes cv::Mat as reference +void ac::Blend3(cv::Mat &frame) { + static int i=0,z=0;// set i,z to zero + static double rValue[3] = { 0, 0, 0 }; + for (z = 0; z < frame.cols; ++z) { + for (i = 0; i < frame.rows; ++i) { + cv::Vec3b &color_value = frame.at(i, z); // get pixel value + for (int j = 0; j < 3; ++j) + color_value[j] += static_cast(color_value[j] * rValue[j]); // loop through each color multiply by rValue + // swap colors + swapColors(frame, i, z); + if(isNegative == true) {// if isNegative true + invert(frame, i, z);// invert pixel + } + } + } + // change rValue array based on random function + // set to either -0.1 or 0.1 + double alpha_inc = 0.1; + if(alpha_increase != 0) + alpha_inc = alpha_increase; + else + alpha_inc = 0.1; + + + for (int q = 0; q < 3; ++q) + rValue[q] += ((rand() % 10) > 5) ? -alpha_inc : alpha_inc; +} +// takes cv::Mat reference +void ac::NegParadox(cv::Mat &frame) { + static double alpha = 1.0f; // alpha equals 1.0 + for (int z = 0; z < frame.cols - 3; ++z) { // left to right + for (int i = 0; i < frame.rows - 3; ++i) { // top to bottom + cv::Vec3b colors[4];// vector array + colors[0] = frame.at(i, z);// grab pixels + colors[1] = frame.at(i + 1, z); + colors[2] = frame.at(i + 2, z); + colors[3] = frame.at(i + 3, z); + cv::Vec3b &color_value = frame.at(i, z);// grab pixel + // set final pixel color values + color_value[0] += static_cast((colors[0][0] * alpha) + (colors[1][0] * alpha)); + color_value[1] += static_cast((colors[1][1] * alpha) + (colors[3][1] * alpha)); + color_value[2] += static_cast((colors[1][2] * alpha) + (colors[2][2] * alpha)); + swapColors(frame, i, z); // swap the colors + if(isNegative == true) { // if negative is true + invert(frame, i, z);// invert pixel + } + } + } + static double trans_var = 0.1f; // translation variable + double translation_variable = (alpha_increase != 0) ? alpha_increase :0.1; + if (alpha < 0) + trans_var = translation_variable;// increase + else if (alpha > 15) + trans_var = -translation_variable; // decrease + alpha += trans_var; // add variable + + resetAlpha(alpha); +} + +// Thought Mode +// takes cv::Mat reference +void ac::ThoughtMode(cv::Mat &frame) { + static double alpha = 1.0f, trans_var = 0.1f; // alpha + static int mode = 0;// current mode + static int sw = 1, tr = 1; + for(int z = 2; z < frame.cols-2; ++z) { + for(int i = 2; i < frame.rows-4; ++i) { + cv::Vec3b &color_value = frame.at(i, z); // current pixel + // set pixel rgb values + if(sw == 1) color_value[0] += static_cast(color_value[mode]*alpha); + if(tr == 0) color_value[mode] -= static_cast(color_value[rand()%2]*alpha); + color_value[mode] += static_cast(color_value[mode]*alpha); + mode++; // increase mode + if(mode >= 3) mode = 0; // reset mode if greater than equal three + swapColors(frame, i, z);// swap colors + if(isNegative == true) { // if is negative true + invert(frame, i, z);// invert pixel + } + } + } + sw = !sw;// not sw + tr = !tr;// not tr + static double max = 4.0f; + if(alpha < 0) + trans_var = translation_variable; + else if(alpha > max) { + trans_var = -translation_variable; + max += 3.0f; + if(max > 23) max = 4.0f; + } + alpha += trans_var; // add to alpha + resetAlpha(alpha); +} +// blend with original pixel +void ac::Pass2Blend(cv::Mat &frame) { + for(int z = 0; z < frame.rows; ++z) { // top to bottom + for(int i = 0; i < frame.cols; ++i) { // left to right + if(!frame.empty() && !orig_frame.empty()) { + cv::Vec3b &color1 = frame.at(z, i);// current pixel + cv::Vec3b color2 = orig_frame.at(z, i);// original frame pixel + for(int q = 0; q < 3; ++q) + color1[q] = static_cast(color2[q] * ac::pass2_alpha) + static_cast(color1[q] * ac::pass2_alpha); + //color1[q] = static_cast(color2[q]+(color1[q]*ac::pass2_alpha));// multiply + } + } + } +} + +// Takes cv::Mat reference +void ac::RandTriBlend(cv::Mat &frame) { + static double alpha = 1.0f;//alpha equals 1.0 + static int i = 0, z = 0;// i,z loop variables + int counter = 0;// center variable + cv::Vec3b colors[6];// array of six colors + for (z = 2; z < frame.cols - 2; ++z) { + for (i = 2; i < frame.rows - 2; ++i) { + // grab pixels + colors[0] = frame.at(i, z); + colors[1] = frame.at(i + 1, z); + colors[2] = frame.at(i + 2, z); + // chaos + counter = rand() % 3; + if (counter == 0) { // if counter equals zero + // set pixel values + colors[3][0] = static_cast((colors[0][0] + colors[1][0] + colors[2][0]*alpha)); + colors[3][1] = static_cast((colors[0][1] + colors[1][1]) * alpha); + colors[3][2] = static_cast((colors[0][2]) * alpha); + counter++; // increase counter + } else if (counter == 1) { // if counter equals one + // set pixel values + colors[3][0] = static_cast((colors[0][0]) * alpha); + colors[3][1] = static_cast((colors[0][1] + colors[1][1]) * alpha); + colors[3][2] = static_cast((colors[0][2] + colors[1][2] + colors[2][2]) * alpha); + counter++; // increase counter + } else { + // set pixel values + colors[3][0] = static_cast((colors[0][0]) * alpha); + colors[3][2] = static_cast((colors[0][1] + colors[1][1]) * alpha); + colors[3][1] = static_cast((colors[0][2] + colors[1][2] + colors[2][2]) * alpha); + } + cv::Vec3b &color_value = frame.at(i, z);// grab current pixel + color_value = colors[3];// assign pixel + swapColors(frame, i, z);// swap colors + if(isNegative == true) { // if isNegative + invert(frame, i, z);// invert pixel + } + } + } + static double max = 4.0f, trans_var = translation_variable;// max, translation variable + if (alpha < 0) // if alpha less than zero + trans_var = translation_variable; + else if (alpha > max) { + trans_var = -translation_variable; + max += 3.0f; + if (max > 23) + max = 4.0f; + } + alpha += trans_var;// add to alpha translation variable + resetAlpha(alpha); +} + +// Blank +// takes cv::Mat reference +void ac::Blank(cv::Mat &frame) { + static double alpha = 1.0f; // static alpha set to 1.0 + static unsigned char val[3] = { 0 };// val array set to zero + static bool color_switch = false;// color switch set to false + for(int z = 0; z < frame.cols; ++z) {// left to right + for(int i = 0; i < frame.rows; ++i) { // top to bottom + cv::Vec3b &color_value = frame.at(i, z); // current pixel + for(int j = 0; j < 3; ++j) { + // process pixel values + val[j] = static_cast((alpha*color_value[j]) / (2-j+1)); + color_value[j] += static_cast(val[2-j] / (j+1)); + if(color_switch == true) color_value[j] = static_cast(-color_value[j]); + } + swapColors(frame, i, z); + if(isNegative == true) { + invert(frame, i, z); // invert pixel + } + } + } + color_switch = !color_switch;// not color switch + static double max = 4.0f, trans_var = translation_variable; + if (alpha < 0) + trans_var = translation_variable; // positive (up) + else if (alpha > max) { + trans_var = -translation_variable; // negative (down) + max += 3.0f; + if (max > 23) + max = 4.0f; + } + alpha += trans_var; // add to alpha trans_Var + resetAlpha(alpha); +} +// Tri +// takes cv::Mat reference +void ac::Tri(cv::Mat &frame) { + static double alpha = 1.0f;// static alpha set to 1 + for(int z = 0; z < frame.cols-3; ++z) {// left to right + for(int i = 0; i < frame.rows-3; ++i) {// top to bottom + cv::Vec3b &color_value = frame.at(i, z);// current pixel + cv::Vec3b colors[2];// colors + // grab pixels + colors[0] = frame.at(i+1, z); + colors[1] = frame.at(i+2, z); + // set pixels + color_value[0] += static_cast(color_value[0]*alpha); + color_value[1] += static_cast(color_value[1]+colors[0][1]+colors[1][1]*alpha); + color_value[2] += static_cast(color_value[2]+colors[0][2]+colors[1][2]*alpha); + swapColors(frame, i, z);// swap + if(isNegative == true) { + invert(frame, i, z); // invert pixel + } + } + } + static double max = 4.0f, trans_var = 0.1f; + if (alpha < 0) + trans_var = translation_variable; // positive (up) + else if (alpha > max) { + trans_var = -translation_variable; // negative (down) + max += 3.0f; + if (max > 23) + max = 4.0f; + } + alpha += trans_var;// add to alpha trans var + resetAlpha(alpha); +} +// Distort +// takes cv::Mat reference +void ac::Distort(cv::Mat &frame) { + static double alpha = 1.0f; // static alpha set to 1 + static int i = 0, z = 0;// loop variables + for(z = 0; z < frame.cols; ++z) { // left to right + for(i = 0; i < frame.rows; ++i) {// top to bottom + cv::Vec3b &color_value = frame.at(i, z); + // set pixel values + color_value[0] = static_cast((i*alpha)+color_value[0]); + color_value[2] = static_cast((z*alpha)+color_value[2]); + color_value[1] = static_cast((alpha*color_value[1])); + if(strobe_It == true) color_value[1] = static_cast(((i+z)*alpha)+color_value[1]); + swapColors(frame, i, z); //swap + if(isNegative == true) { + invert(frame, i, z);// invert + } + } + } + static double max = 4.0f, trans_var = 0.1f; + if (alpha < 0) + trans_var = 0.1f; + else if (alpha > max) { + trans_var = -0.1f; + max += 3.0f; + if (max > 23) + max = 4.0f; + } + alpha += trans_var;// add translation to alpha + resetAlpha(alpha); +} +// takes cv::Mat reference +void ac::CDraw(cv::Mat &frame) { + static int i=0,z=0;// loop variables + static double rad = 80.0f;// radius + static double deg = 1.0f;// degrees + for(z = 0; z < frame.cols; ++z) { // left to right + for(i = 0; i < frame.rows; ++i) {// top to bottom + int cX = static_cast((rad * cos(deg))); + int cY = static_cast((rad * sin(deg))); + cv::Vec3b &color_value = frame.at(i, z); // grab pixel reference + // set values + color_value[0] = static_cast(color_value[0]*(cX * alpha)); + color_value[1] = static_cast(color_value[1]*(cY * alpha)); + color_value[2] = static_cast(color_value[2]*alpha); + deg += 0.1f; + swapColors(frame, i, z);// swap + if(isNegative) invert(frame, i, z);// if isNegative invert + } + } + alpha += 0.1f;// add to alpha + rad += 0.1f;// add to rad + if(rad > 90) rad = 0;// greater than 90 reset + if(alpha > 20) alpha = 0;// greater than 20 reset + resetAlpha(alpha); +} +// Light Strobe +// first cycle through the image +// add a variable to each individual pixel (the input sould be different each frame) +// reason for this is adding to the captured image each frame causes a animation a distortion +// each frame the largest value is calculated by adding the rgb values together for one element each iteration. +// test this first +void ac::Type(cv::Mat &frame) { + int i = 0, z = 0;// loop variables + static double add_r = 1.0; // add_r + static int off = 0;// off variable + for(z = 0; z < frame.rows; ++z) { // top to bottom + for(i = 0; i < frame.cols; ++i) {// left to right + cv::Vec3b ¤t = frame.at(z, i); // grab pixel reference + // set pixel values + current[0] += static_cast(add_r+current[0]); + current[1] += static_cast(add_r+current[1]); + current[2] += static_cast(add_r+current[2]); + // set value indexed by off which changes each frame + current[off] = current[0]+current[1]+current[2]; + swapColors(frame, z, i);// swap the colors + if(isNegative) invert(frame, z, i); // invert pixel + } + } + ++off;// increase off + if(off > 2) off = 0;// greater than two set to zero + add_r += rand()%255;// random distortion plus equals random number + if(add_r > 255) add_r = 0;// greater than 255 set to zero +} +// New One +// takes cv::Mat reference +void ac::NewOne(cv::Mat &frame) { + for(int z = 0; z < frame.cols; ++z) {// left to right + for(int i = 1; i < frame.rows-1; ++i) {// top to bottom + cv::Vec3b &colv = frame.at(i, z);// get pixels + cv::Vec3b &cola = frame.at((frame.rows-1)-i, (frame.cols-1)-z);//frame.at((frame.cols-1)-z, (frame.rows-1)-i); + // set arrays + int red_values[] = { colv[0]+cola[2], colv[1]+cola[1], colv[2]+cola[0], 0 }; + int green_values[] = { colv[2]+cola[0], colv[1]+cola[1], colv[0]+cola[2], 0 }; + int blue_values[] = { colv[1]+cola[1], colv[0]+cola[2], colv[2]+cola[0], 0 }; + unsigned char R = 0,G = 0,B = 0; + // loop through arrays + for(int iq = 0; iq <= 2; ++iq) { + R += red_values[iq]; + R /= 3; + G += green_values[iq]; + G /= 3; + B += blue_values[iq]; + B /= 3; + } + // set pixel values + colv[0] += static_cast(alpha*R); + colv[1] += static_cast(alpha*G); + colv[2] += static_cast(alpha*B); + swapColors(frame, i, z);//swap colors + if(isNegative) invert(frame, i, z); // if isNegative invert pixel + } + } + static double max = 8.0f, trans_var = 0.1f;// max and translation + if (alpha < 0) + trans_var = 0.1f; + else if (alpha > max) { + trans_var = -0.1f; + max += 3.0f; + if (max > 23) + max = 4.0f; + } + alpha += trans_var;// add translation variable + resetAlpha(alpha); + +} +// draw a fractal +void ac::blendFractal(cv::Mat &frame) { + frac::FractalLogic(); + frac::DrawFractal(frame, ac::isNegative); +} + +// draw a fractal with background color blended +void ac::blendFractalMood(cv::Mat &frame) { + // random + unsigned char color = 0; + color = rand()%255; + static bool shift = true; + static bool shift_value = true; + for(int z = 0; z < frame.cols; ++z) {// left to right + for(int i = 0; i < frame.rows; ++i) {// top to bottom + cv::Vec3b &color_value = frame.at(i, z);// grab pixel + // set pixel values + color_value[0] += (shift == shift_value) ? color : -color; + color_value[1] += (shift == shift_value) ? -color : color; + color_value[2] += (shift == shift_value) ? color : -color; + shift_value = !shift_value;// not shift value + } + } + shift = ! shift;// not shift value + frac::FractalLogic(); + frac::DrawFractal(frame, ac::isNegative); // draw fractal +} + +// blend with Image functions Resize X +inline int ac::GetFX(cv::Mat &frame, int x, int nw) { + double xp = (double)x * (double)frame.rows / (double)nw; + return (int)xp; +} +// blend with Image function Resize Y +inline int ac::GetFY(cv::Mat &frame, int y, int nh) { + double yp = (double)y * (double)frame.cols / (double)nh; + return (int)yp; +} +// blend with Image function +// takes cv::Mat as reference +void ac::blendWithImage(cv::Mat &frame) { + if(!blendW_frame.data) // if image not loaded return + return; + static double alpha = 1.0f; // set alpha to 1 + static double beta = 1.0f; // set beta to 1 + for(int z = 0; z < frame.cols; ++z) {// left to right + for(int i = 0; i < frame.rows; ++i) {// top to bottom + // get resized pixel values + int q = GetFX(blendW_frame, i, frame.rows); + int j = GetFY(blendW_frame, z, frame.cols); + // grab pixels + cv::Vec3b &frame_one = frame.at(i, z); + cv::Vec3b &frame_two = blendW_frame.at(q, j); + // set pixel values + for(int p = 0; p < 3; ++p) + frame_one[p] += static_cast((frame_one[p]*alpha)+(frame_two[p]*beta)); + swapColors(frame, i, z); // swap colors + if(isNegative == true) { + invert(frame, i, z);// invert pixel + } + } + } + // move alpha and beta values up and down + static double max = 4.0f, trans_var = 0.1f; + if (alpha < 0) + trans_var = translation_variable; + else if (alpha > max) { + trans_var = -translation_variable; + max += 3.0f; + if (max > 23) + max = 4.0f; + } + alpha += trans_var; + beta += -trans_var; +} +// triBlend with Image unused +void ac::triBlendWithImage(cv::Mat &frame) { + if(images_Enabled == false) return; + static double alpha = 1.0f, beta = 1.0f; + static int i = 0, z = 0, j = 0; + for(z = 0; z < frame.cols; ++z) { + for(i = 0; i < frame.rows; ++i) { + cv::Vec3b colors[3]; + cv::Vec3b &color_value = frame.at(i, z); + int cx[3] = { ac::GetFX(image_files[0], i, frame.rows), ac::GetFX(image_files[1], i, frame.rows), ac::GetFX(image_files[2], i, frame.rows) }; + int cy[3] = { ac::GetFY(image_files[0], z, frame.cols), ac::GetFY(image_files[1], z, frame.cols), ac::GetFY(image_files[2], z, frame.cols) }; + for(j = 0; j < 3; ++j) { + colors[j] = image_files[j].at(cx[j], cy[j]); + } + color_value[0] = static_cast(((color_value[0]+colors[0][0])/2)*alpha); + color_value[1] += static_cast(((color_value[1]+colors[0][1])/2)*alpha); + color_value[2] = static_cast(((color_value[2]+colors[0][2]+colors[1][2]+colors[2][2])/3)*beta); + swapColors(frame, i, z); + if(isNegative == true) { + invert(frame, i, z); + } + } + } + static double max = 4.0f, trans_var = 0.1f; + if (alpha < 0) + trans_var = translation_variable; + else if (alpha > max) { + trans_var = -translation_variable; + max += 3.0f; + if (max > 23) + max = 4.0f; + } + alpha += trans_var; + beta += -trans_var; +} + +// Image Strobe - unused +void ac::imageStrobe(cv::Mat &frame) { + if(images_Enabled == false) return; + static double alpha = 1.0f; + static int i = 0, z = 0, j = 0, image_offset = 0; + for(z = 0; z < frame.cols; ++z) { + for(i = 0; i < frame.rows; ++i) { + cv::Vec3b colors[3]; + cv::Vec3b &color_value = frame.at(i, z); + int cx[3] = { ac::GetFX(image_files[0], i, frame.rows), ac::GetFX(image_files[1], i, frame.rows), ac::GetFX(image_files[2], i, frame.rows) }; + int cy[3] = { ac::GetFY(image_files[0], z, frame.cols), ac::GetFY(image_files[1], z, frame.cols), ac::GetFY(image_files[2], z, frame.cols) }; + for(j = 0; j < 3; ++j) + colors[j] = image_files[j].at(cx[j], cy[j]); + for(j = 0; j < 3; ++j) + color_value[j] += static_cast((colors[image_offset][j]*alpha)); + swapColors(frame, i, z); + if(isNegative == true) { + invert(frame, i, z); + } + } + } + ++image_offset; + if(image_offset >= 4) image_offset = 0; + static double max = 4.0f, trans_var = 0.1f; + if (alpha < 0) + trans_var = translation_variable; + else if (alpha > max) { + trans_var = -translation_variable; + max += 3.0f; + if (max > 23) + max = 4.0f; + } + alpha += trans_var; + resetAlpha(alpha); +} +// Image distraction - unused +void ac::imageDistraction(cv::Mat &frame) { + if(images_Enabled == false) return; + static double alpha = 1.0f; + static int i = 0, z = 0, im_off = 2; + for(z = 0; z < frame.cols; ++z) { + for(i = 0; i < frame.rows; ++i) { + cv::Vec3b &color_value = frame.at(i, z); + int cX = GetFX(image_files[im_off], i, frame.rows), cY = GetFY(image_files[im_off], z, frame.cols); + cv::Vec3b manip_color = image_files[im_off].at(cX, cY); + color_value[0] = static_cast((z*alpha)+color_value[0]); + color_value[1] = static_cast(manip_color[1]*alpha); + color_value[2] = static_cast((i*alpha)+color_value[2]); + swapColors(frame, i, z); + if(isNegative) invert(frame, i, z); + } + } + ++im_off; + if(im_off >= 4) im_off = 0; + static double max = 4.0f, trans_var = 0.1f; + if (alpha < 0) + trans_var = 0.1f; + else if (alpha > max) { + trans_var = -0.1f; + max += 3.0f; + if (max > 23) + max = 4.0f; + } + alpha += trans_var; + resetAlpha(alpha); +} + +// Cos Sin Mulitply draw gradients +// takes cv::Mat reference +void ac::cossinMultiply(cv::Mat &frame) { + static double alpha = 1.0f;// set static alpha to 1.0 + static int i = 0, z = 0;// loop variables + for(z = 0; z < frame.cols; ++z) {// left to right + for(i = 0; i < frame.rows; ++i) {// top to bottom + cv::Vec3b &buffer = frame.at(i, z); // grab pixel + // set pixel values + buffer[0] += static_cast(1+static_cast((sin(alpha))*z)); + buffer[1] += static_cast(1+static_cast((cos(alpha))*i)); + buffer[2] += static_cast((buffer[0]+buffer[1]+buffer[2])/3); + swapColors(frame, i, z);// swap colors + if(isNegative) invert(frame, i, z);// invert pixel + } + } + // add alpha up to 24 return to zero when greater + static double trans_var = 0.05f; + if(alpha > 24) alpha = 1.0f; + alpha += trans_var; + resetAlpha(alpha); +} +// Color Accumulate 1 +void ac::colorAccumulate1(cv::Mat &frame) { + static double alpha = 1.0f; // alpha to 1.0 + static int i = 0, z = 0; // static loop variables + for(z = 0; z < frame.cols; ++z) {// left to right + for(i = 0; i < frame.rows; ++i) {// top to bottom + cv::Vec3b &buffer = frame.at(i, z);// current pixel + // set pixel values + buffer[0] += static_cast((buffer[2]*alpha)); + buffer[1] += static_cast((buffer[0]*alpha)); + buffer[2] += static_cast((buffer[1]*alpha)); + swapColors(frame, i, z); // swap colors + if(isNegative) invert(frame, i, z);// invert pixel + } + } + // increase alpha until 24 then reset + static double trans_var = 0.05f; + alpha += trans_var; + if(alpha > 24) alpha = 1.0f; + resetAlpha(alpha); +} +// Color Accumulate 2 +void ac::colorAccumulate2(cv::Mat &frame) { + static double alpha = 1.0f;// static alpha set to 1.0 + static int i = 0, z = 0;// loop variables + for(z = 0; z < frame.cols; ++z) {// left to right + for(i = 0; i < frame.rows; ++i) {// top to bottom + // grab pixel + cv::Vec3b &buffer = frame.at(i, z); + // set pixel rgb values + buffer[0] += static_cast((buffer[2]*alpha)+i); + buffer[1] += static_cast((buffer[0]*alpha)+z); + buffer[2] += static_cast((buffer[1]*alpha)+i-z); + swapColors(frame, i, z);// swap + if(isNegative) invert(frame, i, z);// if isNegative invert + } + } + static double trans_var = 0.05f;// translation variable + alpha += trans_var;// alpha plus equal translation variable + if(alpha > 24) alpha = 1.0f;// if alpha greater than 24 reset to 1 + resetAlpha(alpha); +} +// Color Accumulate #3 +// takes cv::Mat reference +void ac::colorAccumulate3(cv::Mat &frame) { + static double alpha = 1.0f;// set alpha to 1.0 + static int i = 0, z = 0;// loop variables + for(z = 0; z < frame.cols; ++z) {// from left to right + for(i = 0; i < frame.rows; ++i) {// from top to bottom + cv::Vec3b &buffer = frame.at(i, z);// grab pixel reference + // set rgb values + buffer[0] = static_cast((-buffer[2])+z); + buffer[1] = static_cast((-buffer[0])+i); + buffer[2] = static_cast((-buffer[1])+alpha); + swapColors(frame, i, z);// swap colors + if(isNegative) invert(frame, i, z);// if isNegative true invert pixel + } + } + static double trans_var = 0.05f;// 0.05 variable + alpha += trans_var;// alpha plus equal translation variable + if(alpha > 24) alpha = 1.0f;// alpha greater than 24 set to 1 (reset) + resetAlpha(alpha); +} + +// takes cv::Mat reference +void ac::filter8(cv::Mat &frame) { + static double alpha = 1.0f;// set static alpha to 1.0 + static int i = 0, z = 0, q = 0;// loop variable + for(z = 0; z < frame.cols; ++z) {// from left to right + for(i = 0; i < frame.rows; ++i) {// from top to bottom + cv::Vec3b &buffer = frame.at(i, z);// grab pixel + for(q = 0; q < 3; ++q) {// loop each rgb value + buffer[q] = static_cast(buffer[q]+((i+z)*alpha));// preform calculation + + } + swapColors(frame, i, z);// swap colors + if(isNegative) invert(frame, i, z);// if isNegative invert + } + } + // static direction equals 1 + static int direction = 1; + if(direction == 1) {// if direction equals 1 + alpha += 0.05f;// alpha plus equal 0.05 + if(alpha > 3) { alpha = 3; direction = 2; }// alpha greater than 3 set direction to 2 + } else { + alpha -= 0.05f;// alpha minus equal 0.05 + if(alpha <= 0.1f) { alpha = 0.1f; direction = 1; }//alpha greater than 3 set direction to 1 + } + resetAlpha(direction, alpha); +} + +// takes cv::Mat reference +void ac::filter3(cv::Mat &frame) { + static double alpha = 1.0f;// set static alpha to 1.0 + static int i = 0, z = 0, q = 0;// loop variables + for(z = 0; z < frame.cols; ++z) {// left to right + for(i = 0; i < frame.rows; ++i) {// top to bottom + cv::Vec3b &buffer = frame.at(i, z);// grab pixel reference + for(q = 0; q < 3; ++q) {// loop through rgb values + buffer[q] = static_cast(buffer[0]+(buffer[q])*(alpha));// preform calculation + } + swapColors(frame, i, z);// swap colors + if(isNegative) invert(frame, i, z);// if isNegative invert pixel + } + } + // direction equals 1 + static int direction = 1; + if(direction == 1) { // if direction equals 1 + alpha += 0.1f;// alpha plus equal 0.1 + if(alpha > 6) { alpha = 6; direction = 2; } // if alpha greater than 6 set alpha to 6 direction to 2 + } else { + alpha -= 0.05f;// alpha minus equal 0.1 + if(alpha <= 0.1f) { alpha = 0.1f; direction = 1; } // if alpha lses than equal 0.1 set to 0.1 direction equals 1 + } + resetAlpha(direction, alpha); +} + +// takes cv::Mat as reference +// uses 3 static variables to represent the RGB values +// to mulitply by the alpha variable +// each frame they either increase or are reset to a random number when set to zero +// when they reach a number greater than 255 they are reset to zero +void ac::rainbowBlend(cv::Mat &frame) { + static double alpha = 1.0f;// set static alpha to 1.0 + static int rb = 0, gb = 0, bb = 0;// set static integer r,g,b values + if(rb == 0) // if rb equals 0 + rb = rand()%255;// set rb to random number + else ++rb;// else increase rb + if(gb == 0) // if gb equals 0 + gb = rand()%255;// gb equals random number + else ++gb;// else gb increases + if(bb == 0) // if bb equals 0 + bb = rand()%255;// bb equals random number + else ++bb;// else increase bb + static int i = 0, z = 0;// loop variables + for(z = 0; z < frame.cols; ++z) {// left to right + for(i = 0; i < frame.rows; ++i) {// top to bottom + // grab pixel as cv::Vec3b reference + cv::Vec3b &buffer = frame.at(i, z); + // add to rgb values alpha * rb,gb,bb variables + buffer[0] += static_cast(alpha*rb); + buffer[1] += static_cast(alpha*gb); + buffer[2] += static_cast(alpha*bb); + swapColors(frame, i, z);// swap colors + if(isNegative) invert(frame, i, z);// if isNegative invert pixel + } + } + // if rb greater than 255 set to zero + if(rb > 255) rb = 0; + // if gb greater than 255 set to zero + if(gb > 255) gb = 0; + // if bb greater than 255 set to zero + if(bb > 255) bb = 0; + // static int direction equals 1 + static int direction = 1; + if(direction == 1) {// if direction equals 1 + alpha += 0.1f;// increase alpha + // alpha greater than 6 change direction + if(alpha > 6) { alpha = 6; direction = 2; } + } else { + // decrease alpha + alpha -= 0.05f; + // if alpha <= 0.1 change direction + if(alpha <= 0.1f) { alpha = 0.1f; direction = 1; } + } + resetAlpha(direction, alpha); +} + +// random pixel value added to each pixel RGB value each frame +// takes cv::Mat reference +void ac::randBlend(cv::Mat &frame) { + unsigned char rr = rand()%255;// random Red + unsigned char rg = rand()%255;// random Green + unsigned char rb = rand()%255;// random Blue + static int i = 0, z = 0;// i,z loop variables + for(z = 0; z < frame.cols; ++z) {// from left to right + for(i = 0; i < frame.rows; ++i) {// from top to bottom + cv::Vec3b &buffer = frame.at(i, z);// pixel at + buffer[0] += rr;// add random R + buffer[1] += rg;// add random G + buffer[2] += rb;// add random B + swapColors(frame, i, z);// swap colors + if(isNegative) invert(frame, i, z);// if negative, invert pixel + } + } +} + +// takes cv::Mat reference +void ac::newBlend(cv::Mat &frame) { + static int pos = 300; // static int pos equal 300 + static int i = 0, z = 0;// loop variables + for(z = 0; z < frame.cols; ++z) {// left to right + for(i = 0; i < frame.rows; ++i) {// top to bottom + // grab pixel + cv::Vec3b &buffer = frame.at(i, z); + // set pixel RGB values + buffer[0] = static_cast(buffer[2]+(1+(i*z)/pos)); + buffer[1] = static_cast(buffer[1]+(1+(i*z)/pos)); + buffer[2] = static_cast(buffer[0]+(1+(i*z)/pos)); + swapColors(frame, i, z);// swap colors + if(isNegative) invert(frame, i, z);// if(isNegative) invert pixel + } + } + static int dir = 1;// static direction equals 1 + if(dir == 1) {// dir equals 1 + pos += 25;// pos plus equal 25 + if(pos > 1024) {// greater than 1024 + pos = 1024; + dir = 2;// set direction to 2 + } + } + else {// direction != 1 + pos -= 25;// minus 25 + if(pos < 100) {// less than 100 + pos = 100; + dir = 1;// set direction to 1 + } + } +} +// pixelScale +// takes cv::Mat reference +void ac::pixelScale(cv::Mat &frame) { + static double pos = 1.0f;// pos equals 1.0 + static int i = 0, z = 0;// loop variables + for(z = 0; z < frame.cols; ++z) {// left to right + for(i = 0; i < frame.rows; ++i) {// top to bottom + // grab pixel reference + cv::Vec3b &buffer = frame.at(i, z); + cv::Vec3b buf = buffer;// temp pixel + // set RGB pixel values + buffer[0] = static_cast((buf[0]*pos)+(buf[0]-buffer[2])); + buffer[1] = static_cast((buf[1]*pos)+(buf[1]+buffer[1])); + buffer[2] = static_cast((buf[2]*pos)+(buf[2]-buffer[0])); + swapColors(frame, i, z);// swap colors + if(isNegative) invert(frame, i, z);// if isNegative invert pixel + } + } + static int direction = 1;// direction equals 1 + static double pos_max = 3.0f;// pos_max equals 3.0 + if(direction == 1) {// direction equals 1 + pos += 0.1f;// plus equal 0.1 + if(pos > pos_max) {// greater than pos_max + pos = pos_max; + direction = 0;// set direction to zero + pos_max += 0.5f;// increase pos_max + } + } else if(direction == 0) {// direction equals 0 + pos -= 0.1f;// pos minus equal 0.1 + if(pos <= 0) {// pos less than equal 0 + if(pos_max > 15) pos_max = 1.0f;// pos_max > 14 reset + direction = 1;// direction set back to 1 + } + } + resetAlpha(direction, pos); + +} diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/ac-box.cpp b/windows/Acid.Cam.Qt.Windows.March.2019/ac-box.cpp new file mode 100755 index 0000000..768e428 --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/ac-box.cpp @@ -0,0 +1,103 @@ +/* + * Software written by Jared Bruni https://github.com/lostjared + + This software is dedicated to all the people that experience mental illness. + + Website: http://lostsidedead.com + YouTube: http://youtube.com/LostSideDead + Instagram: http://instagram.com/jaredbruni + Twitter: http://twitter.com/jaredbruni + Facebook: http://facebook.com/LostSideDead0x + + You can use this program free of charge and redistrubute it online as long + as you do not charge anything for this program. This program is meant to be + 100% free. + + BSD 2-Clause License + + Copyright (c) 2019, Jared Bruni + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + */ + +#include"ac.h" + +int ac::Box::frame_width = 0; +int ac::Box::frame_height = 0; + +void ac::Box::initBox(int width, int height) { + x = (rand()%width); + y = (rand()%height); + w = rand()%25; + h = rand()%25; + steps = rand()%10; + index = 0; + do { + frame_index = rand()%28; + } while(frame_index == 13 || frame_index == 14); +} + +void ac::Box::drawBox(cv::Mat &frame) { + cv::Mat temp; + temp.create(cvSize(w, h), CV_8UC3); + for(int yy = y, pos_y = 0; yy < y+h && yy < frame_height; ++yy, ++pos_y) { + for(int ii = x,pos_x = 0; ii < x+w && ii < frame_width; ++ii, ++pos_x) { + cv::Vec3b pixel = frame.at(yy, ii); + cv::Vec3b &target = temp.at(pos_y, pos_x); + target = pixel; + } + } + CallFilter(frame_index, temp); + for(int z = y, pos_y = 0; z < y+h && z < frame_height; ++z, ++pos_y) { + for(int i = x, pos_x = 0; i < x+w && i < frame_width; ++i, ++pos_x) { + if(i < frame.cols && z < frame.rows) { + cv::Vec3b &pixel = frame.at(z, i); + pixel = temp.at(pos_y,pos_x); + } + } + } +} + +void ac::Box::sizeBox() { + if(index > steps) { + initBox(frame_width, frame_height); + return; + } + ++index; + int r1 = rand()%10; + int r2 = rand()%10; + if(w+r1 > frame_width) { + initBox(frame_width, frame_height); + return; + } else { + w += r1; + } + if(h+r2 > frame_height) { + initBox(frame_width, frame_height); + return; + } else { + h += r2; + } +} + diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter1.cpp b/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter1.cpp new file mode 100755 index 0000000..8304873 --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter1.cpp @@ -0,0 +1,273 @@ +/* + * Software written by Jared Bruni https://github.com/lostjared + + This software is dedicated to all the people that experience mental illness. + + Website: http://lostsidedead.com + YouTube: http://youtube.com/LostSideDead + Instagram: http://instagram.com/jaredbruni + Twitter: http://twitter.com/jaredbruni + Facebook: http://facebook.com/LostSideDead0x + + You can use this program free of charge and redistrubute it online as long + as you do not charge anything for this program. This program is meant to be + 100% free. + + BSD 2-Clause License + + Copyright (c) 2019, Jared Bruni + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + */ + +#include "ac.h" +// Acid Cam namespace +namespace ac { +#if defined(__APPLE__) + const std::string version="2.20.0 (macOS)"; +#elif defined(__linux__) + const std::string version="2.20.0 (Linux)"; +#elif defined(_WIN32) + const std::string version="2.20.0 (Windows)"; +#else + const std::string version="2.20.0 (Generic)"; +#endif + // variables + int swapColor_r = 0, swapColor_g = 0, swapColor_b = 0; + bool isNegative = false, noRecord = false, pass2_enabled = false, blendW = false, slide_Show = false, slide_Rand = false, strobe_It = false, switch_Back = false, blur_First = false; + bool images_Enabled = false, fps_force = false,iRev = false; + bool blur_Second = false; + int set_color_map = 0; + cv::Mat orig_frame; + cv::Mat blendW_frame; + cv::Mat image_files[4]; + double alpha = 1.0f, tr = 0.01f; + double fps = 29.97; + int draw_offset = 0; + bool snapShot = false; + int color_order = 0; + int snapshot_Type = 0; + bool in_custom = false; + cv::Size resolution(0, 0); + std::string fileName ="VideoFile.avi"; + std::string draw_strings_value[] = { "Self AlphaBlend", "Self Scale", "StrobeEffect", "Blend #3", "Negative Paradox","ThoughtMode", "RandTriBlend", "Blank", "Tri", "Distort", "CDraw", "Type", "NewOne", "Blend Fractal","Blend Fractal Mood", "CosSinMultiply", "Color Accumlate1", "Color Accumulate2", "Color Accumulate3", "Filter8","Filter3","Rainbow Blend","Rand Blend","New Blend", "Alpha Flame Filters", "Pixel Scale", "PixelSort", "GlitchSort","Random Filter", "Random Flash", "Blend with Image", "Blend with Image #2", "Blend with Image #3", "Blend with Image #4", "GaussianBlur", "Median Blur", "Blur Distortion", "Diamond Pattern","MirrorBlend","Pulse","Sideways Mirror","Mirror No Blend","Sort Fuzz","Fuzz","Double Vision","RGB Shift","RGB Sep","Graident Rainbow","Gradient Rainbow Flash", "Reverse", "Scanlines", "TV Static", "Mirror Average", "Mirror Average Mix", "Mean", "Laplacian", "Bitwise_XOR", "Bitwise_AND","Bitwise_OR","Equalize", "Channel Sort", "Reverse_XOR", "Combine Pixels", "FlipTrip", "Canny","Boxes","Boxes Fade", "Flash Black","SlideRGB","Side2Side","Top2Bottom","Strobe Red Then Green Then Blue","Blend_Angle", "Outward", "Outward Square","ShiftPixels", "ShiftPixelsDown", "XorMultiBlend", "Bitwise_Rotate", "Bitwise_Rotate Diff","HPPD","FuzzyLines","GradientLines","GradientSelf","GradientSelfVertical","GradientDown","GraidentHorizontal","GradientRGB","Inter","UpDown","LeftRight","StrobeScan","BlendedScanLines","GradientStripes","XorSine","SquareSwap","SquareSwap4x2","SquareSwap8x4","SquareSwap16x8","SquareSwap64x32","SquareBars","SquareBars8","SquareSwapRand16x8","SquareVertical8","SquareVertical16","SquareVertical_Roll","SquareSwapSort_Roll","SquareVertical_RollReverse","SquareSwapSort_RollReverse","Circular","WhitePixel","FrameBlend","FrameBlendRGB","TrailsFilter","TrailsFilterIntense","TrailsFilterSelfAlpha","TrailsFilterXor","ColorTrails","MoveRed","MoveRGB","MoveRedGreenBlue","BlurSim","Block","BlockXor","BlockScale","BlockStrobe","PrevFrameBlend","Wave","HighWave","VerticalSort","VerticalChannelSort","HorizontalBlend","VerticalBlend","OppositeBlend","DiagonalLines","HorizontalLines","InvertedScanlines","Soft_Mirror","KanapaTrip","ColorMorphing","ScanSwitch","ScanAlphaSwitch","NegativeStrobe", "XorAddMul","ParticleRelease", "BlendSwitch", "All Red", "All Green", "All Blue","LineRGB","PixelRGB","BoxedRGB","KruegerSweater","RGBFlash","IncreaseBlendHorizontal","BlendIncrease","GradientReverse","GradientReverseVertical","GradientReverseBox","GradientNewFilter","ReinterpretDouble","ReinterpSelfScale","AverageLines","ImageFile","ImageXor","ImageAlphaBlend","ColorRange","ImageInter","TrailsInter","TrailsBlend","TrailsNegate","InterReverse","InterMirror","InterFullMirror","MirrorRGB","RGBStatic1","RGBStatic2","VectorIncrease","LineByLineReverse","RandomIntertwine","RandomFour","BlendThree","AcidTrails","RandomTwo","HorizontalTrailsInter","Trails","BlendTrails","Negate","RandomFilteredSquare","ImageX","RandomQuads","QuadCosSinMultiply","QuadRandomFilter","RollRandom","AverageRandom","HorizontalStripes","DiamondStrobe","SmoothTrails","GridFilter8x","GridFilter16x","GridFilter8xBlend","GridRandom","GridRandomPixel","Dual_SelfAlphaRainbow","Dual_SelfAlphaBlur","SurroundPixelXor","Darken","WeakBlend","AverageVertical","RandomCollectionAverage","RandomCollectionAverageMax","SmoothTrailsSelfAlphaBlend","SmoothTrailsRainbowBlend","MedianBlend","SmoothRandomImageBlend","SmoothImageAlphaBlend","RandomAlphaBlend","RandomTwoFilterAlphaBlend","PixelatedSquare","AlphaBlendPosition","BlendRowAlpha", "BlendRow","BlendRowByVar","BlendRowByDirection","BlendAlphaXor","SelfXorScale","BitwiseXorScale","XorTrails", "RainbowTrails","NegativeTrails","IntenseTrails","SelfAlphaRGB","BlendImageOnOff","XorSelfAlphaImage","BitwiseXorStrobe","AlphaBlendRandom","ChannelSortAlphaBlend","XorChannelSort","GradientColors","GradientColorsVertical","Bitwise_XOR_Average","NotEqual","ImageShiftUpLeft","GradientXorSelfScale","SmoothSourcePixel","StrobeBlend","FrameBars","Sort_Vertical_Horizontal","Sort_Vertical_Horizontal_Bitwise_XOR","Scalar_Average_Multiply","Scalar_Average","Total_Average","AlphaBlendImageXor","FlashWhite","FlashBlackAndWhite","GaussianBlend","RandomXor","RandomXorFlash","RandomAmountMedianBlur","SoftXor","SelfXorBlend","SelfXorDoubleFlash","SelfOrDoubleFlash","BlendRowCurvedSqrt","CycleShiftRGB","CycleShiftRandomRGB","CycleShiftRandomRGB_XorBlend","CycleShiftRandomAlphaBlend","VerticalColorBars","GradientLeftRight","GraidentUpDown","GradientLeftRightInOut","GradientUpDownInOut","Lines","ColorLines","WhiteLines","ThickWhiteLines","UseLineObject","TanAlphaGrid","MedianBlendAnimation","FibFlash", "ScaleFlash","LeftLines","Curtain","RandomCurtain","CurtainVertical","RandomCurtainVertical","inOrder","inOrderBySecond","DarkenFilter","RandomFilterBySecond","ThreeRandom","inOrderAlpha","inOrderAlphaXor","SlideFilter","SlideFilterXor", "RandomSlideFilter","SlideUpDown","SlideUpDownXor", "SlideUpDownRandom","SlideSubFilter", "SlideSubUpDownFilter","ParticleBlend","ParticleFlash","ExactImage","ParticleAlpha","BlendInAndOut","BlendScaleInAndOut","AcidGlitch","XorBackwards","LiquidFilter","MatrixXorAnd","XorAlpha","AlphaAcidTrails","SelfXorAverage","RandomXorBlend","RGBVerticalXor","RGBVerticalXorScale","RGBHorizontalXor","RGBHorizontalXorScale","FadeStrobe","RGBMirror","MirrorStrobe","AndStrobe","AndStrobeScale", "AndPixelStrobe","AndOrXorStrobe","AndOrXorStrobeScale","FadeInAndOut","BrightStrobe","DarkStrobe","ParticleFast","RandomXorOpposite","StrobeTransform","InitBlend","MoveUpLeft","RandomStrobe","RandomBlur","Stuck","StuckStrobe","OrStrobe","LagBlend","SubFilter","AddFilter","BlendImageXor","BlendImageAround_Median","ImageBlendTransform","RGBTrails","RGBTrailsDark","RGBTrailsAlpha","RGBTrailsNegativeAlpha","MovementRGBTrails","RGBTrailsXor","DifferenceStrobe","BlackAndWhiteDifferenceStrobe","DifferenceXor","DifferenceRand", "DifferenceBrightStrobe","PsycheTrails","FourSquare","EightSquare","DiagonalSquare","DiagonalSquareRandom","SquareStretchDown","SquareStretchRight","SquareStretchUp","SquareStretchLeft","DarkTrails","SoftFeedback","SoftFeedbackFrames","ResizeSoftFeedback","SoftFeedback8","SoftFeedbackFrames8","ResizeSoftFeedback8","ResizeSoftFeedbackSubFilter","SoftFeedbackRandFilter","SoftFeedback32","SoftFeedbackFrames32","ResizeSoftFeedback32","SoftFeedbackRandFilter32","SoftFeedbackSubFilter","SoftFeedbackResizeSubFilter","SoftFeedbackResize64","SoftFeedbackResizeSubFilter64","SoftFeedbackReszieSubFilter64_Negate","SoftFeedbackReszieSubFilter64_Mirror","HalfNegateStrobe","MedianBlurXor","NegateTrails","RandomGradient","RandomStrobeFlash","RandomMirror","RandomOther","RandomXorFilter","RandomMirrorBlend","RandomMirrorAlphaBlend","Bitwise_XOR_AlphaSubFilter","AlphaBlendSubFilter","GradientSubFilterXor","XorBlend_SubFilter","SmoothSubFilterAlphaBlend","SmoothSubFilterXorBlend","IntertwineSubFilter","RandBlend","EveryOther","EveryOtherSubFilter","SmoothRandomFilter","RandomFilterRandomTimes","RandomSubFilterRandomTimes","AddToFrameSubFilter","MirrorXor","MirrorXorAll","MirrorXorScale","EnergyMirror","SmoothSubFilter","EnergizeSubFilter","SmoothSubFilter16","EnergizeSubFilter16","EnergizeSubFilter32","SmoothSubFilter32","HalfAddSubFilter","HalfXorSubFilter","StaticXorBlend","PsycheSort","XorScale","ChannelMedianSubFilter","GaussianStrobe","StrobeSort","GlitchSortStrobe","Bitwise_XOR_Blend","Bitwise_XOR_Sort","Bitwise_OR_Blend","Bitwise_AND_Blend","BitwiseColorMatrix","PixelReverseXor","PixelatedSubFilterSort","SilverBlend","RandomPixelOrderSort","ImageXorAlpha","ImageAverageXor","PixelXorBlend","SelfAlphaScale","SelfScaleAlpha","RainbowXorBlend","FrameDifference","SmallDiffference","FadeBlend","FilteredDifferenceSubFilter","ExpandSquareSubFilter","ExpandSquareBlendSubFilter","ExpandSquareVerticalSubFilter","DarkImageMedianBlend","GammaDarken5","GammaDarken10","SelfAlphaScaleBlend","FadeBars","MirrorXorAlpha","MirrorEnergizeSubFilter","StrobeXor","IntertwinedMirror","BlurredMirror","ShadeRGB","InterRGB_SubFilter","InterSmoothSubFilter","InterRGB_Bars_XY","InterRGB_Bars_X","InterRGB_Bars_Y","StoredFramesAlphaBlend_SubFilter","BlendSubFilter","BlendAlphaSubFilter","ReverseFrameBlend","ReverseFrameBlendSwitch","DoubleRandomMirror","Blend_AlphaSubFilter","RandomBlendFilter","DoubleRandomBlendFilter","FlipBlendW","FlipBlendWH", "FlipBlendH", "FlipBlendAll","FrameMedianBlendSubFilter","FrameBlurSubFilter","ImageBlendSubFilter","ImageBlendXorSubFilter","ImageCollectionSubFilter","SelfScaleXorIncrease","Blend_RedGreenBlue","XorBlend_RedGreenBlue","BlendIncrease_RedGreenBlue","Blend_RedReenBlue_Dark","DarkModBlend","PictureBuzz","IncDifference","IncDifferenceAlpha","MirrorMedianBlend","SubFilterMedianBlend","DarkenBlend","DarkCollectionSubFilter","ChannelSort_NoBlend_Descending", "ChannelSort_NoBlend_Ascending","Headrush","DarkSmooth_Filter","DarkSelfAlpha","FlipMedian","FlipMedianSubFilter","FlipMirror","FlipMirrorAverage","FlipMirrorSubFilter","ShuffleMedian","ShuffleRGB","ParticleSnow","RandomPixels","DarkRandomPixels","MedianBlurSubFilter","Bars","ShuffleAlpha","AlphaMorph","ShuffleSelf","PixelatedHorizontalLines","PixelatedVerticalLines","StrobeShuffle","BlendBurred","BlendCombinedValues","RGBColorTrails","BlendCombinedValueSubFilter","BlendSubFilterAlpha","GradientXorPixels","PurpleRain","PixelByPixelXor","CopyXorAlpha","AveragePixelsXor","AveragePixelAlpha","NegativeByRow","AveragePixelCollection","IncorrectLine","XorShift","StrobeXorAndOr","XorWithSource","AlphaBlendWithSource","RGBSep1x","RGBMedianBlend","RGBMirror1","RGBMirror1Median","FlashMirror","CollectionXorSourceSubFilter","ReverseMirrorX","MirrorXorAll_Reverse","MirrorRGBReverse","MirrorRGBReverseBlend","BlendReverseSubFilter","MirrorBitwiseXor","SmoothBlendReverseSubFilter","RandomIncrease","MedianBlend16","MedianBlendBufferSubFilter","BGRBlend","RGBBlend","RGBBlendSubFilter","DivideAndIncH","DivideAndIncW","XorOppositeSubFilter","BlendSmoothSubFilter","BlurSmooth","BlurSmoothMedian","BlurSmoothSubFilter","BlurFlip","BlurFlipSubFilter","BlurMirrorGamma","MedianBlendDark","MedianBlendSubFilterEx","EnergyMirrorDark","AlphaBlendMirror","MirrorAlphaBlendedImage","AlphaBlendXorImage","ShiftFrameSmoothSubFilter","ShiftFrameStaticXorSubFilter","IncreaseDecreaseGamma","GammaIncDecIncrease","RandomSubFilter","TwistedVision","TwistedMirror","SelfScaleSortBlend","FlashMedianBlend","BlendWithFrameSubFilter","AlphaBlendWithFrameSubFilter","AlphaXorBlendWithFrameSubFilter","XorBlendSubFilter","FlipAlphaBlend","RandomFlipFilter","MirrorMedian","FlipMatrixCollection","MirrorMatrixCollection","MirrorMatrixSource","SelfScaleByFrame","SmoothMedianRotateSubFilter","SmoothCollectionAlphaBlend","XorSubFilter","XorAlphaSubFilter","BlurXorAlphaSubFilter","ImageXorFrame","ImageXorFunction","ImageXorAlphaBlend","ImageAlphaXorMedianSubFilter","ImageSmoothAlphaXorSubFilter","ImageXorMirrorFilter","ImageXorSubFilter","ImageAlphaXorSubFilter","SmoothTrailsBlend","MatrixCollectionRGBXor","RainbowGlitch","RainbowGlichStrobe","NegateSwitchStrobe","StrobeAlphaShuffle","ShuffleAlphaWithRGB","ShuffleAlphaSubFilter","ShuffleColorMap","BlendWithRainbowSubFilter","BlendWithJetSubFilter","ColormapBlendSubFilter","RandomColorMap","SmoothMirrorBlurFlip","RandomColorMapAlphaBlendSubFilter","RandomOrder","RandomOrderMedianBlendSubFilter","MirrorOrder","MirrorOrderSubFilter","BlurMirrorOrder","AveragePixelMirror","ShuffleAlphaMedianBlend","MirrorOrderAlpha","FilterStrobeSubFilter","ImageSubtractMedianBlend","ImageDarkBlend","ImageAverageDark","ImageRemainderPixel","AverageLinesBlend","SoftFeedbackMirror","AverageVerticalLinesBlend","LinesMedianBlend","XorSquare","PixelValuesPlusOne","AverageHorizontalFilter","AverageVerticalFilter","GradientAlphaXorHorizontal","GradientAlphaXorVertical","BlendImageWithSubFilter","BlendImageWithSubFilterAlpha","MedianBlendSoft","AndImageSubFilterXor","AlphaBlendImageSubFilterXor","AlphaBlendImageSubFilterXorRev","ParticleReleaseXor","ParticleReleaseXorVec","ParticleReleaseAlphaBlend","ParticleReleaseWithImage","ParticleReleaseSubFilter","ParticleReleaseImageSubFilter","ImageEnergy","ImageEnergySubFilter","ImageDistortion","ImageDistortionSubFilter","SmoothExactImageXorAlpha","FeedbackColormap","SmoothImageAlphaBlendMedian","ImageDarkenSmoothMedian","XorReverseImageSmooth","ReverseSubFilterBlend","ReverseSubFilterXor","ImageReverseSubFilter","SmoothRainbowMedian","MirrorAlphaBlend","ImageSmoothMedianBlend","ImageSmoothMedianSubFilter","ImageAlphaXorMedianBlend","MatrixCollectionBlend","MatrixCollectionSubFilter","MatrixCollectionImageSubFilter","MatrixCollectionBlurAlpha","MatrixCollectionXor","MatrixCollectionXor32","MatrixCollectionRandomColorMap","MatrixCollectionDarkXor","MatrixCollectionRGB","TrailsSubFilter","TrailsSubFilter32","CompareWithSubFilter","MedianTrails","SmoothMedianBlend","ColorTransition","ColorTransitionMedian","ColorTransitionRandom","ColorTransitionRandomMedian","ColorTransitionSubFilter","ColorTransitionImageSubFilter","CurtainSubFilter","RandomTrails","RandomTrailsSubFilter","CosSinMedianBlend","TrailsRGB","MatrixTrailsXorRandom","CosSinMultiplyCollectionXor","Filter8_Blend","Filter8_SubFilter","RandomSmoothAlphaMedian","RandomAlphaBlendFilter","RandomMirrorBitwiseXor","SquareDivideSubFilter","SquareSubFilter","SquareSubFilter8","SquareRandomFilter","SquareRandomSubFilter","ColorExpand","ColorExpandSubFilter","RotateImage","RotateBlendImage","RotateImageSubFilter","RotateAlphaBlendImage","FlipShuffle","FlipRandom","FlipOrder","FlipStrobeSubFilter","MirrorBlendFrame","MirrorBlendVertical","MirrorVerticalAndHorizontal","BlendFor360","MirrorSidesMedian","MirrorSidesSubFilter","MedianFrameAlphaBlendSubFilter","MedianSubFilter","ColorXorScale","ColorXorScaleSubFilter","ImageXorScale","MatrixCollectionShiftSubFilter","MatrixCollectionImageShiftSubFilter","MatrixCollectionSmoothAlphaBlend","MatrixCollectionBlurImageXorAlpha","MatrixCollectionBlurImageSubFilter","MatrixCollectionBlurImageSubFilter16","ImageAlphaBlendSubFilter","MultipleMatrixCollectionSubFilter","BlurAlphaSubFilter","BlurImageSubFilter","MedianBlendSubFilter","MedianBlendImageSubFilter","MedianBlendSelfBlend","BlendHalfSubFilter","BlurImageAlphaBlend","BlurImageAlphaBlendSubFilter","BlurImageAlphaBlendScaleSubFilter","RandomAmountOfMedianBlur","Bitwise_XOR_BlendFrame","AlphaBlendWithSubFilter","AlphaBlendScaleWithSubFilter","GaussianBlendEx","SimpleMatrixBlend","MatrixBlendSubFilter","SmoothMatrixBlendSubFilter","BlurSmoothSubFilterAlphaBlend","BlurSmoothAlphaXorBlendSubFilter","BlurTwiceSubFilter","BlurFrameBlendSubFilter","BlurFrameSubFilter","BlurSmoothMatrix","MedianBlurInc","GaussianBlurInc","BlurSmoothMedianInc","BlurSmoothGaussianInc","BlurMatrixCollectionXor","MatrixCollection8XorSubFilter","BlurSmoothRevFilter","SurroundingPixels","SurroundingPixelsAlpha","MatrixCollectionSurroundingPixels","MatrixCollectionSurroundingPixelsSubFilter","MatrixCollectionSurroundingPixelsImage","MatrixCollectionSurroundingPixelsImageSubFilter","ImageTransparent","MatrixImageAlphaBlendSubFilter","ImageAlphaCollectionSmoothBlend","ImageRandomColormap","ImageRandomColormapAlphaBlend","ImageRandomColormapAlphaScale","ImageRandomColormapSubFilter","ImageShuffle","ImageSubFilter","ImageAlphaBlendWithFrameSubFilter","ImageFadeInOut","ImageFadeBlackInOut","ImageFadeBlackInOutSubFilter","ImageFadeFrameInOut","ImageFadeFrameInOutSubFilter","ImageFadeDouble","BlendSubFilterAndImage","FadeSubFilter","FadeSubFilterRev","ImageBlendSubFilterMedianBlend","FadeSubFilterXor","BlurXorSubFilter","ColorFlashIncrease","ScaleFilter","NegativeDarkenXor","ImageXor_SubFilter","NegateBlendSubFilter","StrobeNegatePixel","StrobeNegateInOut","ImageStrobeOnOff","AlphaStrobeBlend","CannyRandomPixels","FrameImageFadeInOut","FrameImageFadeInOutDouble","ChangeEachSecond","ShuffleImage","ChangeImageEachSecond","ChangeImageFilterOnOff","ChangeXorEachSecond","MorphXor","MorphXorWithSubFilter","MirrorEachSecond","MirrorReverseSubFilter","MirrorReverseSubFilterAlphaBlend","Mirror_Xor_Combined","MirrorFrameShuffle","MirrorShuffleSmooth","Mirror_Xor_Smooth","XorFrameShuffle","XorMirrorBlendFrame","ImageXorSmooth","SmoothSubFilter64","SmoothMedian64","SmoothMedian32_SubFilter","SmoothAlphaMedian_SubFilter","SmoothImage_SubFilter","SmoothImageMedian_SubFilter","SmoothImageAndSubFilter","SmoothSubFilter90","SmoothMedianImageSubFilter16","ImageNegate","ImageNegateAlphaBlend","ImageNegateAlphaBlendSubFilter","FrameNegateAlphaBlendImage","DarkTrailsEffect","DarkNegate","ChannelSortMedianBlend","MatrixCollectionMirrorDirection","StrobeRandomChannel","SplitFramesSort","SplitFrameSortSubFilter","MedianBlend64","SplitFrameFilter","SplitFrameBlend","SplitFrameBlendSubFilter","SplitFrameCollection","SplitFrameMirror","RandomChannels","SmoothRandomChannels","SmoothChannelSubFilter","IncreaseRGB","IncreaseColor","SaturateBlend","SaturateBlendSubFilter","MaxRGB","XorDifferenceFilter","AlphaBlendChannelSort","ColorTrailsFilter","ColorTrailsSubFilter","DarkNegateRainbowMedian","IncreaseQuick","IncreaseRandomIndex","ImageChannelSubFilter", + "No Filter", + "Blend with Source", "Plugin", "Custom","Blend With Image #1","TriBlend with Image", "Image Strobe", "Image distraction" }; + // draw strings + std::string *draw_strings = draw_strings_value; + + + // filter callback functions + DrawFunction draw_func_value[] = { SelfAlphaBlend, SelfScale, StrobeEffect, Blend3, NegParadox, ThoughtMode, RandTriBlend, Blank,Tri,Distort,CDraw,Type,NewOne,blendFractal,blendFractalMood,cossinMultiply,colorAccumulate1,colorAccumulate2,colorAccumulate3,filter8,filter3,rainbowBlend,randBlend,newBlend,alphaFlame,pixelScale,pixelSort,glitchSort,randomFilter,randomFlash,imageBlend,imageBlendTwo,imageBlendThree,imageBlendFour,GaussianBlur,MedianBlur,BlurDistortion,DiamondPattern,MirrorBlend,Pulse,SidewaysMirror,MirrorNoBlend,SortFuzz,Fuzz,DoubleVision,RGBShift,RGBSep,GradientRainbow,GradientRainbowFlash,Reverse,Scanlines,TVStatic,MirrorAverage,MirrorAverageMix,Mean,Laplacian,Bitwise_XOR,Bitwise_AND,Bitwise_OR,Equalize,ChannelSort,Reverse_XOR,CombinePixels,FlipTrip,Canny,Boxes,BoxesFade,FlashBlack,SlideRGB,Side2Side,Top2Bottom,StrobeRedGreenBlue,Blend_Angle,Outward,OutwardSquare,ShiftPixels,ShiftPixelsDown,XorMultiBlend,BitwiseRotate,BitwiseRotateDiff,HPPD,FuzzyLines,GradientLines,GradientSelf,GradientSelfVertical,GradientDown,GraidentHorizontal,GradientRGB,Inter,UpDown,LeftRight,StrobeScan,BlendedScanLines,GradientStripes,XorSine,SquareSwap,SquareSwap4x2,SquareSwap8x4,SquareSwap16x8,SquareSwap64x32,SquareBars,SquareBars8,SquareSwapRand16x8,SquareVertical8,SquareVertical16,SquareVertical_Roll,SquareSwapSort_Roll,SquareVertical_RollReverse,SquareSwapSort_RollReverse,Circular,WhitePixel,FrameBlend,FrameBlendRGB,TrailsFilter,TrailsFilterIntense,TrailsFilterSelfAlpha,TrailsFilterXor,ColorTrails,MoveRed,MoveRGB,MoveRedGreenBlue,BlurSim,Block,BlockXor,BlockScale,BlockStrobe,PrevFrameBlend,Wave,HighWave,VerticalSort,VerticalChannelSort,HorizontalBlend,VerticalBlend,OppositeBlend,DiagonalLines,HorizontalLines,InvertedScanlines,Soft_Mirror,KanapaTrip,ColorMorphing,ScanSwitch,ScanAlphaSwitch,NegativeStrobe,XorAddMul,ParticleRelease,BlendSwitch,AllRed,AllGreen,AllBlue,LineRGB,PixelRGB,BoxedRGB,KruegerSweater,RGBFlash,IncreaseBlendHorizontal,BlendIncrease,GradientReverse,GradientReverseVertical,GradientReverseBox,GradientNewFilter,ReinterpretDouble,ReinterpSelfScale,AverageLines,ImageFile,ImageXor,ImageAlphaBlend,ColorRange,ImageInter,TrailsInter,TrailsBlend,TrailsNegate,InterReverse,InterMirror,InterFullMirror,MirrorRGB,RGBStatic1,RGBStatic2,VectorIncrease,LineByLineReverse,RandomIntertwine,RandomFour,BlendThree,AcidTrails,RandomTwo,HorizontalTrailsInter,Trails,BlendTrails,Negate,RandomFilteredSquare,ImageX,RandomQuads,QuadCosSinMultiply,QuadRandomFilter,RollRandom,AverageRandom,HorizontalStripes,DiamondStrobe,SmoothTrails,GridFilter8x,GridFilter16x,GridFilter8xBlend,GridRandom,GridRandomPixel,Dual_SelfAlphaRainbow,Dual_SelfAlphaBlur,SurroundPixelXor,Darken,WeakBlend,AverageVertical,RandomCollectionAverage,RandomCollectionAverageMax,SmoothTrailsSelfAlphaBlend,SmoothTrailsRainbowBlend,MedianBlend,SmoothRandomImageBlend,SmoothImageAlphaBlend,RandomAlphaBlend,RandomTwoFilterAlphaBlend,PixelatedSquare,AlphaBlendPosition,BlendRowAlpha,BlendRow,BlendRowByVar,BlendRowByDirection,BlendAlphaXor,SelfXorScale,BitwiseXorScale,XorTrails,RainbowTrails,NegativeTrails,IntenseTrails,SelfAlphaRGB,BlendImageOnOff,XorSelfAlphaImage,BitwiseXorStrobe,AlphaBlendRandom,ChannelSortAlphaBlend,XorChannelSort,GradientColors,GradientColorsVertical,Bitwise_XOR_Average,NotEqual,ImageShiftUpLeft,GradientXorSelfScale,SmoothSourcePixel,StrobeBlend,FrameBars,Sort_Vertical_Horizontal,Sort_Vertical_Horizontal_Bitwise_XOR,Scalar_Average_Multiply,Scalar_Average,Total_Average,AlphaBlendImageXor,FlashWhite,FlashBlackAndWhite,GaussianBlend,RandomXor,RandomXorFlash,RandomAmountMedianBlur,SoftXor,SelfXorBlend,SelfXorDoubleFlash,SelfOrDoubleFlash,BlendRowCurvedSqrt,CycleShiftRGB,CycleShiftRandomRGB,CycleShiftRandomRGB_XorBlend,CycleShiftRandomAlphaBlend,VerticalColorBars,GradientLeftRight,GraidentUpDown,GradientLeftRightInOut,GradientUpDownInOut,Lines,ColorLines,WhiteLines,ThickWhiteLines,UseLineObject,TanAlphaGrid,MedianBlendAnimation,FibFlash,ScaleFlash,LeftLines,Curtain,RandomCurtain,CurtainVertical,RandomCurtainVertical,inOrder,inOrderBySecond,DarkenFilter,RandomFilterBySecond,ThreeRandom,inOrderAlpha,inOrderAlphaXor,SlideFilter,SlideFilterXor,RandomSlideFilter,SlideUpDown,SlideUpDownXor,SlideUpDownRandom,SlideSubFilter,SlideSubUpDownFilter,ParticleBlend,ParticleFlash,ExactImage,ParticleAlpha,BlendInAndOut,BlendScaleInAndOut,AcidGlitch,XorBackwards,LiquidFilter,MatrixXorAnd,XorAlpha,AlphaAcidTrails,SelfXorAverage,RandomXorBlend,RGBVerticalXor,RGBVerticalXorScale,RGBHorizontalXor,RGBHorizontalXorScale,FadeStrobe,RGBMirror,MirrorStrobe,AndStrobe,AndStrobeScale,AndPixelStrobe,AndOrXorStrobe,AndOrXorStrobeScale,FadeInAndOut,BrightStrobe,DarkStrobe,ParticleFast,RandomXorOpposite,StrobeTransform,InitBlend,MoveUpLeft,RandomStrobe,RandomBlur,Stuck,StuckStrobe,OrStrobe,LagBlend,SubFilter,AddFilter,BlendImageXor,BlendImageAround_Median,ImageBlendTransform,RGBTrails,RGBTrailsDark,RGBTrailsAlpha,RGBTrailsNegativeAlpha,MovementRGBTrails,RGBTrailsXor,DifferenceStrobe,BlackAndWhiteDifferenceStrobe,DifferenceXor,DifferenceRand,DifferenceBrightStrobe,PsycheTrails,FourSquare,EightSquare,DiagonalSquare,DiagonalSquareRandom,SquareStretchDown,SquareStretchRight,SquareStretchUp,SquareStretchLeft,DarkTrails,SoftFeedback,SoftFeedbackFrames,ResizeSoftFeedback,SoftFeedback8,SoftFeedbackFrames8,ResizeSoftFeedback8,ResizeSoftFeedbackSubFilter,SoftFeedbackRandFilter,SoftFeedback32,SoftFeedbackFrames32,ResizeSoftFeedback32,SoftFeedbackRandFilter32,SoftFeedbackSubFilter,SoftFeedbackResizeSubFilter,SoftFeedbackResize64,SoftFeedbackResizeSubFilter64,SoftFeedbackReszieSubFilter64_Negate,SoftFeedbackReszieSubFilter64_Mirror,HalfNegateStrobe,MedianBlurXor,NegateTrails,RandomGradient,RandomStrobeFlash,RandomMirror,RandomOther,RandomXorFilter,RandomMirrorBlend,RandomMirrorAlphaBlend,Bitwise_XOR_AlphaSubFilter,AlphaBlendSubFilter,GradientSubFilterXor,XorBlend_SubFilter,SmoothSubFilterAlphaBlend,SmoothSubFilterXorBlend,IntertwineSubFilter,RandBlend,EveryOther,EveryOtherSubFilter,SmoothRandomFilter,RandomFilterRandomTimes,RandomSubFilterRandomTimes,AddToFrameSubFilter,MirrorXor,MirrorXorAll,MirrorXorScale,EnergyMirror,SmoothSubFilter,EnergizeSubFilter,SmoothSubFilter16,EnergizeSubFilter16,EnergizeSubFilter32,SmoothSubFilter32,HalfAddSubFilter,HalfXorSubFilter,StaticXorBlend,PsycheSort,XorScale,ChannelMedianSubFilter,GaussianStrobe,StrobeSort,GlitchSortStrobe,Bitwise_XOR_Blend,Bitwise_XOR_Sort,Bitwise_OR_Blend,Bitwise_AND_Blend,BitwiseColorMatrix,PixelReverseXor,PixelatedSubFilterSort,SilverBlend,RandomPixelOrderSort,ImageXorAlpha,ImageAverageXor,PixelXorBlend,SelfAlphaScale,SelfScaleAlpha,RainbowXorBlend,FrameDifference,SmallDiffference,FadeBlend,FilteredDifferenceSubFilter,ExpandSquareSubFilter,ExpandSquareBlendSubFilter,ExpandSquareVerticalSubFilter,DarkImageMedianBlend,GammaDarken5,GammaDarken10,SelfAlphaScaleBlend,FadeBars,MirrorXorAlpha,MirrorEnergizeSubFilter,StrobeXor,IntertwinedMirror,BlurredMirror,ShadeRGB,InterRGB_SubFilter,InterSmoothSubFilter,InterRGB_Bars_XY,InterRGB_Bars_X,InterRGB_Bars_Y,StoredFramesAlphaBlend_SubFilter,BlendSubFilter,BlendAlphaSubFilter,ReverseFrameBlend,ReverseFrameBlendSwitch,DoubleRandomMirror,Blend_AlphaSubFilter,RandomBlendFilter,DoubleRandomBlendFilter,FlipBlendW,FlipBlendWH,FlipBlendH,FlipBlendAll,FrameMedianBlendSubFilter,FrameBlurSubFilter,ImageBlendSubFilter,ImageBlendXorSubFilter,ImageCollectionSubFilter,SelfScaleXorIncrease,Blend_RedGreenBlue,XorBlend_RedGreenBlue,BlendIncrease_RedGreenBlue,Blend_RedReenBlue_Dark,DarkModBlend,PictureBuzz,IncDifference,IncDifferenceAlpha,MirrorMedianBlend,SubFilterMedianBlend,DarkenBlend,DarkCollectionSubFilter,ChannelSort_NoBlend_Descending,ChannelSort_NoBlend_Ascending,Headrush,DarkSmooth_Filter,DarkSelfAlpha,FlipMedian,FlipMedianSubFilter,FlipMirror,FlipMirrorAverage,FlipMirrorSubFilter,ShuffleMedian,ShuffleRGB,ParticleSnow,RandomPixels,DarkRandomPixels,MedianBlurSubFilter,Bars,ShuffleAlpha,AlphaMorph,ShuffleSelf,PixelatedHorizontalLines,PixelatedVerticalLines,StrobeShuffle,BlendBurred,BlendCombinedValues,RGBColorTrails,BlendCombinedValueSubFilter,BlendSubFilterAlpha,GradientXorPixels,PurpleRain,PixelByPixelXor,CopyXorAlpha,AveragePixelsXor,AveragePixelAlpha,NegativeByRow,AveragePixelCollection,IncorrectLine,XorShift,StrobeXorAndOr,XorWithSource,AlphaBlendWithSource,RGBSep1x,RGBMedianBlend,RGBMirror1,RGBMirror1Median,FlashMirror,CollectionXorSourceSubFilter,ReverseMirrorX,MirrorXorAll_Reverse,MirrorRGBReverse,MirrorRGBReverseBlend,BlendReverseSubFilter,MirrorBitwiseXor,SmoothBlendReverseSubFilter,RandomIncrease,MedianBlend16,MedianBlendBufferSubFilter,BGRBlend,RGBBlend,RGBBlendSubFilter,DivideAndIncH,DivideAndIncW,XorOppositeSubFilter,BlendSmoothSubFilter,BlurSmooth,BlurSmoothMedian,BlurSmoothSubFilter,BlurFlip,BlurFlipSubFilter,BlurMirrorGamma,MedianBlendDark,MedianBlendSubFilterEx,EnergyMirrorDark,AlphaBlendMirror,MirrorAlphaBlendedImage,AlphaBlendXorImage,ShiftFrameSmoothSubFilter,ShiftFrameStaticXorSubFilter,IncreaseDecreaseGamma,GammaIncDecIncrease,RandomSubFilter,TwistedVision,TwistedMirror,SelfScaleSortBlend,FlashMedianBlend,BlendWithFrameSubFilter,AlphaBlendWithFrameSubFilter,AlphaXorBlendWithFrameSubFilter,XorBlendSubFilter,FlipAlphaBlend,RandomFlipFilter,MirrorMedian,FlipMatrixCollection,MirrorMatrixCollection,MirrorMatrixSource,SelfScaleByFrame,SmoothMedianRotateSubFilter,SmoothCollectionAlphaBlend,XorSubFilter,XorAlphaSubFilter,BlurXorAlphaSubFilter,ImageXorFrame,ImageXorFunction,ImageXorAlphaBlend,ImageAlphaXorMedianSubFilter,ImageSmoothAlphaXorSubFilter,ImageXorMirrorFilter,ImageXorSubFilter,ImageAlphaXorSubFilter,SmoothTrailsBlend,MatrixCollectionRGBXor,RainbowGlitch,RainbowGlichStrobe,NegateSwitchStrobe,StrobeAlphaShuffle,ShuffleAlphaWithRGB,ShuffleAlphaSubFilter,ShuffleColorMap,BlendWithRainbowSubFilter,BlendWithJetSubFilter,ColormapBlendSubFilter,RandomColorMap,SmoothMirrorBlurFlip,RandomColorMapAlphaBlendSubFilter,RandomOrder,RandomOrderMedianBlendSubFilter,MirrorOrder,MirrorOrderSubFilter,BlurMirrorOrder,AveragePixelMirror,ShuffleAlphaMedianBlend,MirrorOrderAlpha,FilterStrobeSubFilter,ImageSubtractMedianBlend,ImageDarkBlend,ImageAverageDark,ImageRemainderPixel,AverageLinesBlend,SoftFeedbackMirror,AverageVerticalLinesBlend,LinesMedianBlend,XorSquare,PixelValuesPlusOne,AverageHorizontalFilter,AverageVerticalFilter,GradientAlphaXorHorizontal,GradientAlphaXorVertical,BlendImageWithSubFilter,BlendImageWithSubFilterAlpha,MedianBlendSoft,AndImageSubFilterXor,AlphaBlendImageSubFilterXor,AlphaBlendImageSubFilterXorRev,ParticleReleaseXor,ParticleReleaseXorVec,ParticleReleaseAlphaBlend,ParticleReleaseWithImage,ParticleReleaseSubFilter,ParticleReleaseImageSubFilter,ImageEnergy,ImageEnergySubFilter,ImageDistortion,ImageDistortionSubFilter,SmoothExactImageXorAlpha,FeedbackColormap,SmoothImageAlphaBlendMedian,ImageDarkenSmoothMedian,XorReverseImageSmooth,ReverseSubFilterBlend,ReverseSubFilterXor,ImageReverseSubFilter,SmoothRainbowMedian,MirrorAlphaBlend,ImageSmoothMedianBlend,ImageSmoothMedianSubFilter,ImageAlphaXorMedianBlend,MatrixCollectionBlend,MatrixCollectionSubFilter,MatrixCollectionImageSubFilter,MatrixCollectionBlurAlpha,MatrixCollectionXor,MatrixCollectionXor32,MatrixCollectionRandomColorMap,MatrixCollectionDarkXor,MatrixCollectionRGB,TrailsSubFilter,TrailsSubFilter32,CompareWithSubFilter,MedianTrails,SmoothMedianBlend,ColorTransition,ColorTransitionMedian,ColorTransitionRandom,ColorTransitionRandomMedian,ColorTransitionSubFilter,ColorTransitionImageSubFilter,CurtainSubFilter,RandomTrails,RandomTrailsSubFilter,CosSinMedianBlend,TrailsRGB,MatrixTrailsXorRandom,CosSinMultiplyCollectionXor,Filter8_Blend,Filter8_SubFilter,RandomSmoothAlphaMedian,RandomAlphaBlendFilter,RandomMirrorBitwiseXor,SquareDivideSubFilter,SquareSubFilter,SquareSubFilter8,SquareRandomFilter,SquareRandomSubFilter,ColorExpand,ColorExpandSubFilter,RotateImage,RotateBlendImage,RotateImageSubFilter,RotateAlphaBlendImage,FlipShuffle,FlipRandom,FlipOrder,FlipStrobeSubFilter,MirrorBlendFrame,MirrorBlendVertical,MirrorVerticalAndHorizontal,BlendFor360,MirrorSidesMedian,MirrorSidesSubFilter,MedianFrameAlphaBlendSubFilter,MedianSubFilter,ColorXorScale,ColorXorScaleSubFilter,ImageXorScale,MatrixCollectionShiftSubFilter,MatrixCollectionImageShiftSubFilter,MatrixCollectionSmoothAlphaBlend,MatrixCollectionBlurImageXorAlpha,MatrixCollectionBlurImageSubFilter,MatrixCollectionBlurImageSubFilter16,ImageAlphaBlendSubFilter,MultipleMatrixCollectionSubFilter,BlurAlphaSubFilter,BlurImageSubFilter,MedianBlendSubFilter,MedianBlendImageSubFilter,MedianBlendSelfBlend,BlendHalfSubFilter,BlurImageAlphaBlend,BlurImageAlphaBlendSubFilter,BlurImageAlphaBlendScaleSubFilter,RandomAmountOfMedianBlur,Bitwise_XOR_BlendFrame,AlphaBlendWithSubFilter,AlphaBlendScaleWithSubFilter,GaussianBlendEx,SimpleMatrixBlend,MatrixBlendSubFilter,SmoothMatrixBlendSubFilter,BlurSmoothSubFilterAlphaBlend,BlurSmoothAlphaXorBlendSubFilter,BlurTwiceSubFilter,BlurFrameBlendSubFilter,BlurFrameSubFilter,BlurSmoothMatrix,MedianBlurInc,GaussianBlurInc,BlurSmoothMedianInc,BlurSmoothGaussianInc,BlurMatrixCollectionXor,MatrixCollection8XorSubFilter,BlurSmoothRevFilter,SurroundingPixels,SurroundingPixelsAlpha,MatrixCollectionSurroundingPixels,MatrixCollectionSurroundingPixelsSubFilter,MatrixCollectionSurroundingPixelsImage,MatrixCollectionSurroundingPixelsImageSubFilter,ImageTransparent,MatrixImageAlphaBlendSubFilter,ImageAlphaCollectionSmoothBlend,ImageRandomColormap,ImageRandomColormapAlphaBlend,ImageRandomColormapAlphaScale,ImageRandomColormapSubFilter,ImageShuffle,ImageSubFilter,ImageAlphaBlendWithFrameSubFilter,ImageFadeInOut,ImageFadeBlackInOut,ImageFadeBlackInOutSubFilter,ImageFadeFrameInOut,ImageFadeFrameInOutSubFilter,ImageFadeDouble,BlendSubFilterAndImage,FadeSubFilter,FadeSubFilterRev,ImageBlendSubFilterMedianBlend,FadeSubFilterXor,BlurXorSubFilter,ColorFlashIncrease,ScaleFilter,NegativeDarkenXor,ImageXor_SubFilter,NegateBlendSubFilter,StrobeNegatePixel,StrobeNegateInOut,ImageStrobeOnOff,AlphaStrobeBlend,CannyRandomPixels,FrameImageFadeInOut,FrameImageFadeInOutDouble,ChangeEachSecond,ShuffleImage,ChangeImageEachSecond,ChangeImageFilterOnOff,ChangeXorEachSecond,MorphXor,MorphXorWithSubFilter,MirrorEachSecond,MirrorReverseSubFilter,MirrorReverseSubFilterAlphaBlend,Mirror_Xor_Combined,MirrorFrameShuffle,MirrorShuffleSmooth,Mirror_Xor_Smooth,XorFrameShuffle,XorMirrorBlendFrame,ImageXorSmooth,SmoothSubFilter64,SmoothMedian64,SmoothMedian32_SubFilter,SmoothAlphaMedian_SubFilter,SmoothImage_SubFilter,SmoothImageMedian_SubFilter,SmoothImageAndSubFilter,SmoothSubFilter90,SmoothMedianImageSubFilter16,ImageNegate,ImageNegateAlphaBlend,ImageNegateAlphaBlendSubFilter,FrameNegateAlphaBlendImage,DarkTrailsEffect,DarkNegate,ChannelSortMedianBlend,MatrixCollectionMirrorDirection,StrobeRandomChannel,SplitFramesSort,SplitFrameSortSubFilter,MedianBlend64,SplitFrameFilter,SplitFrameBlend,SplitFrameBlendSubFilter,SplitFrameCollection,SplitFrameMirror,RandomChannels,SmoothRandomChannels,SmoothChannelSubFilter,IncreaseRGB,IncreaseColor,SaturateBlend,SaturateBlendSubFilter,MaxRGB,XorDifferenceFilter,AlphaBlendChannelSort,ColorTrailsFilter,ColorTrailsSubFilter,DarkNegateRainbowMedian,IncreaseQuick,IncreaseRandomIndex,ImageChannelSubFilter, + NoFilter, + BlendWithSource,plugin,custom,blendWithImage, triBlendWithImage,imageStrobe, imageDistraction,0}; + // draw functions + DrawFunction *draw_func = draw_func_value; + // number of filters + int draw_max = 876; + // variables + double translation_variable = 0.001f, pass2_alpha = 0.75f; + // swap colors inline function + std::unordered_map filter_map; + bool color_map_set = false; + DrawFunction custom_callback = 0; + DrawFunction plugin_func = 0; + int colors[3] = {rand()%255, rand()%255, rand()%255}; + int proc_mode = 0; + bool reset_filter = false; + double alpha_increase = 0; + + FilterType filters[] = { {"Self AlphaBlend",SelfAlphaBlend}, {"Self Scale", SelfScale}, {"StrobeEffect", StrobeEffect}, {"Blend #3", Blend3}, {"Negative Paradox", NegParadox}, {"ThoughtMode", ThoughtMode}, {"RandTriBlend", RandTriBlend}, {"Blank", Blank}, {"Tri",Tri}, {"Distort",Distort}, {"CDraw",CDraw}, {"Type",Type}, {"NewOne",NewOne}, {"Blend Fractal",blendFractal}, {"Blend Fractal Mood",blendFractalMood}, {"CosSinMultiply",cossinMultiply}, {"Color Accumlate1",colorAccumulate1}, {"Color Accumulate2",colorAccumulate2}, {"Color Accumulate3",colorAccumulate3}, {"Filter8",filter8}, {"Filter3",filter3}, {"Rainbow Blend",rainbowBlend}, {"Rand Blend",randBlend}, {"New Blend",newBlend}, {"Alpha Flame Filters",alphaFlame}, {"Pixel Scale",pixelScale}, {"PixelSort",pixelSort}, {"GlitchSort",glitchSort}, {"Random Filter",randomFilter}, {"Random Flash",randomFlash}, {"Blend with Image",imageBlend}, {"Blend with Image #2",imageBlendTwo}, {"Blend with Image #3",imageBlendThree}, {"Blend with Image #4",imageBlendFour}, {"GaussianBlur",GaussianBlur}, {"Median Blur",MedianBlur}, {"Blur Distortion",BlurDistortion}, {"Diamond Pattern",DiamondPattern}, {"MirrorBlend",MirrorBlend}, {"Pulse",Pulse}, {"Sideways Mirror",SidewaysMirror}, {"Mirror No Blend",MirrorNoBlend}, {"Sort Fuzz",SortFuzz}, {"Fuzz",Fuzz}, {"Double Vision",DoubleVision}, {"RGB Shift",RGBShift}, {"RGB Sep",RGBSep}, {"Graident Rainbow",GradientRainbow}, {"Gradient Rainbow Flash",GradientRainbowFlash}, {"Reverse",Reverse}, {"Scanlines",Scanlines}, {"TV Static",TVStatic}, {"Mirror Average",MirrorAverage}, {"Mirror Average Mix",MirrorAverageMix}, {"Mean",Mean}, {"Laplacian",Laplacian}, {"Bitwise_XOR",Bitwise_XOR}, {"Bitwise_AND",Bitwise_AND}, {"Bitwise_OR",Bitwise_OR}, {"Equalize",Equalize}, {"Channel Sort",ChannelSort}, {"Reverse_XOR",Reverse_XOR}, {"Combine Pixels",CombinePixels}, {"FlipTrip",FlipTrip}, {"Canny",Canny}, {"Boxes",Boxes}, {"Boxes Fade",BoxesFade}, {"Flash Black",FlashBlack}, {"SlideRGB",SlideRGB}, {"Side2Side",Side2Side}, {"Top2Bottom",Top2Bottom}, {"Strobe Red Then Green Then Blue",StrobeRedGreenBlue}, {"Blend_Angle",Blend_Angle}, {"Outward",Outward}, {"Outward Square",OutwardSquare}, {"ShiftPixels",ShiftPixels}, {"ShiftPixelsDown",ShiftPixelsDown}, {"XorMultiBlend",XorMultiBlend}, {"Bitwise_Rotate",BitwiseRotate}, {"Bitwise_Rotate Diff",BitwiseRotateDiff}, {"HPPD",HPPD}, {"FuzzyLines",FuzzyLines}, {"GradientLines",GradientLines}, {"GradientSelf",GradientSelf}, {"GradientSelfVertical",GradientSelfVertical}, {"GradientDown",GradientDown}, {"GraidentHorizontal",GraidentHorizontal}, {"GradientRGB",GradientRGB}, {"Inter",Inter}, {"UpDown",UpDown}, {"LeftRight",LeftRight}, {"StrobeScan",StrobeScan}, {"BlendedScanLines",BlendedScanLines}, {"GradientStripes",GradientStripes}, {"XorSine",XorSine}, {"SquareSwap",SquareSwap}, {"SquareSwap4x2",SquareSwap4x2}, {"SquareSwap8x4",SquareSwap8x4}, {"SquareSwap16x8",SquareSwap16x8}, {"SquareSwap64x32",SquareSwap64x32}, {"SquareBars",SquareBars}, {"SquareBars8",SquareBars8}, {"SquareSwapRand16x8",SquareSwapRand16x8}, {"SquareVertical8",SquareVertical8}, {"SquareVertical16",SquareVertical16}, {"SquareVertical_Roll",SquareVertical_Roll}, {"SquareSwapSort_Roll",SquareSwapSort_Roll}, {"SquareVertical_RollReverse",SquareVertical_RollReverse}, {"SquareSwapSort_RollReverse",SquareSwapSort_RollReverse}, {"Circular",Circular}, {"WhitePixel",WhitePixel}, {"FrameBlend",FrameBlend}, {"FrameBlendRGB",FrameBlendRGB}, {"TrailsFilter",TrailsFilter}, {"TrailsFilterIntense",TrailsFilterIntense}, {"TrailsFilterSelfAlpha",TrailsFilterSelfAlpha}, {"TrailsFilterXor",TrailsFilterXor}, {"ColorTrails",ColorTrails}, {"MoveRed",MoveRed}, {"MoveRGB",MoveRGB}, {"MoveRedGreenBlue",MoveRedGreenBlue}, {"BlurSim",BlurSim}, {"Block",Block}, {"BlockXor",BlockXor}, {"BlockScale",BlockScale}, {"BlockStrobe",BlockStrobe}, {"PrevFrameBlend",PrevFrameBlend}, {"Wave",Wave}, {"HighWave",HighWave}, {"VerticalSort",VerticalSort}, {"VerticalChannelSort",VerticalChannelSort}, {"HorizontalBlend",HorizontalBlend}, {"VerticalBlend",VerticalBlend}, {"OppositeBlend",OppositeBlend}, {"DiagonalLines",DiagonalLines}, {"HorizontalLines",HorizontalLines}, {"InvertedScanlines",InvertedScanlines}, {"Soft_Mirror",Soft_Mirror}, {"KanapaTrip",KanapaTrip}, {"ColorMorphing",ColorMorphing}, {"ScanSwitch",ScanSwitch}, {"ScanAlphaSwitch",ScanAlphaSwitch}, {"NegativeStrobe",NegativeStrobe}, {"XorAddMul",XorAddMul}, {"ParticleRelease",ParticleRelease}, {"BlendSwitch",BlendSwitch}, {"All Red",AllRed}, {"All Green",AllGreen}, {"All Blue",AllBlue}, {"LineRGB",LineRGB}, {"PixelRGB",PixelRGB}, {"BoxedRGB",BoxedRGB}, {"KruegerSweater",KruegerSweater}, {"RGBFlash",RGBFlash}, {"IncreaseBlendHorizontal",IncreaseBlendHorizontal}, {"BlendIncrease",BlendIncrease}, {"GradientReverse",GradientReverse}, {"GradientReverseVertical",GradientReverseVertical}, {"GradientReverseBox",GradientReverseBox}, {"GradientNewFilter",GradientNewFilter}, {"ReinterpretDouble",ReinterpretDouble}, {"ReinterpSelfScale",ReinterpSelfScale}, {"AverageLines",AverageLines}, {"ImageFile",ImageFile}, {"ImageXor",ImageXor}, {"ImageAlphaBlend",ImageAlphaBlend}, {"ColorRange",ColorRange}, {"ImageInter",ImageInter}, {"TrailsInter",TrailsInter}, {"TrailsBlend",TrailsBlend}, {"TrailsNegate",TrailsNegate}, {"InterReverse",InterReverse}, {"InterMirror",InterMirror}, {"InterFullMirror",InterFullMirror}, {"MirrorRGB",MirrorRGB}, {"RGBStatic1",RGBStatic1}, {"RGBStatic2",RGBStatic2}, {"VectorIncrease",VectorIncrease}, {"LineByLineReverse",LineByLineReverse}, {"RandomIntertwine",RandomIntertwine}, {"RandomFour",RandomFour}, {"BlendThree",BlendThree}, {"AcidTrails",AcidTrails}, {"RandomTwo",RandomTwo}, {"HorizontalTrailsInter",HorizontalTrailsInter}, {"Trails",Trails}, {"BlendTrails",BlendTrails}, {"Negate",Negate}, {"RandomFilteredSquare",RandomFilteredSquare}, {"ImageX",ImageX}, {"RandomQuads",RandomQuads}, {"QuadCosSinMultiply",QuadCosSinMultiply}, {"QuadRandomFilter",QuadRandomFilter}, {"RollRandom",RollRandom}, {"AverageRandom",AverageRandom}, {"HorizontalStripes",HorizontalStripes}, {"DiamondStrobe",DiamondStrobe}, {"SmoothTrails",SmoothTrails}, {"GridFilter8x",GridFilter8x}, {"GridFilter16x",GridFilter16x}, {"GridFilter8xBlend",GridFilter8xBlend}, {"GridRandom",GridRandom}, {"GridRandomPixel",GridRandomPixel}, {"Dual_SelfAlphaRainbow",Dual_SelfAlphaRainbow}, {"Dual_SelfAlphaBlur",Dual_SelfAlphaBlur}, {"SurroundPixelXor",SurroundPixelXor}, {"Darken",Darken}, {"WeakBlend",WeakBlend}, {"AverageVertical",AverageVertical}, {"RandomCollectionAverage",RandomCollectionAverage}, {"RandomCollectionAverageMax",RandomCollectionAverageMax}, {"SmoothTrailsSelfAlphaBlend",SmoothTrailsSelfAlphaBlend}, {"SmoothTrailsRainbowBlend",SmoothTrailsRainbowBlend}, {"MedianBlend",MedianBlend}, {"SmoothRandomImageBlend",SmoothRandomImageBlend}, {"SmoothImageAlphaBlend",SmoothImageAlphaBlend}, {"RandomAlphaBlend",RandomAlphaBlend}, {"RandomTwoFilterAlphaBlend",RandomTwoFilterAlphaBlend}, {"PixelatedSquare",PixelatedSquare}, {"AlphaBlendPosition",AlphaBlendPosition}, {"BlendRowAlpha",BlendRowAlpha}, {"BlendRow",BlendRow}, {"BlendRowByVar",BlendRowByVar}, {"BlendRowByDirection",BlendRowByDirection}, {"BlendAlphaXor",BlendAlphaXor}, {"SelfXorScale",SelfXorScale}, {"BitwiseXorScale",BitwiseXorScale}, {"XorTrails",XorTrails}, {"RainbowTrails",RainbowTrails}, {"NegativeTrails",NegativeTrails}, {"IntenseTrails",IntenseTrails}, {"SelfAlphaRGB",SelfAlphaRGB}, {"BlendImageOnOff",BlendImageOnOff}, {"XorSelfAlphaImage",XorSelfAlphaImage}, {"BitwiseXorStrobe",BitwiseXorStrobe}, {"AlphaBlendRandom",AlphaBlendRandom}, {"ChannelSortAlphaBlend",ChannelSortAlphaBlend}, {"XorChannelSort",XorChannelSort}, {"GradientColors",GradientColors}, {"GradientColorsVertical",GradientColorsVertical}, {"Bitwise_XOR_Average",Bitwise_XOR_Average}, {"NotEqual",NotEqual}, {"ImageShiftUpLeft",ImageShiftUpLeft}, {"GradientXorSelfScale",GradientXorSelfScale}, {"SmoothSourcePixel",SmoothSourcePixel}, {"StrobeBlend",StrobeBlend}, {"FrameBars",FrameBars}, {"Sort_Vertical_Horizontal",Sort_Vertical_Horizontal}, {"Sort_Vertical_Horizontal_Bitwise_XOR",Sort_Vertical_Horizontal_Bitwise_XOR}, {"Scalar_Average_Multiply",Scalar_Average_Multiply}, {"Scalar_Average",Scalar_Average}, {"Total_Average",Total_Average}, {"AlphaBlendImageXor",AlphaBlendImageXor}, {"FlashWhite",FlashWhite}, {"FlashBlackAndWhite",FlashBlackAndWhite}, {"GaussianBlend",GaussianBlend}, {"RandomXor",RandomXor}, {"RandomXorFlash",RandomXorFlash}, {"RandomAmountMedianBlur",RandomAmountMedianBlur}, {"SoftXor",SoftXor}, {"SelfXorBlend",SelfXorBlend}, {"SelfXorDoubleFlash",SelfXorDoubleFlash}, {"SelfOrDoubleFlash",SelfOrDoubleFlash}, {"BlendRowCurvedSqrt",BlendRowCurvedSqrt}, {"CycleShiftRGB",CycleShiftRGB}, {"CycleShiftRandomRGB",CycleShiftRandomRGB}, {"CycleShiftRandomRGB_XorBlend",CycleShiftRandomRGB_XorBlend}, {"CycleShiftRandomAlphaBlend",CycleShiftRandomAlphaBlend}, {"VerticalColorBars",VerticalColorBars}, {"GradientLeftRight",GradientLeftRight}, {"GraidentUpDown",GraidentUpDown}, {"GradientLeftRightInOut",GradientLeftRightInOut}, {"GradientUpDownInOut",GradientUpDownInOut}, {"Lines",Lines}, {"ColorLines",ColorLines}, {"WhiteLines",WhiteLines}, {"ThickWhiteLines",ThickWhiteLines}, {"UseLineObject",UseLineObject}, {"TanAlphaGrid",TanAlphaGrid}, {"MedianBlendAnimation",MedianBlendAnimation}, {"FibFlash",FibFlash}, {"ScaleFlash",ScaleFlash}, {"LeftLines",LeftLines}, {"Curtain",Curtain}, {"RandomCurtain",RandomCurtain}, {"CurtainVertical",CurtainVertical}, {"RandomCurtainVertical",RandomCurtainVertical}, {"inOrder",inOrder}, {"inOrderBySecond",inOrderBySecond}, {"DarkenFilter",DarkenFilter}, {"RandomFilterBySecond",RandomFilterBySecond}, {"ThreeRandom",ThreeRandom}, {"inOrderAlpha",inOrderAlpha}, {"inOrderAlphaXor",inOrderAlphaXor}, {"SlideFilter",SlideFilter}, {"SlideFilterXor",SlideFilterXor}, {"RandomSlideFilter",RandomSlideFilter}, {"SlideUpDown",SlideUpDown}, {"SlideUpDownXor",SlideUpDownXor}, {"SlideUpDownRandom",SlideUpDownRandom}, {"SlideSubFilter",SlideSubFilter}, {"SlideSubUpDownFilter",SlideSubUpDownFilter}, {"ParticleBlend",ParticleBlend}, {"ParticleFlash",ParticleFlash}, {"ExactImage",ExactImage}, {"ParticleAlpha",ParticleAlpha}, {"BlendInAndOut",BlendInAndOut}, {"BlendScaleInAndOut",BlendScaleInAndOut}, {"AcidGlitch",AcidGlitch}, {"XorBackwards",XorBackwards}, {"LiquidFilter",LiquidFilter}, {"MatrixXorAnd",MatrixXorAnd}, {"XorAlpha",XorAlpha}, {"AlphaAcidTrails",AlphaAcidTrails}, {"SelfXorAverage",SelfXorAverage}, {"RandomXorBlend",RandomXorBlend}, {"RGBVerticalXor",RGBVerticalXor}, {"RGBVerticalXorScale",RGBVerticalXorScale}, {"RGBHorizontalXor",RGBHorizontalXor}, {"RGBHorizontalXorScale",RGBHorizontalXorScale}, {"FadeStrobe",FadeStrobe}, {"RGBMirror",RGBMirror}, {"MirrorStrobe",MirrorStrobe}, {"AndStrobe",AndStrobe}, {"AndStrobeScale",AndStrobeScale}, {"AndPixelStrobe",AndPixelStrobe}, {"AndOrXorStrobe",AndOrXorStrobe}, {"AndOrXorStrobeScale",AndOrXorStrobeScale}, {"FadeInAndOut",FadeInAndOut}, {"BrightStrobe",BrightStrobe}, {"DarkStrobe",DarkStrobe}, {"ParticleFast",ParticleFast}, {"RandomXorOpposite",RandomXorOpposite}, {"StrobeTransform",StrobeTransform}, {"InitBlend",InitBlend}, {"MoveUpLeft",MoveUpLeft}, {"RandomStrobe",RandomStrobe}, {"RandomBlur",RandomBlur}, {"Stuck",Stuck}, {"StuckStrobe",StuckStrobe}, {"OrStrobe",OrStrobe}, {"LagBlend",LagBlend}, {"SubFilter",SubFilter}, {"AddFilter",AddFilter}, {"BlendImageXor",BlendImageXor}, {"BlendImageAround_Median",BlendImageAround_Median}, {"ImageBlendTransform",ImageBlendTransform}, {"RGBTrails",RGBTrails}, {"RGBTrailsDark",RGBTrailsDark}, {"RGBTrailsAlpha",RGBTrailsAlpha}, {"RGBTrailsNegativeAlpha",RGBTrailsNegativeAlpha}, {"MovementRGBTrails",MovementRGBTrails}, {"RGBTrailsXor",RGBTrailsXor}, {"DifferenceStrobe",DifferenceStrobe}, {"BlackAndWhiteDifferenceStrobe",BlackAndWhiteDifferenceStrobe}, {"DifferenceXor",DifferenceXor}, {"DifferenceRand",DifferenceRand}, {"DifferenceBrightStrobe",DifferenceBrightStrobe}, {"PsycheTrails",PsycheTrails}, {"FourSquare",FourSquare}, {"EightSquare",EightSquare}, {"DiagonalSquare",DiagonalSquare}, {"DiagonalSquareRandom",DiagonalSquareRandom}, {"SquareStretchDown",SquareStretchDown}, {"SquareStretchRight",SquareStretchRight}, {"SquareStretchUp",SquareStretchUp}, {"SquareStretchLeft",SquareStretchLeft}, {"DarkTrails",DarkTrails}, {"SoftFeedback",SoftFeedback}, {"SoftFeedbackFrames",SoftFeedbackFrames}, {"ResizeSoftFeedback",ResizeSoftFeedback}, {"SoftFeedback8",SoftFeedback8}, {"SoftFeedbackFrames8",SoftFeedbackFrames8}, {"ResizeSoftFeedback8",ResizeSoftFeedback8}, {"ResizeSoftFeedbackSubFilter",ResizeSoftFeedbackSubFilter}, {"SoftFeedbackRandFilter",SoftFeedbackRandFilter}, {"SoftFeedback32",SoftFeedback32}, {"SoftFeedbackFrames32",SoftFeedbackFrames32}, {"ResizeSoftFeedback32",ResizeSoftFeedback32}, {"SoftFeedbackRandFilter32",SoftFeedbackRandFilter32}, {"SoftFeedbackSubFilter",SoftFeedbackSubFilter}, {"SoftFeedbackResizeSubFilter",SoftFeedbackResizeSubFilter},{"SoftFeedbackResize64",SoftFeedbackResize64}, {"SoftFeedbackResizeSubFilter64",SoftFeedbackResizeSubFilter64}, {"SoftFeedbackReszieSubFilter64_Negate",SoftFeedbackReszieSubFilter64_Negate}, {"SoftFeedbackReszieSubFilter64_Mirror",SoftFeedbackReszieSubFilter64_Mirror}, {"HalfNegateStrobe",HalfNegateStrobe},{"MedianBlurXor", MedianBlurXor},{"NegateTrails", NegateTrails},{"RandomGradient", RandomGradient},{"RandomStrobeFlash", RandomStrobeFlash}, {"RandomMirror", RandomMirror},{"RandomOther", RandomOther},{"RandomXorFilter", RandomXorFilter},{"RandomMirrorBlend", RandomMirrorBlend},{"RandomMirrorAlphaBlend", RandomMirrorAlphaBlend}, {"Bitwise_XOR_AlphaSubFilter", Bitwise_XOR_AlphaSubFilter}, {"AlphaBlendSubFilter", AlphaBlendSubFilter},{"GradientSubFilterXor", GradientSubFilterXor},{"XorBlend_SubFilter", XorBlend_SubFilter},{"SmoothSubFilterAlphaBlend", SmoothSubFilterAlphaBlend},{"SmoothSubFilterXorBlend", SmoothSubFilterXorBlend},{"IntertwineSubFilter", IntertwineSubFilter},{"RandBlend", RandBlend},{"EveryOther", EveryOther},{"EveryOtherSubFilter", EveryOtherSubFilter},{"SmoothRandomFilter", SmoothRandomFilter},{"RandomFilterRandomTimes", RandomFilterRandomTimes},{"RandomSubFilterRandomTimes", RandomSubFilterRandomTimes},{"AddToFrameSubFilter",AddToFrameSubFilter},{"MirrorXor", MirrorXor},{"MirrorXorAll", MirrorXorAll}, {"MirrorXorScale", MirrorXorScale},{"EnergyMirror",EnergyMirror},{"SmoothSubFilter", SmoothSubFilter},{"EnergizeSubFilter", EnergizeSubFilter},{"SmoothSubFilter16", SmoothSubFilter16},{"EnergizeSubFilter16", EnergizeSubFilter16},{"EnergizeSubFilter32", EnergizeSubFilter32},{"SmoothSubFilter32", SmoothSubFilter32},{"HalfAddSubFilter", HalfAddSubFilter},{"HalfXorSubFilter", HalfXorSubFilter},{"StaticXorBlend", StaticXorBlend},{"PsycheSort", PsycheSort},{"XorScale", XorScale},{"ChannelMedianSubFilter", ChannelMedianSubFilter},{"GaussianStrobe", GaussianStrobe},{"StrobeSort", StrobeSort},{"GlitchSortStrobe", GlitchSortStrobe},{"Bitwise_XOR_Blend",Bitwise_XOR_Blend},{"Bitwise_XOR_Sort", Bitwise_XOR_Sort},{"Bitwise_OR_Blend", Bitwise_OR_Blend},{"Bitwise_AND_Blend", Bitwise_AND_Blend},{"BitwiseColorMatrix", BitwiseColorMatrix},{"PixelReverseXor", PixelReverseXor},{"PixelatedSubFilterSort", PixelatedSubFilterSort},{"SilverBlend", SilverBlend},{"RandomPixelOrderSort", RandomPixelOrderSort},{"ImageXorAlpha", ImageXorAlpha},{"ImageAverageXor", ImageAverageXor},{"PixelXorBlend", PixelXorBlend},{"SelfAlphaScale", SelfAlphaScale},{"SelfScaleAlpha", SelfScaleAlpha},{"RainbowXorBlend", RainbowXorBlend},{"FrameDifference", FrameDifference},{"SmallDiffference", SmallDiffference},{"FadeBlend", FadeBlend},{"FilteredDifferenceSubFilter", FilteredDifferenceSubFilter},{"ExpandSquareSubFilter", ExpandSquareSubFilter}, {"ExpandSquareBlendSubFilter", ExpandSquareBlendSubFilter},{"ExpandSquareVerticalSubFilter", ExpandSquareVerticalSubFilter},{"DarkImageMedianBlend", DarkImageMedianBlend},{"GammaDarken5", GammaDarken5},{"GammaDarken10", GammaDarken10},{"SelfAlphaScaleBlend", SelfAlphaScaleBlend},{"FadeBars", FadeBars},{"MirrorXorAlpha", MirrorXorAlpha},{"MirrorEnergizeSubFilter", MirrorEnergizeSubFilter},{"StrobeXor", StrobeXor},{"IntertwinedMirror", InterMirror}, {"BlurredMirror", BlurredMirror},{"ShadeRGB", ShadeRGB},{"InterRGB_SubFilter", InterRGB_SubFilter},{"InterSmoothSubFilter", InterSmoothSubFilter},{"InterRGB_Bars_XY", InterRGB_Bars_XY},{"InterRGB_Bars_X",InterRGB_Bars_X},{"InterRGB_Bars_Y", InterRGB_Bars_Y},{"StoredFramesAlphaBlend_SubFilter", StoredFramesAlphaBlend_SubFilter},{"BlendSubFilter", BlendSubFilter},{"BlendAlphaSubFilter", BlendAlphaSubFilter},{"ReverseFrameBlend", ReverseFrameBlend},{"ReverseFrameBlendSwitch", ReverseFrameBlendSwitch},{"DoubleRandomMirror", DoubleRandomMirror},{"Blend_AlphaSubFilter", Blend_AlphaSubFilter},{"RandomBlendFilter", RandomBlendFilter},{"DoubleRandomBlendFilter", DoubleRandomBlendFilter},{"FlipBlendW", FlipBlendW},{"FlipBlendWH", FlipBlendWH}, {"FlipBlendH", FlipBlendH}, {"FlipBlendAll", FlipBlendAll},{"FrameMedianBlendSubFilter", FrameMedianBlendSubFilter}, {"FrameBlurSubFilter", FrameBlurSubFilter},{"ImageBlendSubFilter", ImageBlendSubFilter},{"ImageBlendXorSubFilter", ImageBlendXorSubFilter},{"ImageCollectionSubFilter", ImageCollectionSubFilter},{"SelfScaleXorIncrease", SelfScaleXorIncrease},{"Blend_RedGreenBlue", Blend_RedGreenBlue},{"XorBlend_RedGreenBlue", XorBlend_RedGreenBlue},{"BlendIncrease_RedGreenBlue", BlendIncrease_RedGreenBlue},{"Blend_RedReenBlue_Dark", Blend_RedReenBlue_Dark},{"DarkModBlend", DarkModBlend}, {"PictureBuzz", PictureBuzz},{"IncDifference", IncDifference},{"IncDifferenceAlpha", IncDifferenceAlpha},{"MirrorMedianBlend", MirrorMedianBlend},{"SubFilterMedianBlend", SubFilterMedianBlend},{"DarkenBlend", DarkenBlend},{"DarkCollectionSubFilter", DarkCollectionSubFilter},{"ChannelSort_NoBlend_Descending", ChannelSort_NoBlend_Descending}, {"ChannelSort_NoBlend_Ascending", ChannelSort_NoBlend_Ascending},{"Headrush", Headrush},{"DarkSmooth_Filter", DarkSmooth_Filter},{"DarkSelfAlpha", DarkSelfAlpha},{"FlipMedian", FlipMedian},{"FlipMedianSubFilter", FlipMedianSubFilter},{"FlipMirror", FlipMirror},{"FlipMirrorAverage", FlipMirrorAverage},{"FlipMirrorSubFilter", FlipMirrorSubFilter},{"ShuffleMedian", ShuffleMedian},{"ShuffleRGB", ShuffleRGB},{"ParticleSnow", ParticleSnow},{"RandomPixels", RandomPixels},{"DarkRandomPixels", DarkRandomPixels},{"MedianBlurSubFilter", MedianBlurSubFilter},{"Bars", Bars},{"ShuffleAlpha", ShuffleAlpha},{"AlphaMorph", AlphaMorph},{"ShuffleSelf", ShuffleSelf},{"PixelatedHorizontalLines", PixelatedHorizontalLines},{"PixelatedVerticalLines", PixelatedVerticalLines},{"StrobeShuffle", StrobeShuffle},{"BlendBurred", BlendBurred},{"BlendCombinedValues", BlendCombinedValues},{"RGBColorTrails", RGBColorTrails},{"BlendCombinedValueSubFilter", BlendCombinedValueSubFilter},{"BlendSubFilterAlpha", BlendSubFilterAlpha},{"GradientXorPixels", GradientXorPixels},{"PurpleRain", PurpleRain},{"PixelByPixelXor", PixelByPixelXor},{"CopyXorAlpha", CopyXorAlpha},{"AveragePixelsXor", AveragePixelsXor},{"AveragePixelAlpha", AveragePixelAlpha},{"NegativeByRow", NegativeByRow},{"AveragePixelCollection", AveragePixelCollection},{"IncorrectLine", IncorrectLine},{"XorShift", XorShift},{"StrobeXorAndOr", StrobeXorAndOr},{"XorWithSource", XorWithSource},{"AlphaBlendWithSource", AlphaBlendWithSource},{"RGBSep1x", RGBSep},{"RGBMedianBlend", RGBMedianBlend},{"RGBMirror1", RGBMirror1},{"RGBMirror1Median", RGBMirror1Median}, {"FlashMirror", FlashMirror},{"CollectionXorSourceSubFilter", CollectionXorSourceSubFilter},{"ReverseMirrorX", ReverseMirrorX},{"MirrorXorAll_Reverse", MirrorXorAll_Reverse},{"MirrorRGBReverse", MirrorRGBReverse},{"MirrorRGBReverseBlend", MirrorRGBReverseBlend},{"BlendReverseSubFilter", BlendReverseSubFilter},{"MirrorBitwiseXor", MirrorBitwiseXor},{"SmoothBlendReverseSubFilter", SmoothBlendReverseSubFilter},{"RandomIncrease", RandomIncrease},{"MedianBlend16", MedianBlend16},{"MedianBlendBufferSubFilter", MedianBlendBufferSubFilter},{"BGRBlend", BGRBlend},{"RGBBlend", RGBBlend},{"RGBBlendSubFilter", RGBBlendSubFilter},{"DivideAndIncH", DivideAndIncH},{"DivideAndIncW", DivideAndIncW},{"XorOppositeSubFilter", XorOppositeSubFilter},{"BlendSmoothSubFilter", BlendSmoothSubFilter},{"BlurSmooth", BlurSmooth},{"BlurSmoothMedian", BlurSmoothMedian},{"BlurSmoothSubFilter", BlurSmoothSubFilter},{"BlurFlip", BlurFlip},{"BlurFlipSubFilter", BlurFlipSubFilter},{"BlurMirrorGamma", BlurMirrorGamma},{"MedianBlendDark", MedianBlendDark},{"MedianBlendSubFilterEx", MedianBlendSubFilterEx},{"EnergyMirrorDark", EnergyMirrorDark},{"AlphaBlendMirror", AlphaBlendMirror},{"MirrorAlphaBlendedImage", MirrorAlphaBlendedImage},{"AlphaBlendXorImage", AlphaBlendXorImage},{"ShiftFrameSmoothSubFilter", ShiftFrameSmoothSubFilter},{"ShiftFrameStaticXorSubFilter", ShiftFrameStaticXorSubFilter},{"IncreaseDecreaseGamma", IncreaseDecreaseGamma},{"GammaIncDecIncrease", GammaIncDecIncrease},{"RandomSubFilter", RandomSubFilter},{"TwistedVision", TwistedVision},{"TwistedMirror", TwistedMirror},{"SelfScaleSortBlend", SelfScaleSortBlend},{"FlashMedianBlend", FlashMedianBlend},{"BlendWithFrameSubFilter", BlendWithFrameSubFilter},{"AlphaBlendWithFrameSubFilter", AlphaBlendWithFrameSubFilter},{"AlphaXorBlendWithFrameSubFilter", AlphaXorBlendWithFrameSubFilter},{"XorBlendSubFilter", XorBlendSubFilter},{"FlipAlphaBlend", FlipAlphaBlend},{"RandomFlipFilter", RandomFlipFilter},{"MirrorMedian", MirrorMedian},{"FlipMatrixCollection", FlipMatrixCollection},{"MirrorMatrixCollection", MirrorMatrixCollection},{"MirrorMatrixSource", MirrorMatrixSource},{"SelfScaleByFrame", SelfScaleByFrame},{"SmoothMedianRotateSubFilter", SmoothMedianRotateSubFilter},{"SmoothCollectionAlphaBlend", SmoothCollectionAlphaBlend},{"XorSubFilter", XorSubFilter},{"XorAlphaSubFilter", XorAlphaSubFilter},{"BlurXorAlphaSubFilter", BlurXorAlphaSubFilter},{"ImageXorFrame", ImageXorFrame},{"ImageXorFunction", ImageXorFunction},{"ImageXorAlphaBlend", ImageXorAlphaBlend},{"ImageAlphaXorMedianSubFilter", ImageAlphaXorMedianSubFilter},{"ImageSmoothAlphaXorSubFilter", ImageSmoothAlphaXorSubFilter},{"ImageXorMirrorFilter", ImageXorMirrorFilter},{"ImageXorSubFilter", ImageXorSubFilter},{"ImageAlphaXorSubFilter", ImageAlphaXorSubFilter},{"SmoothTrailsBlend", SmoothTrailsBlend},{"MatrixCollectionRGBXor", MatrixCollectionRGBXor},{"RainbowGlitch", RainbowGlitch},{"RainbowGlichStrobe", RainbowGlichStrobe}, {"NegateSwitchStrobe", NegateSwitchStrobe},{"StrobeAlphaShuffle", StrobeAlphaShuffle},{"ShuffleAlphaWithRGB", ShuffleAlphaWithRGB},{"ShuffleAlphaSubFilter", ShuffleAlphaSubFilter},{"ShuffleColorMap", ShuffleColorMap},{"BlendWithRainbowSubFilter", BlendWithRainbowSubFilter},{"BlendWithJetSubFilter", BlendWithJetSubFilter},{"ColormapBlendSubFilter", ColormapBlendSubFilter},{"RandomColorMap", RandomColorMap},{"SmoothMirrorBlurFlip", SmoothMirrorBlurFlip},{"RandomColorMapAlphaBlendSubFilter", RandomColorMapAlphaBlendSubFilter},{"RandomOrder", RandomOrder},{"RandomOrderMedianBlendSubFilter", RandomOrderMedianBlendSubFilter}, {"MirrorOrder", MirrorOrder},{"MirrorOrderSubFilter", MirrorOrderSubFilter},{"BlurMirrorOrder", BlurMirrorOrder},{"AveragePixelMirror", AveragePixelMirror},{"ShuffleAlphaMedianBlend", ShuffleAlphaMedianBlend},{"MirrorOrderAlpha", MirrorOrderAlpha},{"FilterStrobeSubFilter", FilterStrobeSubFilter},{"ImageSubtractMedianBlend", ImageSubtractMedianBlend},{"ImageDarkBlend", ImageDarkBlend},{"ImageAverageDark", ImageAverageDark},{"ImageRemainderPixel", ImageRemainderPixel},{"AverageLinesBlend", AverageLinesBlend},{"SoftFeedbackMirror", SoftFeedbackMirror},{"AverageVerticalLinesBlend", AverageVerticalLinesBlend},{"LinesMedianBlend", LinesMedianBlend},{"XorSquare", XorSquare},{"PixelValuesPlusOne", PixelValuesPlusOne},{"AverageHorizontalFilter", AverageHorizontalFilter},{"AverageVerticalFilter", AverageVerticalFilter},{"GradientAlphaXorHorizontal", GradientAlphaXorHorizontal},{"GradientAlphaXorVertical", GradientAlphaXorVertical},{"BlendImageWithSubFilter", BlendImageWithSubFilter},{"BlendImageWithSubFilterAlpha", BlendImageWithSubFilterAlpha},{"MedianBlendSoft", MedianBlendSoft},{"AndImageSubFilterXor", AndImageSubFilterXor},{"AlphaBlendImageSubFilterXor", AlphaBlendImageSubFilterXor},{"AlphaBlendImageSubFilterXorRev", AlphaBlendImageSubFilterXorRev},{"ParticleReleaseXor", ParticleReleaseXor},{"ParticleReleaseXorVec", ParticleReleaseXorVec},{"ParticleReleaseAlphaBlend", ParticleReleaseAlphaBlend},{"ParticleReleaseWithImage", ParticleReleaseWithImage},{"ParticleReleaseSubFilter", ParticleReleaseSubFilter},{"ParticleReleaseImageSubFilter", ParticleReleaseImageSubFilter},{"ImageEnergy", ImageEnergy},{"ImageEnergySubFilter", ImageEnergySubFilter},{"ImageDistortion", ImageDistortion},{"ImageDistortionSubFilter", ImageDistortionSubFilter},{"SmoothExactImageXorAlpha", SmoothExactImageXorAlpha},{"FeedbackColormap", FeedbackColormap},{"SmoothImageAlphaBlendMedian", SmoothImageAlphaBlendMedian},{"ImageDarkenSmoothMedian", ImageDarkenSmoothMedian},{"XorReverseImageSmooth", XorReverseImageSmooth},{"ReverseSubFilterBlend", ReverseSubFilterBlend},{"ReverseSubFilterXor", ReverseSubFilterXor},{"ImageReverseSubFilter", ImageReverseSubFilter},{"SmoothRainbowMedian", SmoothRainbowMedian},{"MirrorAlphaBlend", MirrorAlphaBlend},{"ImageSmoothMedianBlend", ImageSmoothMedianBlend},{"ImageSmoothMedianSubFilter", ImageSmoothMedianSubFilter},{"ImageAlphaXorMedianBlend", ImageAlphaXorMedianBlend},{"MatrixCollectionBlend", MatrixCollectionBlend},{"MatrixCollectionSubFilter", MatrixCollectionSubFilter},{"MatrixCollectionImageSubFilter", MatrixCollectionImageSubFilter},{"MatrixCollectionBlurAlpha", MatrixCollectionBlurAlpha},{"MatrixCollectionXor", MatrixCollectionXor},{"MatrixCollectionXor32", MatrixCollectionXor32},{"MatrixCollectionRandomColorMap", MatrixCollectionRandomColorMap},{"MatrixCollectionDarkXor", MatrixCollectionDarkXor},{"MatrixCollectionRGB", MatrixCollectionRGB},{"TrailsSubFilter", TrailsSubFilter},{"TrailsSubFilter32", TrailsSubFilter32},{"CompareWithSubFilter", CompareWithSubFilter},{"MedianTrails", MedianTrails},{"SmoothMedianBlend", SmoothMedianBlend},{"ColorTransition", ColorTransition},{"ColorTransitionMedian", ColorTransitionMedian},{"ColorTransitionRandom", ColorTransitionRandom},{"ColorTransitionRandomMedian", ColorTransitionRandomMedian},{"ColorTransitionSubFilter", ColorTransitionSubFilter},{"ColorTransitionImageSubFilter", ColorTransitionImageSubFilter},{"CurtainSubFilter", CurtainSubFilter},{"RandomTrails", RandomTrails},{"RandomTrailsSubFilter", RandomTrailsSubFilter},{"CosSinMedianBlend", CosSinMedianBlend},{"TrailsRGB", TrailsRGB},{"MatrixTrailsXorRandom", MatrixTrailsXorRandom},{"CosSinMultiplyCollectionXor", CosSinMultiplyCollectionXor},{"Filter8_Blend", Filter8_Blend},{"Filter8_SubFilter", Filter8_SubFilter},{"RandomSmoothAlphaMedian", RandomSmoothAlphaMedian},{"RandomAlphaBlend", RandomAlphaBlendFilter},{"RandomMirrorBitwiseXor", RandomMirrorBitwiseXor},{"SquareDivideSubFilter", SquareDivideSubFilter},{"SquareSubFilter", SquareSubFilter},{"SquareSubFilter8", SquareSubFilter8},{"SquareRandomFilter", SquareRandomFilter},{"SquareRandomSubFilter", SquareRandomSubFilter},{"ColorExpand", ColorExpand},{"ColorExpandSubFilter", ColorExpandSubFilter},{"RotateImage", RotateImage},{"RotateBlendImage", RotateBlendImage},{"RotateImageSubFilter", RotateImageSubFilter},{"RotateAlphaBlendImage", RotateAlphaBlendImage},{"FlipShuffle", FlipShuffle},{"FlipRandom", FlipRandom},{"FlipOrder", FlipOrder},{"FlipStrobeSubFilter", FlipStrobeSubFilter},{"MirrorBlendFrame", MirrorBlendFrame},{"MirrorBlendVertical", MirrorBlendVertical},{"MirrorVerticalAndHorizontal", MirrorVerticalAndHorizontal},{"BlendFor360", BlendFor360},{"MirrorSidesMedian", MirrorSidesMedian},{"MirrorSidesSubFilter", MirrorSidesSubFilter},{"MedianFrameAlphaBlendSubFilter", MedianFrameAlphaBlendSubFilter},{"MedianSubFilter", MedianSubFilter},{"ColorXorScale", ColorXorScale},{"ColorXorScaleSubFilter", ColorXorScaleSubFilter},{"ImageXorScale", ImageXorScale},{"MatrixCollectionShiftSubFilter", MatrixCollectionShiftSubFilter},{"MatrixCollectionImageShiftSubFilter", MatrixCollectionImageShiftSubFilter},{"MatrixCollectionSmoothAlphaBlend", MatrixCollectionSmoothAlphaBlend},{"MatrixCollectionBlurImageXorAlpha", MatrixCollectionBlurImageXorAlpha},{"MatrixCollectionBlurImageSubFilter", MatrixCollectionBlurImageSubFilter},{"MatrixCollectionBlurImageSubFilter16", MatrixCollectionBlurImageSubFilter16},{"ImageAlphaBlendSubFilter", ImageAlphaBlendSubFilter},{"MultipleMatrixCollectionSubFilter", MultipleMatrixCollectionSubFilter},{"BlurAlphaSubFilter", BlurAlphaSubFilter},{"BlurImageSubFilter", BlurImageSubFilter},{"MedianBlendSubFilter", MedianBlendSubFilter},{"MedianBlendImageSubFilter", MedianBlendImageSubFilter},{"MedianBlendSelfBlend", MedianBlendSelfBlend},{"BlendHalfSubFilter", BlendHalfSubFilter},{"BlurImageAlphaBlend", BlurImageAlphaBlend},{"BlurImageAlphaBlendSubFilter", BlurImageAlphaBlendSubFilter},{"BlurImageAlphaBlendScaleSubFilter", BlurImageAlphaBlendScaleSubFilter},{"RandomAmountOfMedianBlur", RandomAmountOfMedianBlur},{"Bitwise_XOR_BlendFrame", Bitwise_XOR_BlendFrame},{"AlphaBlendWithSubFilter", AlphaBlendWithSubFilter},{"AlphaBlendScaleWithSubFilter", AlphaBlendScaleWithSubFilter},{"GaussianBlendEx", GaussianBlendEx},{"SimpleMatrixBlend", SimpleMatrixBlend},{"MatrixBlendSubFilter", MatrixBlendSubFilter},{"SmoothMatrixBlendSubFilter", SmoothMatrixBlendSubFilter},{"BlurSmoothSubFilterAlphaBlend", BlurSmoothSubFilterAlphaBlend},{"BlurSmoothAlphaXorBlendSubFilter", BlurSmoothAlphaXorBlendSubFilter},{"BlurTwiceSubFilter", BlurTwiceSubFilter},{"BlurFrameBlendSubFilter", BlurFrameBlendSubFilter},{"BlurFrameSubFilter", BlurFrameSubFilter},{"BlurSmoothMatrix", BlurSmoothMatrix},{"MedianBlurInc", MedianBlurInc},{"GaussianBlurInc", GaussianBlurInc},{"BlurSmoothMedianInc", BlurSmoothMedianInc},{"BlurSmoothGaussianInc", BlurSmoothGaussianInc},{"BlurMatrixCollectionXor", BlurMatrixCollectionXor},{"MatrixCollection8XorSubFilter", MatrixCollection8XorSubFilter},{"BlurSmoothRevFilter", BlurSmoothRevFilter},{"SurroundingPixels", SurroundingPixels},{"SurroundingPixelsAlpha", SurroundingPixelsAlpha},{"MatrixCollectionSurroundingPixels", MatrixCollectionSurroundingPixels},{"MatrixCollectionSurroundingPixelsSubFilter", MatrixCollectionSurroundingPixelsSubFilter},{"MatrixCollectionSurroundingPixelsImage", MatrixCollectionSurroundingPixelsImage},{"MatrixCollectionSurroundingPixelsImageSubFilter", MatrixCollectionSurroundingPixelsImageSubFilter},{"ImageTransparent", ImageTransparent},{"MatrixImageAlphaBlendSubFilter", MatrixImageAlphaBlendSubFilter},{"ImageAlphaCollectionSmoothBlend", ImageAlphaCollectionSmoothBlend},{"ImageRandomColormap", ImageRandomColormap},{"ImageRandomColormapAlphaBlend", ImageRandomColormapAlphaBlend},{"ImageRandomColormapAlphaScale", ImageRandomColormapAlphaScale},{"ImageRandomColormapSubFilter", ImageRandomColormapSubFilter},{"ImageShuffle", ImageShuffle},{"ImageSubFilter", ImageSubFilter},{"ImageAlphaBlendWithFrameSubFilter", ImageAlphaBlendWithFrameSubFilter},{"ImageFadeInOut", ImageFadeInOut},{"ImageFadeBlackInOut", ImageFadeBlackInOut},{"ImageFadeBlackInOutSubFilter", ImageFadeBlackInOutSubFilter},{"ImageFadeFrameInOut", ImageFadeFrameInOut},{"ImageFadeFrameInOutSubFilter",ImageFadeFrameInOutSubFilter},{"ImageFadeDouble", ImageFadeDouble},{"BlendSubFilterAndImage", BlendSubFilterAndImage},{"FadeSubFilter", FadeSubFilter},{"FadeSubFilterRev", FadeSubFilterRev},{"ImageBlendSubFilterMedianBlend", ImageBlendSubFilterMedianBlend},{"FadeSubFilterXor", FadeSubFilterXor},{"BlurXorSubFilter",BlurXorSubFilter},{"ColorFlashIncrease", ColorFlashIncrease},{"ScaleFilter", ScaleFilter},{"NegativeDarkenXor", NegativeDarkenXor},{"ImageXor_SubFilter", ImageXor_SubFilter},{"NegateBlendSubFilter(", NegateBlendSubFilter},{"StrobeNegatePixel",StrobeNegatePixel},{"StrobeNegateInOut", StrobeNegateInOut},{"ImageStrobeOnOff", ImageStrobeOnOff},{"AlphaStrobeBlend", AlphaStrobeBlend},{"CannyRandomPixels", CannyRandomPixels},{"FrameImageFadeInOut", FrameImageFadeInOut},{"FrameImageFadeInOutDouble", FrameImageFadeInOutDouble},{"ChangeEachSecond", ChangeEachSecond},{"ShuffleImage", ShuffleImage},{"ChangeImageEachSecond", ChangeImageEachSecond},{"ChangeImageFilterOnOff", ChangeImageFilterOnOff},{"ChangeXorEachSecond", ChangeXorEachSecond},{"MorphXor", MorphXor},{"MorphXorWithSubFilter", MorphXorWithSubFilter},{"MirrorEachSecond", MirrorEachSecond},{"MirrorReverseSubFilter", MirrorReverseSubFilter},{"MirrorReverseSubFilterAlphaBlend", MirrorReverseSubFilterAlphaBlend},{"Mirror_Xor_Combined", Mirror_Xor_Combined},{"MirrorFrameShuffle", MirrorFrameShuffle},{"MirrorShuffleSmooth", MirrorShuffleSmooth},{"Mirror_Xor_Smooth", Mirror_Xor_Smooth},{"XorFrameShuffle", XorFrameShuffle},{"XorMirrorBlendFrame", XorMirrorBlendFrame},{"ImageXorSmooth", ImageXorSmooth},{"SmoothSubFilter64", SmoothSubFilter64},{"SmoothMedian64", SmoothMedian64},{"SmoothMedian32_SubFilter", SmoothMedian32_SubFilter},{"SmoothAlphaMedian_SubFilter", SmoothAlphaMedian_SubFilter},{"SmoothImage_SubFilter", SmoothImage_SubFilter},{"SmoothImageMedian_SubFilter", SmoothImageMedian_SubFilter},{"SmoothImageAndSubFilter", SmoothImageAndSubFilter},{"SmoothSubFilter90", SmoothSubFilter90},{"SmoothMedianImageSubFilter16", SmoothMedianImageSubFilter16},{"ImageNegate", ImageNegate},{"ImageNegateAlphaBlend", ImageNegateAlphaBlend},{"ImageNegateAlphaBlendSubFilter", ImageNegateAlphaBlendSubFilter},{"FrameNegateAlphaBlendImage", FrameNegateAlphaBlendImage},{"DarkTrailsEffect", DarkTrailsEffect},{"DarkNegate", DarkNegate},{"ChannelSortMedianBlend",ChannelSortMedianBlend},{"MatrixCollectionMirrorDirection", MatrixCollectionMirrorDirection},{"StrobeRandomChannel", StrobeRandomChannel},{"SplitFramesSort", SplitFramesSort},{"SplitFrameSortSubFilter", SplitFrameSortSubFilter},{"MedianBlend64", MedianBlend64},{"SplitFrameFilter", SplitFrameFilter},{"SplitFrameBlend", SplitFrameBlend},{"SplitFrameBlendSubFilter", SplitFrameBlendSubFilter},{"SplitFrameCollection", SplitFrameCollection},{"SplitFrameMirror", SplitFrameMirror},{"RandomChannels", RandomChannels},{"SmoothRandomChannels", SmoothRandomChannels},{"SmoothChannelSubFilter", SmoothChannelSubFilter},{"IncreaseRGB", IncreaseRGB},{"IncreaseColor", IncreaseColor},{"SaturateBlend", SaturateBlend},{"SaturateBlendSubFilter", SaturateBlendSubFilter},{"MaxRGB", MaxRGB},{"XorDifferenceFilter", XorDifferenceFilter},{"AlphaBlendChannelSort", AlphaBlendChannelSort},{"ColorTrailsFilter", ColorTrailsFilter},{"ColorTrailsSubFilter", ColorTrailsSubFilter},{"DarkNegateRainbowMedian", DarkNegateRainbowMedian},{"IncreaseQuick", IncreaseQuick},{"IncreaseRandomIndex", IncreaseRandomIndex},{"ImageChannelSubFilter", ImageChannelSubFilter}, + {"No Filter",NoFilter}, + {"Blend with Source",BlendWithSource}, {"Plugin",plugin}, {"Custom",custom}, {"Blend With Image #1",blendWithImage}, {"TriBlend with Image", triBlendWithImage}, {"Image Strobe",imageStrobe}}; + + FilterType *filter_array = filters; + FilterType filterByIndex(const int &num) { + return filter_array[num]; + } + FilterType filterByString(const std::string &num) { + return filter_array[ac::filter_map[num]]; + } + std::unordered_map filter_map_str; +} + +cv::Mat blend_image, color_image, color_bg_image,color_replace_image,color_filter; +bool blend_set = false; +bool colorkey_set = false; +bool colorkey_bg = false; +bool colorkey_replace = false; +bool colorkey_filter = false; +// return version info +std::string ac::getVersion() { + return version; +} +// be sure to call this on startup +void ac::fill_filter_map() { + for(int i = 0; i < ac::draw_max; ++i) + filter_map[draw_strings[i]] = i; + for(int i = 0; i < ac::draw_max-3; ++i) + filter_map_str[filters[i].first] = filters[i]; + ac::init_filter_menu_map(); +} + +void ac::DrawFilter(const std::string &name, const cv::Mat &frame, cv::Mat &outframe) { + outframe = frame.clone(); + CallFilter(name, outframe); +} + +void ac::DrawFilter(int index, const cv::Mat &frame, cv::Mat &outframe) { + outframe = frame.clone(); + CallFilter(index, outframe); +} +void ac::DrawFilter(int index, cv::Mat &frame) { + CallFilter(index, frame); +} +void ac::DrawFilter(const std::string &name, cv::Mat &frame) { + CallFilter(name, frame); +} + +bool ac::CallFilter(int index, cv::Mat &frame) { + if(index >= 0 && index < ac::draw_max) { + DrawFilterUnordered(ac::draw_strings[index], frame); + return true; + } + return false; +} + +bool ac::CallFilter(const std::string &name, cv::Mat &frame) { + int index = ac::filter_map[name]; + if(index >= 0 && index < ac::draw_max) { + DrawFilterUnordered(name, frame); + return true; + } + return false; +} + +void ac::DrawFilterUnordered(const std::string &name, cv::Mat &frame) { + if(filter_map_str.find(name) != filter_map_str.end()) + filter_map_str[name].second(frame); +} + + +void ac::swapColors(cv::Mat &frame, int y, int x) { + if(in_custom == true) return; + if(color_order == 0 && swapColor_r == 0 && swapColor_g == 0 && swapColor_b == 0) return; // if no swap needed return + if(set_color_map > 0 && color_map_set == false) { + return; + } + swapColors_(frame, y, x); +} + +void ac::swapColors_(cv::Mat &frame, int y, int x) { + cv::Vec3b &cur = frame.at(y,x); + cur[0] += swapColor_b; + cur[1] += swapColor_g; + cur[2] += swapColor_r; + cv::Vec3b temp;// temp + temp = cur;// temp = cur + // Default color order is BGR + // swap RGB orders + switch(color_order) { + case 1: // RGB + cur[0] = temp[2]; + cur[1] = temp[1]; + cur[2] = temp[0]; + break; + case 2:// GBR + cur[0] = temp[1]; + cur[1] = temp[0]; + break; + case 3:// BRG + cur[1] = temp[2]; + cur[2] = temp[1]; + break; + case 4: // GRB + cur[0] = temp[1]; + cur[1] = temp[2]; + cur[2] = temp[0]; + break; + } +} +// invert pixel in frame at x,y +void ac::invert(cv::Mat &frame, int y, int x) { + if(in_custom == true) return; + cv::Vec3b &cur = frame.at(y,x);// cur pixel + cur[0] = ~cur[0]; // bit manipulation sets opposite + cur[1] = ~cur[1]; + cur[2] = ~cur[2]; +} + +// proc position +void ac::procPos(int &direction, double &pos, double &pos_max, const double max_size, double iter) { + if(alpha_increase != 0) iter = alpha_increase; + switch(proc_mode) { + case 0: { // move in - increase move out movin - increase move out + // static int direction + // pos max + // if direction equals 1 + if(direction == 1) { + pos += iter; // pos plus equal 0.05 + if(pos > pos_max) { // if pos > pos max + pos = pos_max; // pos = pos_max + direction = 0;// direction equals 0 + pos_max += 0.5; // pos_max increases by 0.5 + } + } else if(direction == 0) {// direction equals 0 + pos -= iter;// pos -= 0.05 + if(pos <= 1.0) {// if pos <= 1.0 + if(pos_max > max_size) pos_max = 1.0;// if pos max at maxmium + // set to 1.0 + direction = 1;// set direction back to 1 + } + } + } + break; + case 1: { // flat fade in fade out + if(direction == 1) { + pos += iter; + if(pos > max_size) direction = 0; + + } else if(direction == 0) { + pos -= iter; + if(pos <= 1) direction = 1; + } + + } + break; + case 2: { + pos += iter; + if(pos >= pos_max) { + pos = 1.0; + } + } + break; + } + resetAlpha(direction, pos); +} + + +void ac::setProcMode(int value) { + proc_mode = value; +} + diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter10.cpp b/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter10.cpp new file mode 100755 index 0000000..46d1542 --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter10.cpp @@ -0,0 +1,1146 @@ +/* + * Software written by Jared Bruni https://github.com/lostjared + + This software is dedicated to all the people that experience mental illness. + + Website: http://lostsidedead.com + YouTube: http://youtube.com/LostSideDead + Instagram: http://instagram.com/jaredbruni + Twitter: http://twitter.com/jaredbruni + Facebook: http://facebook.com/LostSideDead0x + + You can use this program free of charge and redistrubute it online as long + as you do not charge anything for this program. This program is meant to be + 100% free. + + BSD 2-Clause License + + Copyright (c) 2019, Jared Bruni + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + */ + +#include"ac.h" + +void ac::ExpandSquareSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "ExpandSquareSubFilter") + return; + + static int start_x = frame.cols/2; + static int stop_x = frame.cols/2; + static int speed = frame.cols/24; + cv::Mat frame_copy = frame.clone(); + cv::Mat output; + CallFilter(subfilter, frame_copy); + for(int z = 0; z < frame.rows; ++z) { + for(int i = start_x; i < stop_x; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + pixel = frame_copy.at(z, i); + } + } + static int dir = 1; + if(dir == 1) { + start_x -= speed; + stop_x += speed; + if(start_x <= 0 || stop_x > frame.cols-1) { + dir = 0; + } + } else { + start_x += speed; + stop_x -= speed; + if(start_x >= (frame.cols/2)-1 || stop_x <= (frame.cols/2)-1) { + dir = 1; + } + } + AddInvert(frame); +} + +void ac::ExpandSquareBlendSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "ExpandSquareSubFilter") + return; + static int start_x = frame.cols/2; + static int stop_x = frame.cols/2; + static int speed = frame.cols/24; + static double alpha = 1.0, alpha_max = 4.0; + cv::Mat frame_copy = frame.clone(); + cv::Mat output; + CallFilter(subfilter, frame_copy); + for(int z = 0; z < frame.rows; ++z) { + for(int i = start_x; i < stop_x; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = frame_copy.at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] = static_cast(pixel[j]*(alpha+1)) ^ static_cast(pix[j]*alpha); + } + } + static int dir = 1; + if(dir == 1) { + start_x -= speed; + stop_x += speed; + if(start_x <= 0 || stop_x > frame.cols-1) { + dir = 0; + } + } else { + start_x += speed; + stop_x -= speed; + if(start_x >= (frame.cols/2)-1 || stop_x <= (frame.cols/2)-1) { + dir = 1; + } + } + static int direction = 1; + procPos(direction, alpha, alpha_max); + AddInvert(frame); +} + +void ac::ExpandSquareVerticalSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "ExpandSquareVerticalSubFilter") + return; + static int start_x = frame.rows/2; + static int stop_x = frame.rows/2; + static int speed = frame.rows/24; + cv::Mat frame_copy = frame.clone(); + cv::Mat output; + CallFilter(subfilter, frame_copy); + for(int z = 0; z < frame.cols; ++z) { + for(int i = start_x; i < stop_x; ++i) { + cv::Vec3b &pixel = frame.at(i, z); + pixel = frame_copy.at(i, z); + } + } + static int dir = 1; + if(dir == 1) { + start_x -= speed; + stop_x += speed; + if(start_x <= 0 || stop_x > frame.rows-1) { + dir = 0; + } + } else { + start_x += speed; + stop_x -= speed; + if(start_x >= (frame.rows/2)-1 || stop_x <= (frame.rows/2)-1) { + dir = 1; + } + } + AddInvert(frame); +} + +void ac::DarkImageMedianBlend(cv::Mat &frame) { + if(blend_set == true) { + SmoothImageAlphaBlend(frame); + cv::Mat frame_copy = frame.clone(); + setGamma(frame_copy,frame,5); + MedianBlend(frame); + } +} + +void ac::GammaDarken5(cv::Mat &frame) { + cv::Mat frame_copy = frame.clone(); + setGamma(frame_copy, frame, 5); +} + +void ac::GammaDarken10(cv::Mat &frame) { + cv::Mat frame_copy = frame.clone(); + setGamma(frame_copy, frame, 10); +} + +void ac::SelfAlphaScaleBlend(cv::Mat &frame) { + static double alpha = 1.0, alpha_max = 4.0; + static MatrixCollection<4> collection; + collection.shiftFrames(frame); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + unsigned int val = 0; + for(int j = 0; j < 3; ++j) { + val += static_cast(pixel[j]*(alpha+1)); + pixel[j] = pixel[j]^val; + } + + } + } + static int dir = 1; + procPos(dir,alpha,alpha_max); + AddInvert(frame); +} + +void ac::FadeBars(cv::Mat &frame) { + unsigned char ch[3] = {static_cast(rand()%255), static_cast(rand()%255), static_cast(rand()%255)}; + static double alpha = 1.0, alpha_max = 4.0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = static_cast((pixel[j]^ch[j])*alpha); + ++ch[j]; + } + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 5.0, 0.1); + AddInvert(frame); +} + +void ac::MirrorXorAlpha(cv::Mat &frame) { + static double alpha[3] = {1.0, 3.0, 1.0}, alpha_max = 3.0; + static cv::Vec3b color_(rand()%255, rand()%255, rand()%255); + cv::Mat frame_copy = frame.clone(); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b values[3]; + values[0] = frame_copy.at(frame.rows-z-1, frame.cols-i-1); + values[1] = frame_copy.at(frame.rows-z-1, i); + values[2] = frame_copy.at(z, frame.cols-i-1); + for(int j = 0; j < 3; ++j) { + pixel[j] = cv::saturate_cast(static_cast((pixel[j]*alpha[j])) ^ static_cast((values[0][j]*alpha[j])) ^ static_cast((values[1][j]*alpha[j])) ^ static_cast((values[2][j]*alpha[j]))); + pixel[j] = pixel[j]^color_[j]; + } + } + } + AddInvert(frame); + static int dir[3] = {1, 0, 1}; + for(int j = 0; j < 3; ++j) { + if(dir[j] == 1) { + color_[j] += 5; + } else if(dir[j] == 0) { + color_[j] -= 5; + } + procPos(dir[j], alpha[j], alpha_max, 4.0, 0.1); + } +} + +void ac::MirrorEnergizeSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "MirrorEnergizeSubFilter") + return; + DarkenImage(frame, 6); + MirrorXorAlpha(frame); + EnergizeSubFilter(frame); + AddInvert(frame); +} + +void ac::StrobeXor(cv::Mat &frame) { + cv::Vec3b pix(rand()%255, rand()%255, rand()%255); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] = pixel[j]^pix[j]; + } + } + AddInvert(frame); +} + +void ac::IntertwinedMirror(cv::Mat &frame) { + cv::Mat frame_copy = frame.clone(); + int lines = 0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b values[3]; + values[0] = frame_copy.at(frame.rows-z-1, frame.cols-i-1); + values[1] = frame_copy.at(frame.rows-z-1, i); + values[2] = frame_copy.at(z, frame.cols-i-1); + for(int j = 0; j < 3; ++j) { + pixel[j] = pixel[j]^values[lines][j]; + } + } + ++lines; + if(lines > 2) + lines = 0; + } + AddInvert(frame); +} + +void ac::BlurredMirror(cv::Mat &frame) { + cv::Mat frame_copy; + cv::medianBlur(frame, frame_copy, 3); + DarkenImage(frame_copy, 2); + DarkenImage(frame, 2); + static double alpha = 1.0, alpha_max = 4.0; + int lines = 0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b values[3]; + values[0] = frame_copy.at(frame.rows-z-1, frame.cols-i-1); + values[1] = frame_copy.at(frame.rows-z-1, i); + values[2] = frame_copy.at(z, frame.cols-i-1); + for(int j = 0; j < 3; ++j) + pixel[j] = static_cast((pixel[j] * (1+alpha))) ^ static_cast((values[lines][j]*alpha)); + } + ++lines; + if(lines > 2) + lines = 0; + } + MedianBlend(frame); + static int dir = 1; + procPos(dir, alpha, alpha_max); + AddInvert(frame); +} + +void ac::ShadeRGB(cv::Mat &frame) { + cv::Mat frame_copy; + frame_copy = frame.clone(); + DarkenImage(frame_copy, 2); + DarkenImage(frame, 2); + static double alpha = 1.0, alpha_max = 4.0; + int lines = 0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b values[6]; + values[0] = frame_copy.at(frame.rows-z-1, frame.cols-i-1); + values[1] = frame_copy.at(frame.rows-z-1, i); + values[2] = frame_copy.at(z, frame.cols-i-1); + if(lines <= 2) + pixel[lines] += static_cast((pixel[lines] * alpha)) ^ static_cast((values[lines][lines]*alpha)); + } + ++lines; + if(lines > 2) + lines = 0; + + } + MedianBlend(frame); + static int dir = 1; + procPos(dir, alpha, alpha_max); + AddInvert(frame); +} + +void ac::InterRGB_SubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "InterRGB_SubFilter") + return; + cv::Mat frame_copy = frame.clone(); + CallFilter(subfilter, frame_copy); + int index = 0; + static double alpha = 1.0, alpha_max = 4.0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = frame_copy.at(z, i); + switch(index) { + case 0: + pixel[0] = static_cast(pixel[0]*alpha); + pixel[1] = pix[1]; + pixel[2] = pix[2]; + break; + case 1: + pixel[0] = pix[0]; + pixel[1] = static_cast(pixel[1]*alpha); + pixel[2] = pix[2]; + break; + case 2: + pixel[0] = pix[0]; + pixel[1] = pix[1]; + pixel[2] = static_cast(pixel[2]*alpha); + break; + } + } + ++index; + if(index > 2) + index = 0; + } + static int dir = 1.0; + procPos(dir, alpha, alpha_max, 4.1, 0.05); + AddInvert(frame); +} + +void ac::InterSmoothSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "InterSmoothSubFilter") + return; + static MatrixCollection<8> collection; + cv::Mat frame_copy = frame.clone(); + CallFilter(subfilter, frame_copy); + int index = 0; + static double alpha = 1.0, alpha_max = 4.0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = frame_copy.at(z, i); + switch(index) { + case 0: + for(int j = 0; j < 3; ++j) + pixel[j] = static_cast(pixel[j]*(alpha+1))^pix[j]; + break; + case 1: + pixel = pix; + break; + } + } + ++index; + if(index > 1) + index = 0; + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 4.1, 0.05); + collection.shiftFrames(frame); + Smooth(frame, &collection); + AddInvert(frame); +} + +void ac::InterRGB_Bars_XY(cv::Mat &frame) { + unsigned int index = 0; + static double alpha = 1.0, alpha_max = 4.0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = pixel[j]^static_cast((i+z)*alpha); + } + pixel[index] = 255; + } + ++index; + if(index > 2) + index = 0; + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 4.1, 0.05); + AddInvert(frame); +} + +void ac::InterRGB_Bars_X(cv::Mat &frame) { + unsigned int index = 0; + static double alpha = 1.0, alpha_max = 4.0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = pixel[j]^static_cast(i*alpha); + } + pixel[index] = 255; + } + ++index; + if(index > 2) + index = 0; + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 4.1, 0.05); + AddInvert(frame); +} + +void ac::InterRGB_Bars_Y(cv::Mat &frame) { + unsigned int index = 0; + static double alpha = 1.0, alpha_max = 4.0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = pixel[j]^static_cast(z*alpha); + } + pixel[index] = 255; + } + ++index; + if(index > 2) + index = 0; + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 4.1, 0.05); + AddInvert(frame); +} + +void ac::StoredFramesAlphaBlend_SubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "StoredFramesAlphaBlend_SubFilter") + return; + static MatrixCollection<8> collection; + static double alpha = 1.0, alpha_max = 4.0; + cv::Mat frame_copy = frame.clone(); + CallFilter(subfilter, frame_copy); + cv::Mat fcopy = frame.clone(); + AlphaBlend(fcopy, frame_copy, frame, alpha); + collection.shiftFrames(frame); + Smooth(frame, &collection); + static int dir = 1; + procPos(dir, alpha, alpha_max, 4.1, 0.05); + AddInvert(frame); +} + +void ac::BlendSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "BlendSubFilter") + return; + cv::Mat frame_copy = frame.clone(); + CallFilter(subfilter, frame_copy); + int index = 0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = frame_copy.at(z, i); + switch(index) { + case 0: + break; + case 1: + pixel = pix; + break; + } + ++index; + if(index > 1) + index = 0; + } + } + AddInvert(frame); +} + +void ac::BlendAlphaSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "BlendAlphaSubFilter") + return; + cv::Mat frame_copy = frame.clone(); + CallFilter(subfilter, frame_copy); + static double alpha = 1.0, alpha_max = 4.0; + int index = 0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = frame_copy.at(z, i); + switch(index) { + case 0: + for(int j = 0; j < 3; ++j) + pixel[j] = static_cast(pixel[j]*(alpha+1)) ^ static_cast(pix[j]*alpha); + break; + case 1: + pixel = pix; + break; + } + ++index; + if(index > 1) + index = 0; + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 4.1, 0.05); + AddInvert(frame); +} + +// duplicate for right now +void ac::ReverseFrameBlend(cv::Mat &frame) { + cv::Mat frame_copy = frame.clone(); + Reverse(frame_copy); + MedianBlend(frame_copy); + int index = 0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = frame_copy.at(z, i); + switch(index) { + case 0: + break; + case 1: + pixel = pix; + break; + } + ++index; + if(index > 1) + index = 0; + } + } + AddInvert(frame); +} + +void ac::ReverseFrameBlendSwitch(cv::Mat &frame) { + cv::Mat frame_copy = frame.clone(); + Reverse(frame_copy); + MedianBlend(frame_copy); + static bool onval = true; + int index = 0; + if(onval == false) + index = 1; + onval = (onval == true) ? false : true; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = frame_copy.at(z, i); + switch(index) { + case 0: + break; + case 1: + pixel = pix; + break; + } + ++index; + if(index > 1) + index = 0; + } + } + AddInvert(frame); +} + +void ac::DoubleRandomMirror(cv::Mat &frame) { + cv::Mat frame_copy1 = frame.clone(); + RandomMirror(frame_copy1); + RandomMirror(frame); + int index = 0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = frame_copy1.at(z, i); + switch(index) { + case 0: + break; + case 1: + pixel = pix; + break; + } + ++index; + if(index > 1) + index = 0; + } + } + AddInvert(frame); +} + +void ac::Blend_AlphaSubFilter(cv::Mat &frame) { + + if(subfilter == -1 || ac::draw_strings[subfilter] == "Blend_AlphaSubFilter") + return; + + cv::Mat frame_copy1 = frame.clone(); + RandomBlendFilter(frame); + CallFilter(subfilter, frame_copy1); + int index = 0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = frame_copy1.at(z, i); + switch(index) { + case 0: + break; + case 1: + pixel = pix; + break; + } + ++index; + if(index > 1) + index = 0; + } + } + AddInvert(frame); +} + +void ac::RandomBlendFilter(cv::Mat &frame) { + static std::vector vzBlend { "Self AlphaBlend", "Self Scale", "Blend #3", "Negative Paradox", "ThoughtMode", "RandTriBlend", "Filter3","Rainbow Blend","Rand Blend","Pixel Scale","Pulse", "Combine Pixels", "Blend_Angle", "XorMultiBlend", "UpDown","LeftRight", "BlendedScanLines","XorSine", "FrameBlend", "FrameBlendRGB", "PrevFrameBlend", "HorizontalBlend", "VerticalBlend", "OppositeBlend", "DiagonalLines", "HorizontalLines", "BlendSwitch", "IncreaseBlendHorizontal", "BlendIncrease", "ColorRange", "VectorIncrease", "BlendThree", "HorizontalStripes", "Dual_SelfAlphaRainbow", "Dual_SelfAlphaBlur", "SurroundPixelXor", "WeakBlend", "AverageVertical", "RandomAlphaBlend", "RandomTwoFilterAlphaBlend", "AlphaBlendPosition", "BlendRowAlpha", "BlendRow", "BlendRowByVar", "BlendRowByDirection", "BlendAlphaXor", "SelfXorScale", "SelfAlphaRGB", "XorSelfAlphaImage", "AlphaBlendRandom", "ChannelSortAlphaBlend", "RandomXor", "RandomXorFlash", "SoftXor", "SelfXorBlend", "SelfXorDoubleFlash", "SelfOrDoubleFlash", "BlendRowCurvedSqrt", "CycleShiftRandomAlphaBlend", "TanAlphaGrid", "BlendInAndOut", "BlendScaleInAndOut", "AcidGlitch", "LiquidFilter", "MatrixXorAnd", "XorAlpha", "SelfXorAverage", "RandomXorBlend", "RGBVerticalXor", "RGBVerticalXorScale", "RGBHorizontalXor", "RGBHorizontalXorScale", "FadeInAndOut", "InitBlend", "LagBlend", "AddFilter", "RandBlend", "EveryOther","StaticXorBlend", "XorScale", "Bitwise_XOR_Blend", "Bitwise_OR_Blend", "Bitwise_AND_Blend", "PixelReverseXor", "SilverBlend", "PixelXorBlend", "SelfAlphaScale", "SelfScaleAlpha", "RainbowXorBlend", "FadeBlend", "SelfAlphaScaleBlend", "FadeBars", "ShadeRGB", "InterRGB_Bars_XY", "InterRGB_Bars_X", "InterRGB_Bars_Y", "ReverseFrameBlend", "ReverseFrameBlendSwitch"}; + + CallFilter(vzBlend[rand()%vzBlend.size()], frame); + AddInvert(frame); +} + +void ac::DoubleRandomBlendFilter(cv::Mat &frame) { + cv::Mat frame_copy1 = frame.clone(); + RandomBlendFilter(frame_copy1); + RandomBlendFilter(frame); + int index = 0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = frame_copy1.at(z, i); + switch(index) { + case 0: + break; + case 1: + pixel = pix; + break; + } + ++index; + if(index > 1) + index = 0; + } + } + AddInvert(frame); +} + +void ac::FlipBlendWH(cv::Mat &frame) { + cv::Mat frame_copy1; + cv::flip(frame, frame_copy1, -1); + int index = 0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = frame_copy1.at(z, i); + switch(index) { + case 0: + break; + case 1: + pixel = pix; + break; + } + ++index; + if(index > 1) + index = 0; + } + } + AddInvert(frame); +} + +void ac::FlipBlendH(cv::Mat &frame) { + cv::Mat frame_copy1; + cv::flip(frame, frame_copy1, 0); + int index = 0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = frame_copy1.at(z, i); + switch(index) { + case 0: + break; + case 1: + pixel = pix; + break; + } + ++index; + if(index > 1) + index = 0; + } + } + AddInvert(frame); +} + +void ac::FlipBlendW(cv::Mat &frame) { + cv::Mat frame_copy1; + cv::flip(frame, frame_copy1, 1); + int index = 0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = frame_copy1.at(z, i); + switch(index) { + case 0: + break; + case 1: + pixel = pix; + break; + } + ++index; + if(index > 1) + index = 0; + } + } + AddInvert(frame); +} + +void ac::FlipBlendAll(cv::Mat &frame) { + cv::Mat frame_copy[3]; + cv::flip(frame, frame_copy[0], 0); + cv::flip(frame, frame_copy[1], 1); + cv::flip(frame, frame_copy[2], -1); + int index = 0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix[3]; + pix[0] = frame_copy[0].at(z, i); + pix[1] = frame_copy[1].at(z, i); + pix[2] = frame_copy[2].at(z, i); + switch(index) { + case 0: + break; + case 1: + pixel = pix[0]; + break; + case 2: + pixel = pix[1]; + break; + case 3: + pixel = pix[2]; + break; + } + ++index; + if(index > 3) + index = 0; + } + } + AddInvert(frame); +} + +void ac::FrameMedianBlendSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "FrameMedianBlendSubFilter") + return; + cv::Mat frame_copy; + cv::flip(frame, frame_copy, 1); + CallFilter(subfilter, frame_copy); + MedianBlend(frame_copy); + int index = 0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = frame_copy.at(z, i); + switch(index) { + case 0: + break; + case 1: + pixel = pix; + break; + } + ++index; + if(index > 1) + index = 0; + } + } + MedianBlur(frame); + RainbowXorBlend(frame); + AddInvert(frame); +} + +void ac::FrameBlurSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "FrameBlurSubFilter") + return; + static double alpha = 1.0, alpha_max = 4.0; + cv::Mat frame_copy1 = frame.clone(); + cv::Mat frame_copy2 = frame.clone(); + MedianBlur(frame_copy1); + CallFilter(subfilter, frame_copy1); + MedianBlur(frame_copy1); + MedianBlur(frame_copy2); + AlphaBlend(frame_copy1, frame_copy2, frame, alpha); + MedianBlur(frame); + static int dir = 1; + procPos(dir, alpha, alpha_max, 4.1, 0.05); + AddInvert(frame); +} + +void ac::ImageBlendSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "ImageBlendSubFilter") + return; + + if(blend_set == true) { + cv::Mat frame_copy1 = frame.clone(); + ExactImage(frame_copy1); + CallFilter(subfilter, frame_copy1); + + int index = 0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix1 = frame_copy1.at(z, i); + switch(index) { + case 0: + break; + case 1: + pixel = pix1; + break; + } + ++index; + if(index > 1) + index = 0; + } + } + } + +} + +void ac::ImageBlendXorSubFilter(cv::Mat &frame) { + if(blend_set == false || subfilter == -1 || ac::draw_strings[subfilter] == "ImageBlendXorSubFilter") + return; + static double alpha = 1.0, alpha_max = 4.0; + cv::Mat frame_copy1 = frame.clone(); + cv::Mat frame_copy2 = frame.clone(); + ExactImage(frame_copy1); + CallFilter(subfilter, frame_copy2); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix[3]; + pix[0] = frame_copy1.at(z, i); + pix[1] = frame_copy2.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = pixel[j]^static_cast(pix[0][j]*alpha)^pix[1][j]; + } + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 4.1, 0.05); +} + +void ac::ImageCollectionSubFilter(cv::Mat &frame) { + if(blend_set == false || subfilter == -1 || ac::draw_strings[subfilter] == "ImageBlendXorSubFilter") + return; + static double alpha = 1.0, alpha_max = 4.0; + static int dir = 1; + cv::Mat frame_copy1 = frame.clone(); + cv::Mat frame_copy2 = frame.clone(); + ExactImage(frame_copy1); + AlphaBlend(frame_copy1, frame_copy2, frame, alpha); + CallFilter(subfilter, frame); + static MatrixCollection<8> collection; + collection.shiftFrames(frame); + Smooth(frame, &collection); + procPos(dir, alpha, alpha_max, 4.1, 0.05); + AddInvert(frame); +} + +void ac::SelfScaleXorIncrease(cv::Mat &frame) { + static double alpha = 1.0, increase_val = 0.05, limit_start = 1.0, limit = limit_start,min_start = 4.0, min = min_start, max = 10.0, rev_max = 1.0; + if(alpha_increase != 0) + increase_val = alpha_increase; + else + increase_val = 0.05; + + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] = static_cast(pixel[j]*(alpha+1))^static_cast(alpha*15); + } + } + static int dir = 1; + if(dir == 1) { + alpha += increase_val; + if(alpha >= limit) { + dir = 0; + limit += 1.0; + if(limit > max) { + limit = limit_start; + } + } + } else if(dir == 0) { + alpha -= increase_val; + if(alpha <= min) { + dir = 1; + min -= 1.0; + if(min < rev_max) { + min = min_start; + } + } + } + AddInvert(frame); +} + +void ac::Blend_RedGreenBlue(cv::Mat &frame) { + static cv::Scalar values(rand()%255, rand()%255, rand()%255); + static double speed_val = 5.0; + if(reset_alpha) { + for(int j = 0; j < 3; ++j) + values[j] = rand()%255; + } + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] += values[j]; + } + } + } + for(int j = 0; j < 3; ++j) { + if(values[j] > 255) { + values[j] = 0; + break; + } else { + values[j] += speed_val; + } + } + AddInvert(frame); +} + +void ac::XorBlend_RedGreenBlue(cv::Mat &frame) { + static cv::Scalar values(rand()%255, rand()%255, rand()%255); + static double speed_val = 2.5; + if(reset_alpha) { + for(int j = 0; j < 3; ++j) + values[j] = rand()%255; + } + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = pixel[j]^static_cast(0.5*values[j]); + } + } + } + for(int j = 0; j < 3; ++j) { + if(values[j] > 255) { + values[j] = 0; + break; + } else { + values[j] += speed_val; + } + } + AddInvert(frame); + +} + +void ac::BlendIncrease_RedGreenBlue(cv::Mat &frame) { + static bool values_dir[3]; + static cv::Scalar values(rand()%255, rand()%255, rand()%255); + static double speed_val = 1.5; + if(reset_alpha) { + for(int j = 0; j < 3; ++j) + values[j] = rand()%255; + } + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] += static_cast(0.5 * values[j]); + } + } + } + for(int j = 0; j < 3; ++j) { + if(values[j] > 255) { + if(values_dir[j] == true) + values_dir[j] = false; + else + values_dir[j] = true; + break; + } else { + if(values_dir[j] == true) + values[j] += speed_val; + else + values[j] -= speed_val; + } + } + AddInvert(frame); +} + +void ac::Blend_RedReenBlue_Dark(cv::Mat &frame) { + static cv::Scalar values(rand()%255, rand()%255, rand()%255); + static double speed_val = 5.0; + if(reset_alpha) { + for(int j = 0; j < 3; ++j) + values[j] = rand()%255; + } + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + unsigned int val = static_cast(values[j]); + if(pixel[j] == 0) pixel[j] = 1; + pixel[j] = val%pixel[j]; + } + } + } + for(int j = 0; j < 3; ++j) { + if(values[j] > 255) { + values[j] = 0; + break; + } else { + values[j] += speed_val; + } + } + AddInvert(frame); +} + +void ac::DarkModBlend(cv::Mat &frame) { + static cv::Scalar values(rand()%255, rand()%255, rand()%255); + static double speed_val = 5.0; + if(reset_alpha) { + for(int j = 0; j < 3; ++j) + values[j] = rand()%255; + } + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + unsigned int val = static_cast(values[j]); + if(pixel[j] == 0) pixel[j] = 1; + pixel[j] = (val^pixel[j]); + if(pixel[j] == 0) pixel[j] = 1; + pixel[j] = val%pixel[j]; + } + } + } + for(int j = 0; j < 3; ++j) { + if(values[j] > 255) { + for(int q = 0; q < 3; ++q) + values[j] = rand()%255; + values[j] = 0; + break; + } else { + values[j] += speed_val; + } + } + AddInvert(frame); +} + +void ac::PictureBuzz(cv::Mat &frame) { + static cv::Scalar values(rand()%255, rand()%255, rand()%255); + cv::Vec3b l_values; + static double speed_val = 0.01; + if(reset_alpha) { + for(int j = 0; j < 3; ++j) + values[j] = rand()%255; + } + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + l_values[j] += pixel[j]; + unsigned int val = static_cast(values[j]); + if(l_values[j] == 0) l_values[j] = 1; + pixel[j] += val%l_values[j]; + } + } + } + for(int j = 0; j < 3; ++j) { + if(values[j] > 1024) { + values[j] = 0; + break; + } else { + values[j] += speed_val; + } + } + AddInvert(frame); +} + +void ac::IncDifference(cv::Mat &frame) { + static cv::Mat fcopy = frame.clone(); + static cv::Size size_var; + if(fcopy.size() != frame.size()) { + fcopy = frame.clone(); + } + for(unsigned int z = 0; z < frame.rows; ++z) { + for(unsigned int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b back = pixel; + cv::Vec3b &pix_cp = fcopy.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] += pix_cp[j]; + pix_cp[j] = 255-back[j]; + } + } + } + AddInvert(frame); +} + +void ac::IncDifferenceAlpha(cv::Mat &frame) { + static double alpha = 1.0, alpha_max = 4.0; + static cv::Mat fcopy = frame.clone(); + static cv::Size size_var; + int index = rand()%3; + if(fcopy.size() != frame.size()) { + fcopy = frame.clone(); + } + for(unsigned int z = 0; z < frame.rows; ++z) { + for(unsigned int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b back = pixel; + cv::Vec3b &pix_cp = fcopy.at(z, i); + for(int j = 0; j < 3; ++j) { + if(pixel[j] == 0) pixel[j] = 1; + pixel[j] = pix_cp[j]%(1+(pixel[j])); + } + pix_cp[index] = 255-(back[index]*alpha); + } + } + ++index; + if(index > 2) + index = 0; + AddInvert(frame); + static int dir = 1; + procPos(dir, alpha, alpha_max); +} diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter11.cpp b/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter11.cpp new file mode 100755 index 0000000..aea1501 --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter11.cpp @@ -0,0 +1,1013 @@ +/* + * Software written by Jared Bruni https://github.com/lostjared + + This software is dedicated to all the people that experience mental illness. + + Website: http://lostsidedead.com + YouTube: http://youtube.com/LostSideDead + Instagram: http://instagram.com/jaredbruni + Twitter: http://twitter.com/jaredbruni + Facebook: http://facebook.com/LostSideDead0x + + You can use this program free of charge and redistrubute it online as long + as you do not charge anything for this program. This program is meant to be + 100% free. + + BSD 2-Clause License + + Copyright (c) 2019, Jared Bruni + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + */ + +#include "ac.h" + + +void ac::MirrorMedianBlend(cv::Mat &frame) { + static MatrixCollection<8> collection; + cv::Mat mirror = frame.clone(); + RandomMirror(mirror); + collection.shiftFrames(mirror); + Smooth(frame, &collection); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = collection.frames[7].at(z, i); + cv::Vec3b fpixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = (pixel[j]^fpixel[j])/2; + } + } + } + MedianBlend(frame); + AddInvert(frame); +} + +void ac::SubFilterMedianBlend(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "SubFilterMedianBlend") + return; + static MatrixCollection<8> collection; + cv::Mat mirror = frame.clone(); + CallFilter(subfilter, mirror); + collection.shiftFrames(mirror); + Smooth(frame, &collection); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = collection.frames[7].at(z, i); + cv::Vec3b fpixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = (pixel[j]^fpixel[j])/2; + } + } + } + MedianBlend(frame); + AddInvert(frame); +} + +void ac::DarkenBlend(cv::Mat &frame) { + static MatrixCollection<8> collection; + static int dark = 2; + cv::Mat copyf = frame.clone(); + cv::Mat copyo = frame.clone(); + DarkenImage(copyf, dark); + ++dark; + if(dark > 8) + dark = 2; + + collection.shiftFrames(copyf); + Smooth(copyo, &collection); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b cpypix = copyo.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = ((pixel[j]^cpypix[j])/2); + } + } + } + AddInvert(frame); +} + +void ac::DarkCollectionSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "DarkCollectionSubFilter") + return; + static MatrixCollection<8> collection; + cv::Mat copyf = frame.clone(); + CallFilter(subfilter, copyf); + DarkenFilter(copyf); + collection.shiftFrames(copyf); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Scalar s; + cv::Vec3b &pixel = frame.at(z, i); + for(int q = 1; q < collection.size(); ++q) { + cv::Vec3b pix = collection.frames[q].at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = pixel[j]^pix[j]; + s[j] += pixel[j]; + } + } + for(int j = 0; j < 3; ++j) { + s[j] = s[j]/collection.size(); + pixel[j] = static_cast(s[j]); + } + } + } + AddInvert(frame); +} + + +void ac::ChannelSort_NoBlend_Descending(cv::Mat &frame) { + std::vector v; + cv::split(frame, v); + cv::Mat channels[3]; + cv::Mat output; + cv::sort(v[0], channels[0],cv::SORT_DESCENDING); + cv::sort(v[1], channels[1],cv::SORT_DESCENDING); + cv::sort(v[2], channels[2],cv::SORT_DESCENDING); + cv::merge(channels, 3, frame); + AddInvert(frame); +} + +void ac::ChannelSort_NoBlend_Ascending(cv::Mat &frame) { + std::vector v; + cv::split(frame, v); + cv::Mat channels[3]; + cv::Mat output; + cv::sort(v[0], channels[0],cv::SORT_ASCENDING); + cv::sort(v[1], channels[1],cv::SORT_ASCENDING); + cv::sort(v[2], channels[2],cv::SORT_ASCENDING); + cv::merge(channels, 3, frame); + AddInvert(frame); +} + +void ac::Headrush(cv::Mat &frame) { + static MatrixCollection<16> collection; + static int index = 0; + cv::Mat copyf = frame.clone(); + if(index == 0) { + ChannelSort_NoBlend_Descending(copyf); + index = 1; + } else { + ChannelSort_NoBlend_Ascending(copyf); + index = 0; + } + collection.shiftFrames(copyf); + cv::Mat total = frame.clone(); + Smooth(frame, &collection); + AddInvert(frame); +} + +void ac::DarkSmooth_Filter(cv::Mat &frame) { + static int dark = 2; + static MatrixCollection<8> collection; + collection.shiftFrames(frame); + static int dir = 1; + if(dir == 1) { + ++dark; + if(dark > 12) + dir = 0; + } else if(dir == 0) { + --dark; + if(dark <= 2) + dir = 1; + } + + DarkSmooth(frame, &collection, dark); + AddInvert(frame); +} + +void ac::DarkSelfAlpha(cv::Mat &frame) { + cv::Mat copyf = frame.clone(); + double alpha = 1.0, alpha_max = 4.0; + DarkenImage(copyf, 2); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b darkpixel = copyf.at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] = static_cast(pixel[j]*(alpha+1)) ^ static_cast(darkpixel[j]*alpha); + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 4.1, 0.05); + AddInvert(frame); +} + +void ac::FlipMedian(cv::Mat &frame) { + static MatrixCollection<8> collection; + cv::Mat copyf = frame.clone(); + static int index = 0; + switch(index) { + case 0: + FlipBlendAll(copyf); + break; + case 1: + FlipBlendW(copyf); + break; + case 2: + FlipBlendH(copyf); + break; + case 3: + FlipBlendWH(copyf); + break; + } + ++index; + if(index > 3) index = 0; + collection.shiftFrames(copyf); + Smooth(frame, &collection); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::FlipMedianSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "FlipMedianSubFilter") + return; + static MatrixCollection<8> collection; + cv::Mat copyf = frame.clone(); + CallFilter(subfilter, copyf); + FlipBlendAll(copyf); + collection.shiftFrames(copyf); + Smooth(frame, &collection); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::FlipMirror(cv::Mat &frame) { + DarkenFilter(frame); + MirrorXorAll(frame); + FlipBlendAll(frame); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::FlipMirrorAverage(cv::Mat &frame) { + static MatrixCollection<8> collection; + cv::Mat copyf = frame.clone(); + DarkenFilter(copyf); + MirrorXorAll(copyf); + collection.shiftFrames(copyf); + Smooth(frame, &collection); + FlipBlendAll(frame); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::FlipMirrorSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "FlipMirrorSubFilter") + return; + static MatrixCollection<8> collection; + cv::Mat copyf = frame.clone(); + DarkenFilter(copyf); + CallFilter(subfilter, copyf); + collection.shiftFrames(copyf); + Smooth(frame, &collection); + FlipBlendAll(frame); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::ShuffleMedian(cv::Mat &frame) { + static std::vector filter_array{"MedianBlend","MedianBlurXor", "MirrorMedianBlend", "FlipMedian"}; + static int index = 0; + Shuffle(index, frame, filter_array); + AddInvert(frame); +} + +void ac::ShuffleRGB(cv::Mat &frame) { + std::vector filter_array { "RGB Shift", "RGB Sep", "SlideRGB", "GradientRGB", "FrameBlendRGB", "MoveRGB", "LineRGB", "PixelRGB", "RGBFlash", "MirrorRGB", "RGBStatic1", "RGBStatic2", "SelfAlphaRGB", "CycleShiftRGB", "CycleShiftRandomRGB", "CycleShiftRandomRGB_XorBlend", "RGBVerticalXor", "RGBVerticalXorScale", "RGBHorizontalXor", "RGBHorizontalXorScale", "RGBMirror", "RGBTrails", "RGBTrailsDark", "RGBTrailsAlpha", "RGBTrailsNegativeAlpha", "MovementRGBTrails", "RGBTrailsXor", "ShadeRGB"}; + static int index = 0; + Shuffle(index, frame, filter_array); + AddInvert(frame); +} + +void ac::RandomPixels(cv::Mat &frame) { + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] += rand()%255; + } + } + AddInvert(frame); +} + +void ac::DarkRandomPixels(cv::Mat &frame) { + int max = 1+(rand()%255); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] += rand()%max; + pixel[j] /= 4; + } + } + } + AddInvert(frame); +} + +void ac::MedianBlurSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "MedianBlurSubFilter") + return; + static MatrixCollection<8> collection; + static int counter = 1; + cv::Mat copyf = frame.clone(); + for(int i = 0; i < counter; ++i) { + MedianBlur(copyf); + } + CallFilter(subfilter, copyf); + collection.shiftFrames(copyf); + ++counter; + if(counter > 3) + counter = 1; + Smooth(frame, &collection); + AddInvert(frame); +} + +void ac::Bars(cv::Mat &frame) { + static int start = rand()%3; + for(int z = 0; z < frame.rows; ++z) { + int index = start; + for(int i = 0; i < frame.cols; i += 3) { + cv::Vec3b &pixel = frame.at(z, i); + pixel[index] = 255; + ++index; + if(index > 2) + index = 0; + } + } + ++start; + if(start > 2) + start = rand()%3; + AddInvert(frame); +} + +void ac::ShuffleAlpha(cv::Mat &frame) { + static std::vector filter_array {"Self AlphaBlend","ScanAlphaSwitch", "Dual_SelfAlphaRainbow", "Dual_SelfAlphaBlur","BlendAlphaXor","SmoothTrailsSelfAlphaBlend","SelfAlphaRGB","XorAlpha","SelfAlphaScale", "SelfScaleAlpha","DarkSelfAlpha"}; + static int index = 0; + Shuffle(index, frame, filter_array); + AddInvert(frame); +} + +void ac::AlphaMorph(cv::Mat &frame) { + static MatrixCollection<8> collection; + cv::Mat copyf = frame.clone(); + ShuffleAlpha(copyf); + DarkenFilter(copyf); + collection.shiftFrames(copyf); + cv::Mat copyr = frame.clone(); + Smooth(copyf, &collection); + static double alpha = 1.0, alpha_max = 4.0; + static int dir = 1; + AlphaBlend(copyf, copyr, frame, alpha); + procPos(dir, alpha, alpha_max, 4.1, 0.01); + AddInvert(frame); +} + +void ac::ShuffleSelf(cv::Mat &frame) { + static std::vector filter_array {"Self AlphaBlend", "Self Scale", "ReinterpSelfScale", "Dual_SelfAlphaRainbow", "Dual_SelfAlphaBlur","SelfXorScale", "SelfAlphaRGB", "GradientXorSelfScale", "SelfXorBlend", "SelfXorDoubleFlash", "SelfOrDoubleFlash", "SelfXorAverage", "SelfAlphaScale", "SelfScaleAlpha", "SelfAlphaScaleBlend", "SelfScaleXorIncrease", "DarkSelfAlpha"}; + static int index = 0; + Shuffle(index, frame, filter_array); + AddInvert(frame); +} + +void ac::PixelatedHorizontalLines(cv::Mat &frame) { + cv::Vec3b pix(rand()%255, rand()%255, rand()%255); + static double alpha = 1.0, alpha_max = 4.0; + for(int c = 0; c < frame.rows; ++c) { + int start = rand()%frame.cols; + for(int q = start; q < frame.cols; ++q) { + cv::Vec3b &pixel = frame.at(c, q); + for(int j = 0; j < 3; ++j) { + pixel[j] = static_cast((pixel[j]^pix[j])*alpha); + } + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::PixelatedVerticalLines(cv::Mat &frame) { + cv::Vec3b pix(rand()%255, rand()%255, rand()%255); + static double alpha = 1.0, alpha_max = 4.0; + for(int c = 0; c < frame.cols; ++c) { + int start = rand()%frame.rows; + for(int q = start; q < frame.rows; ++q) { + cv::Vec3b &pixel = frame.at(q,c); + for(int j = 0; j < 3; ++j) { + pixel[j] = static_cast((pixel[j]^pix[j])*alpha); + } + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::StrobeShuffle(cv::Mat &frame) { + static std::vector filter_array {"StrobeEffect", "StrobeScan", "BlockStrobe", "NegativeStrobe", "BitwiseXorStrobe", "StrobeBlend", "FadeStrobe", "MirrorStrobe", "AndStrobe", "AndStrobeScale", "AndPixelStrobe", "AndOrXorStrobe", "AndOrXorStrobeScale", "BrightStrobe", "DarkStrobe", "StrobeTransform", "RandomStrobe", "StuckStrobe", "OrStrobe", "DifferenceStrobe","RandomStrobeFlash", "GaussianStrobe", "StrobeSort", "GlitchSortStrobe", "StrobeXor"}; + static int index = 0; + Shuffle(index, frame, filter_array); + AddInvert(frame); +} + +void ac::BlendBurred(cv::Mat &frame) { + static MatrixCollection<4> collection; + cv::Mat blur_copy = frame.clone(); + MedianBlur(blur_copy); + DarkenFilter(frame); + MedianBlur(blur_copy); + DarkenFilter(blur_copy); + MedianBlur(blur_copy); + collection.shiftFrames(blur_copy); + cv::Scalar value; + for(int q = 1; q < collection.size(); ++q) { + cv::Mat &frame_ref = collection.frames[q]; + for(int z = 0; z < frame_ref.rows; ++z) { + for(int i = 0; i < frame_ref.cols; ++i) { + cv::Vec3b color = frame_ref.at(z, i); + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + value[j] += color[j]; + value[j] /= 3; + pixel[j] = pixel[j]^static_cast(value[j]); + } + } + } + } + AddInvert(frame); +} + +void ac::BlendCombinedValues(cv::Mat &frame) { + static cv::Scalar values; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + values[j] += pixel[j]; + values[j] /= 3; + pixel[j] = pixel[j]^static_cast(values[j]); + } + } + } + AddInvert(frame); +} + +void ac::RGBColorTrails(cv::Mat &frame) { + RGBTrails(frame); + BlendCombinedValues(frame); + AddInvert(frame); +} + +void ac::BlendCombinedValueSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "BlendCombinedValueSubFilter") + return; + static cv::Scalar values; + cv::Mat copyf = frame.clone(); + CallFilter(subfilter, copyf); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b val = copyf.at(z, i); + for(int j = 0; j < 3; ++j) { + values[j] += val[j]; + values[j] /= 3; + pixel[j] = pixel[j]^static_cast(values[j]); + } + } + } + AddInvert(frame); +} + +void ac::BlendSubFilterAlpha(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "BlendSubFilterAlpha") + return; + + static double alpha = 1.0, alpha_max = 2.0; + + cv::Mat copyf = frame.clone(); + CallFilter(subfilter, copyf); + + for(int z = 0; z < frame.rows; ++z) { + cv::Scalar values; + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + values[j] += pixel[j]; + values[j] = values[j]/1.77; + pixel[j] = pixel[j] ^ (static_cast(values[j]*3.14)); + } + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 1.5, 0.001); + cv::Mat copy_frame = frame.clone(); + AlphaBlend(copy_frame, copyf, frame, alpha); + AddInvert(frame); +} + +void ac::GradientXorPixels(cv::Mat &frame) { + static cv::Scalar values(rand()%255, rand()%255, rand()%255); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + values[j] += pixel[j]+i; + values[j] /= 6.14; + pixel[j] = pixel[j]^static_cast(values[j]); + } + } + } + AddInvert(frame); +} + +void ac::PurpleRain(cv::Mat &frame) { + cv::Scalar values; + for(int i = 0; i < frame.cols; ++i) { + for(int z = 0; z < frame.rows; ++z) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + values[j] += pixel[j]; + values[j] /= (j+1); + pixel[j] = pixel[j] ^ static_cast(values[j]); + } + } + } + AddInvert(frame); +} + +void ac::PixelByPixelXor(cv::Mat &frame) { + cv::Vec3b pix; + static int counter = 2; + for(int i = 0; i < frame.cols; ++i) { + for(int z = 0; z < frame.rows; ++z) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pix[j] += pixel[j]; + pix[j] /= counter; + pixel[j] = pixel[j]^pix[j]; + } + } + } + ++counter; + if(counter > 8) + counter = 2; + + AddInvert(frame); +} + +void ac::CopyXorAlpha(cv::Mat &frame) { + static cv::Mat frame_copy; + if(frame_copy.empty() || frame_copy.size() != frame.size()) + frame_copy = frame.clone(); + + cv::Mat backup = frame.clone(); + static double alpha = 1.0, alpha_max = 4.0; + for(int z = 0; z < frame.rows-2; ++z) { + for(int i = 0; i < frame.cols-2; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix[4]; + pix[0] = frame_copy.at(z, i+1); + pix[1] = frame_copy.at(z+1, i); + pix[2] = frame_copy.at(z+1, i+1); + + cv::Vec3b color; + for(int j = 0; j < 3; ++j) { + color[j] += pix[0][j] + pix[1][j] + pix[2][j]; + color[j] /= 6.0; + pixel[j] = static_cast(color[j] * alpha) ^ static_cast(pixel[j]*(alpha+1)); + } + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 4.1, 0.1); + frame_copy = backup.clone(); + AddInvert(frame); +} + +void ac::AveragePixelsXor(cv::Mat &frame) { + cv::Scalar values; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b color = frame.at(z, i); + for(int j = 0; j < 3; ++j) + values[j] += color[j]; + } + } + cv::Vec3b pix; + for(int j = 0; j < 3; ++j) { + values[j] /= (frame.cols * frame.rows); + pix[j] = static_cast(values[j]); + } + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] = pixel[j]^pix[j]; + } + } + AddInvert(frame); +} + +void ac::AveragePixelAlpha(cv::Mat &frame) { + static double alpha = 1.0, alpha_max = 4.0; + cv::Scalar values; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b color = frame.at(z, i); + for(int j = 0; j < 3; ++j) + values[j] += color[j]; + } + } + cv::Vec3b pix; + for(int j = 0; j < 3; ++j) { + values[j] /= (frame.cols * frame.rows); + pix[j] = static_cast(values[j]); + } + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] = static_cast(pixel[j]*(alpha+1))^static_cast(pix[j]*alpha); + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max); + AddInvert(frame); +} + +void ac::NegativeByRow(cv::Mat &frame) { + bool neg = true; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + if(neg == false) break; + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] = ~pixel[j]; + + } + neg = (neg == true) ? false : true; + } + AddInvert(frame); +} + +void ac::AveragePixelCollection(cv::Mat &frame) { + static MatrixCollection<8> collection; + MedianBlur(frame); + MedianBlur(frame); + collection.shiftFrames(frame); + cv::Scalar values; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + for(int q = 0; q < collection.size(); ++q) { + cv::Vec3b pix = collection.frames[q].at(z, i); + for(int j = 0; j < 3; ++j) + values[j] += pix[j]; + } + } + } + cv::Vec3b fpix; + for(int j = 0; j < 3; ++j) { + values[j] = values[j] / ((frame.rows * frame.cols) * 3.14); + fpix[j] = static_cast(values[j]); + } + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = pixel[j]^fpix[j]; + } + } + } + AddInvert(frame); +} + +void ac::IncorrectLine(cv::Mat &frame) { + cv::Vec3b xval; + xval[0] = rand()%255; + xval[1] = rand()%255; + xval[2] = rand()%255; + for(int z = 0; z < frame.rows; ++z) { + cv::Scalar values; + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + values[j] += pixel[j]; + pixel[j] = pixel[j] ^ xval[j]; + } + } + for(int j = 0; j < 3; ++j) { + xval[j] = static_cast(values[j]/frame.cols/3.14); + } + } + AddInvert(frame); +} + +void ac::XorShift(cv::Mat &frame) { + int sw = 0; + static double alpha = 1.0, alpha_max = 4.0; + cv::Scalar values; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + values[sw] += pixel[sw]; + ++sw; + if(sw > 2) + sw = 0; + } + } + + cv::Vec3b pix; + for(int j = 0; j < 3; ++j) { + values[j] = values[j] / (frame.rows * frame.cols); + pix[j] = static_cast((values[j] * alpha)/3.14); + } + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = pixel[j] ^ pix[j]; + } + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max); + AddInvert(frame); +} + +void ac::StrobeXorAndOr(cv::Mat &frame) { + cv::Vec3b rnd(rand()%255, rand()%255, rand()%255); + static int index = 0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) + switch(index) { + case 0: + pixel[j] = pixel[j] ^ rnd[j]; + break; + case 1: + pixel[j] = pixel[j] & rnd[j]; + break; + case 2: + pixel[j] = pixel[j] | rnd[j]; + break; + } + } + } + ++index; + if(index > 2) + index = 0; + AddInvert(frame); +} + +void ac::XorWithSource(cv::Mat &frame) { + if(orig_frame.empty()) + return; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b orig = orig_frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = pixel[j]^orig[j]; + } + } + } +} + +void ac::AlphaBlendWithSource(cv::Mat &frame) { + if(orig_frame.empty()) + return; + + static double alpha = 1.0, alpha_max = 4.0; + cv::Mat copy_f = frame.clone(); + AlphaBlend(copy_f, orig_frame, frame, alpha); + static int dir = 1; + procPos(dir, alpha, alpha_max, 4.1, 0.05); +} + +void ac::RGBSep1x(cv::Mat &frame) { + cv::Mat copy_f = frame.clone(); + static int offset = 0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = offset, start_i = 0, x = offset/2; x < frame.cols && start_i < frame.cols && i < frame.cols; ++i, ++start_i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b copy_pix = copy_f.at(z, start_i); + cv::Vec3b copy_pix2 = copy_f.at(z, x); + pixel[2] += copy_pix[2]; + pixel[0] += copy_pix2[0]; + } + for(int i = 0; i < offset; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b off_x = copy_f.at(z, frame.cols-i-1); + pixel[1] += off_x[1]; + } + } + ++offset; + if(offset > frame.cols) + offset = 2; + AddInvert(frame); +} + +void ac::RGBMedianBlend(cv::Mat &frame) { + RGBSep1x(frame); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::RGBMirror1(cv::Mat &frame) { + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pixels[4]; + pixels[0] = frame.at(frame.rows-z-1, frame.cols-i-1); + pixels[1] = frame.at(frame.rows-z-1, i); + pixels[2] = frame.at(z, frame.cols-i-1); + pixels[3] = pixel; + pixel[0] += pixels[0][0]; + pixel[1] += pixels[1][1]; + pixel[2] += pixels[2][2]; + } + } + + AddInvert(frame); +} + +void ac::RGBMirror1Median(cv::Mat &frame) { + RGBMirror1(frame); + MedianBlend(frame); +} + +void ac::FlashMirror(cv::Mat &frame) { + static int index = 0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix[4]; + pix[0] = frame.at(z, frame.cols-i-1); + pix[1] = frame.at(frame.rows-z-1, i); + pix[2] = frame.at(frame.rows-z-1, frame.cols-i-1); + pix[3] = pixel; + + for(int j = 0; j < 3; ++j) { + pixel[j] = pixel[j] ^ pix[index][j]; + } + } + } + ++index; + if(index > 2) + index = 0; + MedianBlend(frame); + AddInvert(frame); +} + +void ac::CollectionXorSourceSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "CollectionXorSourceSubFilter") + return; + static MatrixCollection<6> collection; + static double alpha = 1.0, alpha_max = 4.0; + cv::Mat frame_copy = frame.clone(); + CallFilter(subfilter, frame_copy); + collection.shiftFrames(frame_copy); + Smooth(frame_copy, &collection, false); + AlphaXorBlend(frame_copy, orig_frame, frame, alpha); + static int dir = 1; + procPos(dir, alpha, alpha_max); + AddInvert(frame); +} + +void ac::ReverseMirrorX(cv::Mat &frame) { + cv::Mat copyf = frame.clone(); + Reverse(copyf); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = copyf.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = pixel[j] ^ pix[j]; + } + } + } + AddInvert(frame); +} + +void ac::MirrorXorAll_Reverse(cv::Mat &frame) { + cv::Mat frame_copy = frame.clone(); + Reverse(frame_copy); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b values[3]; + values[0] = frame_copy.at(frame.rows-z-1, frame.cols-i-1); + values[1] = frame_copy.at(frame.rows-z-1, i); + values[2] = frame_copy.at(z, frame.cols-i-1); + for(int j = 0; j < 3; ++j) { + pixel[j] ^= (pixel[j] ^ values[0][j] ^ values[1][j] ^ values[2][j]); + } + } + } + AddInvert(frame); +} + +void ac::MirrorRGBReverse(cv::Mat &frame) { + cv::Mat copyf[3]; + cv::flip(frame, copyf[0], 0); + cv::flip(frame, copyf[1], 1); + cv::flip(frame, copyf[2], -1); + static int index = 0; + + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix[3]; + pix[0] = copyf[0].at(z, i); + pix[1] = copyf[1].at(z, i); + pix[2] = copyf[2].at(z, i); + switch(index) { + case 0: + pixel[0] = pix[0][0]; + pixel[1] = pix[1][1]; + pixel[2] = pix[2][2]; + break; + case 1: + pixel[0] = pix[2][0]; + pixel[1] = pix[0][1]; + pixel[2] = pix[1][2]; + break; + case 2: + pixel[0] = pix[1][0]; + pixel[1] = pix[2][1]; + pixel[2] = pix[0][2]; + break; + } + } + } + ++index; + if(index > 2) + index = 0; + AddInvert(frame); +} + +void ac::MirrorRGBReverseBlend(cv::Mat &frame) { + cv::Mat copyf[3]; + cv::flip(frame, copyf[0], 0); + cv::flip(frame, copyf[1], 1); + cv::flip(frame, copyf[2], -1); + static int index = 0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix[3]; + pix[0] = copyf[0].at(z, i); + pix[1] = copyf[1].at(z, i); + pix[2] = copyf[2].at(z, i); + switch(index) { + case 0: + pixel[0] ^= pix[0][0]; + pixel[1] ^= pix[1][1]; + pixel[2] ^= pix[2][2]; + break; + case 1: + pixel[0] ^= pix[2][0]; + pixel[1] ^= pix[0][1]; + pixel[2] ^= pix[1][2]; + break; + case 2: + pixel[0] ^= pix[1][0]; + pixel[1] ^= pix[2][1]; + pixel[2] ^= pix[0][2]; + break; + } + } + } + ++index; + if(index > 2) + index = 0; + + AddInvert(frame); +} + diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter12.cpp b/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter12.cpp new file mode 100755 index 0000000..fb38920 --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter12.cpp @@ -0,0 +1,1114 @@ +/* + * Software written by Jared Bruni https://github.com/lostjared + + This software is dedicated to all the people that experience mental illness. + + Website: http://lostsidedead.com + YouTube: http://youtube.com/LostSideDead + Instagram: http://instagram.com/jaredbruni + Twitter: http://twitter.com/jaredbruni + Facebook: http://facebook.com/LostSideDead0x + + You can use this program free of charge and redistrubute it online as long + as you do not charge anything for this program. This program is meant to be + 100% free. + + BSD 2-Clause License + + Copyright (c) 2019, Jared Bruni + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + */ + +#include "ac.h" + +void ac::BlendReverseSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "BlendReverseSubFitler") + return; + cv::Mat copyf = frame.clone(); + Reverse(copyf); + CallFilter(subfilter, copyf); + static double alpha = 1.0, alpha_max = 7.0; + static int index = 0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = copyf.at(z, i); + switch(index) { + case 0: + pixel[0] = pixel[0]^pix[0]; + pixel[1] = pixel[1]^pix[1]; + pixel[2] = pixel[2]^pix[2]; + break; + case 1: + pixel[0] = pixel[2]^pix[0]; + pixel[1] = pixel[0]^pix[1]; + pixel[2] = pixel[1]^pix[2]; + break; + case 2: + pixel[0] = pixel[1]^pix[0]; + pixel[1] = pixel[2]^pix[1]; + pixel[2] = pixel[0]^pix[2]; + break; + case 3: + pixel[0] = pixel[0]^pix[2]; + pixel[1] = pixel[1]^pix[0]; + pixel[2] = pixel[2]^pix[1]; + break; + case 4: + pixel[0] = pixel[0]^pix[0]; + pixel[1] = pixel[1]^pix[2]; + pixel[2] = pixel[2]^pix[1]; + break; + case 5: + pixel[0] = pixel[0]^pix[1]; + pixel[1] = pixel[1]^pix[2]; + pixel[2] = pixel[2]^pix[0]; + break; + } + } + } + ++index; + if(index > 5) + index = 0; + static int dir = 1; + procPos(dir, alpha, alpha_max, 7.1, 0.005); + AddInvert(frame); +} + +void ac::MirrorBitwiseXor(cv::Mat &frame) { + static double alpha = 1.0, alpha_max = 4.0; + cv::Mat temp = frame.clone(); + FlipBlendAll(temp); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = temp.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = static_cast(pixel[j]*(alpha+1))^static_cast(pix[j]*alpha); + } + } + } + MirrorXorAll(frame); + static int dir = 1; + procPos(dir, alpha, alpha_max, 4.1, 0.001); + DarkenFilter(frame); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::SmoothBlendReverseSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "SmoothBlendReverseSubFilter") + return; + static MatrixCollection<8> collection; + static double alpha = 1.0, alpha_max = 4.1; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + CallFilter(subfilter, copy1); + BlendReverseSubFilter(copy2); + collection.shiftFrames(copy1); + collection.shiftFrames(copy2); + Smooth(frame, &collection,false); + static int dir = 1; + procPos(dir, alpha, alpha_max, 4.1, 0.01); + AddInvert(frame); +} + + +void ac::RandomIncrease(cv::Mat &frame) { + static cv::Vec3b values; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] += values[j]; + } + } + } + for(int j = 0; j < 3; ++j) { + values[j] = size_reset(values[j]+rand()%25); + } + AddInvert(frame); +} + +void ac::MedianBlend16(cv::Mat &frame) { + static MatrixCollection<16> collection; + int r = 3+rand()%7; + for(int i = 0; i < r; ++i) + MedianBlur(frame); + + collection.shiftFrames(frame); + static double alpha = 1.0, alpha_max = 3.0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Scalar value; + for(int j = 0; j < collection.size(); ++j) { + cv::Vec3b pixel = collection.frames[j].at(z, i); + for(int q = 0; q < 3; ++q) { + value[q] += pixel[q]; + } + } + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + int val = 1+static_cast(value[j]); + pixel[j] = static_cast(pixel[j] ^ val); + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } + static int direction = 1; + procPos(direction, alpha, alpha_max); +} + +void ac::MedianBlendBufferSubFilter(cv::Mat &frame) { + + if(subfilter == -1 || ac::draw_strings[subfilter] == "MedianBlendBufferSubFilter") + return; + + static MatrixCollection<12> collection; + + cv::Mat copy_f = frame.clone(); + CallFilter(subfilter, copy_f); + + for(int i = 0; i < 3; ++i) { + MedianBlur(frame); + MedianBlur(copy_f); + } + + collection.shiftFrames(frame); + static double alpha = 1.0, alpha_max = 3.0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Scalar value; + for(int j = 0; j < collection.size(); ++j) { + cv::Vec3b pixel = collection.frames[j].at(z, i); + for(int q = 0; q < 3; ++q) { + value[q] += pixel[q]; + } + } + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = copy_f.at(z, i); + for(int j = 0; j < 3; ++j) { + int val = 1+static_cast(value[j]); + pixel[j] = static_cast(pixel[j] ^ val ^ pix[j]); + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } + static int direction = 1; + procPos(direction, alpha, alpha_max); +} + +void ac::BGRBlend(cv::Mat &frame) { + for(int j = 0; j < 3; ++j) + MedianBlur(frame); + static MatrixCollection<12> collection; + collection.shiftFrames(frame); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Scalar values; + for(int q = 0; q < collection.size(); ++q) { + cv::Vec3b pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) + values[j] += pixel[q]; + } + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = pixel; + for(int j = 0; j < 3; ++j) { + int val = static_cast(values[j]); + pixel[j] = pix[3-j-1] ^ val; + } + } + } + AddInvert(frame); +} + +void ac::RGBBlend(cv::Mat &frame) { + cv::Mat noblur = frame.clone(); + for(int j = 0; j < 3; ++j) + MedianBlur(frame); + static MatrixCollection<12> collection; + collection.shiftFrames(frame); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Scalar values; + for(int q = 0; q < collection.size(); ++q) { + cv::Vec3b pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + values[j] += pixel[q]; + values[j] /= 1.5; + } + } + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = noblur.at(z, i); + for(int j = 0; j < 3; ++j) { + int val = static_cast(values[j]); + pixel[j] = pixel[j] ^ val; + } + } + } + AddInvert(frame); +} + +void ac::RGBBlendSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "RGBBlendSubFilter") + return; + for(int j = 0; j < 3; ++j) + MedianBlur(frame); + cv::Mat copy_f = frame.clone(); + CallFilter(subfilter, copy_f); + static MatrixCollection<4> collection; + collection.shiftFrames(frame); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Scalar values; + for(int q = 0; q < collection.size(); ++q) { + cv::Vec3b pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + values[j] += pixel[q]; + values[j] /= 1.5; + } + } + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = copy_f.at(z, i); + for(int j = 0; j < 3; ++j) { + int val = static_cast(values[j]); + pixel[j] = pixel[j] ^ val ^ pix[j]; + } + } + } + AddInvert(frame); +} + + +void ac::DivideAndIncH(cv::Mat &frame) { + unsigned int x = 0, y = 0; + unsigned int counter_x = 0, counter_y = 0; + unsigned int row_x = frame.cols/255; + unsigned int row_y = frame.rows/255; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + pixel[0] += x; + pixel[1] += y; + ++counter_x; + if(counter_x >= row_x) { + counter_x = 0; + ++x; + } + } + ++counter_y; + if(counter_y >= row_y) { + counter_y = 0; + ++y; + } + } + AddInvert(frame); +} + +void ac::DivideAndIncW(cv::Mat &frame) { + unsigned int x = 0, y = 0; + unsigned int counter_x = 0, counter_y = 0; + unsigned int row_x = frame.cols/255; + unsigned int row_y = frame.rows/255; + for(int i = 0; i < frame.cols; ++i) { + for(int z = 0; z < frame.rows; ++z) { + cv::Vec3b &pixel = frame.at(z, i); + pixel[0] += x; + pixel[1] += y; + ++counter_x; + if(counter_x >= row_x) { + counter_x = 0; + ++x; + } + } + ++counter_y; + if(counter_y >= row_y) { + counter_y = 0; + ++y; + } + } + AddInvert(frame); +} + +void ac::XorOppositeSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "XorOppositeSubFilter") + return; + + cv::Mat copyf = frame.clone(); + CallFilter(subfilter, copyf); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b rpix = copyf.at(frame.rows-z-1, i); + cv::Vec3b rpix1 = copyf.at(z, frame.cols-i-1); + cv::Vec3b rpix2 = copyf.at(frame.rows-z-1, frame.cols-i-1); + + for(int j = 0; j < 3; ++j) { + pixel[j] = (pixel[j]^rpix[j])^(rpix1[j]^rpix2[j]); + } + } + } + AddInvert(frame); +} + +void ac::BlendSmoothSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "BlendSmoothSubFilter") + return; + static MatrixCollection<12> collection; + cv::Mat copyf = frame.clone(); + CallFilter(subfilter, copyf); + collection.shiftFrames(copyf); + Smooth(frame, &collection); + AddInvert(frame); +} + +void ac::BlurSmooth(cv::Mat &frame) { + static MatrixCollection<16> collection; + collection.shiftFrames(frame); + Smooth(frame, &collection); + for(int i = 0; i < 5; ++i) + MedianBlur(frame); + + AddInvert(frame); +} + +void ac::BlurSmoothMedian(cv::Mat &frame) { + BlurSmooth(frame); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::BlurSmoothSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "BlurSmoothSubFilter") + return; + + static MatrixCollection<16> collection; + CallFilter(subfilter, frame); + for(int i = 0; i < 5; ++i) + MedianBlur(frame); + + collection.shiftFrames(frame); + Smooth(frame, &collection); + AddInvert(frame); +} + +void ac::BlurFlip(cv::Mat &frame) { + for(int j = 0; j < 3; ++j) + MedianBlur(frame); + FlipBlendAll(frame); + int amt = rand()%3; + for(int j = 0; j < amt+3; ++j) + MedianBlur(frame); + MedianBlend(frame); + XorAlpha(frame); + cv::Mat copy = frame.clone(); + setGamma(copy, frame, 5); + AddInvert(frame); +} + +void ac::BlurFlipSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "BlurFlipSubFilter") + return; + cv::Mat copyf = frame.clone(); + cv::Mat copyi = frame.clone(); + CallFilter(subfilter, copyf); + for(int j = 0; j < 3; ++j) + MedianBlur(copyi); + FlipBlendAll(copyi); + int amt = rand()%3; + for(int j = 0; j < amt+3; ++j) + MedianBlur(copyi); + MedianBlend(copyi); + XorAlpha(copyi); + cv::Mat cpi = copyi.clone(); + setGamma(cpi, copyi, 5); + static double alpha = 1.0, alpha_max = 7.0; + AlphaBlend(copyf, copyi, frame, alpha); + static int dir = 1; + procPos(dir, alpha, alpha_max); + AddInvert(frame); +} + +void ac::BlurMirrorGamma(cv::Mat &frame) { + MirrorXorAll(frame); + cv::Mat copyf = frame.clone(); + cv::Mat copyi = frame.clone(); + cv::Mat copyo = frame.clone(); + setGamma(copyf, copyo, 2); + setGamma(copyi, copyf, 5); + int r = rand()%3; + for(int i = 0; i < 3+r; ++i) { + MedianBlur(copyo); + MedianBlur(copyf); + } + FlipBlendWH(copyf); + static double alpha = 1.0, alpha_max = 4.0; + AlphaBlend(copyo,copyf,frame,alpha); + MedianBlend(frame); + cv::Mat copyt = frame.clone(); + setGamma(copyt, frame, 2); + static int dir = 1; + procPos(dir, alpha, alpha_max, 4.1, 0.1); + AddInvert(frame); +} + +void ac::MedianBlendDark(cv::Mat &frame) { + static MatrixCollection<8> collection; + int r = 3+rand()%7; + for(int i = 0; i < r; ++i) + MedianBlur(frame); + + collection.shiftFrames(frame); + static double alpha = 1.0, alpha_max = 3.0; + for(int i = 0; i < frame.cols; ++i) { + for(int z = 0; z < frame.rows; ++z) { + cv::Scalar value; + for(int j = 0; j < collection.size(); ++j) { + cv::Vec3b pixel = collection.frames[j].at(z, i); + for(int q = 0; q < 3; ++q) { + value[q] -= pixel[q]; + } + } + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + int val = 1+static_cast(value[j]); + pixel[j] = static_cast(pixel[j] ^ val); + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } + cv::Mat copyf = frame.clone(); + setGamma(copyf, frame, 4); + static int direction = 1; + procPos(direction, alpha, alpha_max); + AddInvert(frame); +} + +void ac::MedianBlendSubFilterEx(cv::Mat &frame) { + + if(subfilter == -1 || ac::draw_strings[subfilter] == "MedianBlendSubFilterEx") + return; + + CallFilter(subfilter, frame); + cv::Mat copysub = frame.clone(); + static MatrixCollection<12> collection; + int r = 3;; + for(int i = 0; i < r; ++i) + MedianBlur(frame); + + collection.shiftFrames(frame); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Scalar value; + for(int j = 0; j < collection.size(); ++j) { + cv::Vec3b pixel = collection.frames[j].at(z, i); + for(int q = 0; q < 3; ++q) { + value[q] += pixel[q]; + } + } + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + int val = 1+static_cast(value[j]); + pixel[j] = static_cast(pixel[j] ^ val); + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } + cv::Mat output = frame.clone(); + AlphaBlend(copysub, output, frame, 0.5); + AddInvert(frame); +} + +void ac::EnergyMirrorDark(cv::Mat &frame) { + MirrorXorAll(frame); + BlendWithSource(frame); + MedianBlendDark(frame); + AddInvert(frame); +} + +void ac::AlphaBlendMirror(cv::Mat &frame) { + cv::Mat copyf = frame.clone(); + cv::Mat ucopy; + cv::flip(frame, ucopy, -1); + static double alpha = 1.0, alpha_max = 2.0; + AlphaBlend(copyf, ucopy, frame, alpha); + cv::flip(frame, ucopy, 1); + cv::Mat ecopy = frame.clone(); + AlphaXorBlend(ecopy, ucopy, frame, alpha); + static int dir = 1; + procPos(dir, alpha, alpha_max, 2.1, 0.01); + AddInvert(frame); +} + + +void ac::AlphaBlendXorImage(cv::Mat &frame) { + if(blend_set == true) { + static double alpha = 1.0, alpha_max = 3.0; + + cv::Mat copyf,outval; + cv::resize(blend_image, copyf, frame.size()); + AlphaBlend(frame, copyf, outval, alpha); + MedianBlur(outval); + MedianBlur(outval); + MedianBlur(outval); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = copyf.at(z, i); + cv::Vec3b pixval = outval.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = (pixel[j]^pix[j]^pixval[j]); + } + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 3.1, 0.05); + } + AddInvert(frame); +} + +void ac::ShiftFrameSmoothSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "ShiftFrameSmoothSubFilter") + return; + static MatrixCollection<16> collection; + CallFilter(subfilter, frame); + collection.shiftFrames(frame); + Smooth(frame, &collection, false); + AddInvert(frame); +} + + +void ac::ShiftFrameStaticXorSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "ShiftFrameStaticXorSubFilter") + return; + static MatrixCollection<16> collection; + CallFilter(subfilter, frame); + cv::Scalar scalar; + ScalarAverage(frame, scalar); + cv::Vec3b val; + static double alpha = 1.0, alpha_max = 3.0; + for(int j = 0; j < 3; ++j) + val[j] = static_cast(scalar[j] * alpha); + StaticXor(frame, &collection, val); + static int dir = 1; + procPos(dir, alpha, alpha_max, 3.1, 0.01); + AddInvert(frame); +} + +void ac::IncreaseDecreaseGamma(cv::Mat &frame) { + static int dir = 1; + static int light = 1; + static int min = 1, max = 10; + cv::Mat copyf = frame.clone(); + setGamma(copyf, frame, light); + if(dir == 1) { + ++light; + if(light > max) + dir = 0; + } else { + --light; + if(light <= min) + dir = 1; + + } + AddInvert(frame); +} + +void ac::GammaIncDecIncrease(cv::Mat &frame) { + static int dir = 1; + static int light = 1; + static int min = 1, max = 3, total_max = 12; + cv::Mat copyf = frame.clone(); + setGamma(copyf, frame, light); + if(dir == 1) { + ++light; + if(light > max) { + ++max; + if(max > total_max) { + max = 1; + } + dir = 0; + } + } else if(dir == 0) { + --light; + if(light <= min) { + dir = 1; + } + } + AddInvert(frame); +} + +void ac::RandomSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "RandomSubFilter") + return; + static int index = 0; + static std::vector vSub { "Bitwise_XOR_AlphaSubFilter", "AlphaBlendSubFilter", "GradientSubFilterXor", "XorBlend_SubFilter","EnergizeSubFilter","PixelatedSubFilterSort","FilteredDifferenceSubFilter","ExpandSquareSubFilter","MirrorEnergizeSubFilter", "InterRGB_SubFilter", "InterSmoothSubFilter", "StoredFramesAlphaBlend_SubFilter", "BlendSubFilter", "BlendAlphaSubFilter", "Blend_AlphaSubFilter", "FrameMedianBlendSubFilter", "FrameBlurSubFilter","SubFilterMedianBlend", "DarkCollectionSubFilter", "FlipMedianSubFilter", "FlipMirrorSubFilter", "BlendCombinedValueSubFilter","CollectionXorSourceSubFilter","BlendReverseSubFilter","SmoothBlendReverseSubFilter","MedianBlendBufferSubFilter","RGBBlendSubFilter","XorOppositeSubFilter", "BlendSmoothSubFilter", "BlurSmoothSubFilter", "BlurFlipSubFilter", "MedianBlendSubFilterEx", "ShiftFrameSmoothSubFilter", "ShiftFrameStaticXorSubFilter"}; + + static auto rng = std::default_random_engine{}; + CallFilter(vSub[index], frame); + ++index; + if(index > vSub.size()-1) { + index = 0; + std::shuffle(vSub.begin(), vSub.end(),rng); + } + AddInvert(frame); +} + +void ac::TwistedVision(cv::Mat &frame) { + static int pos[3] = {2,frame.cols-1,2}; + static int sized_w = frame.size().width; + if(sized_w != frame.size().width) { + pos[1] = frame.cols-1; + sized_w = frame.size().width; + } + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + int cx = i+pos[0]; + if(cx >= 0 && cx < frame.cols) { + cv::Vec3b pix = frame.at(z, cx); + for(int j = 0; j < 3; ++j) { + pixel[j] = pix[j]^pixel[j]; + } + } else { + for(int j = 0; j < 3; ++j) + pixel[j] = pixel[j]^pos[0]; + } + int cx_x = i+pos[1]; + if(cx_x >= 0 && cx_x < frame.cols) { + cv::Vec3b pix=frame.at(z, cx_x); + for(int j = 0; j < 3; ++j) { + pixel[j] = pixel[j]^pix[j]; + } + } else { + for(int j = 0; j < 3; ++j) + pixel[j] = pixel[j]^pos[1]; + } + } + } + ++pos[0]; + if(pos[0] > frame.cols/2) { + pos[0] = 2; + } + --pos[1]; + if(pos[1] <= frame.cols/2) + pos[1] = frame.cols-1; + + AddInvert(frame); +} + +void ac::TwistedMirror(cv::Mat &frame) { + cv::Mat copyf = frame.clone(), copyi = frame.clone(); + FlipBlendAll(copyf); + TwistedVision(copyi); + MirrorXorAll(copyi); + AlphaBlend(copyf,copyi,frame, 0.7); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::SelfScaleSortBlend(cv::Mat &frame) { + cv::Mat copyf = frame.clone(), copyi = frame.clone(); + StrobeSort(copyf); + SelfScale(copyi); + AlphaBlend(copyi, copyf, frame, 0.5); + AddInvert(frame); +} + +void ac::FlashMedianBlend(cv::Mat &frame) { + cv::Mat copyf = frame.clone(), copyi = frame.clone(); + cv::Vec3b color(rand()%255,rand()%255,rand()%255); + for(int z = 0; z < copyf.rows; ++z) { + for(int i = 0; i < copyf.cols; ++i) { + cv::Vec3b &pixel = copyf.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = pixel[j]^color[j]; + } + } + } + MedianBlend(copyf); + AlphaBlend(copyf, copyi, frame, 0.5); + AddInvert(frame); +} + +void ac::BlendWithFrameSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "BlendWithFrameSubFilter") + return; + cv::Mat copyf = frame.clone(), copyi = frame.clone(); + CallFilter(subfilter, copyf); + AlphaBlend(copyf, copyi, frame, 0.5); + AddInvert(frame); +} + +void ac::AlphaBlendWithFrameSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "AlphaBlendWithFrameSubFilter") + return; + + static double alpha = 1.0, alpha_max = 4.0; + cv::Mat copyf = frame.clone(), copyi = frame.clone(); + CallFilter(subfilter, copyf); + AlphaBlend(copyf, copyi, frame, alpha); + static int dir = 1; + procPos(dir, alpha, alpha_max, 4.1, 0.01); + AddInvert(frame); +} + +void ac::AlphaXorBlendWithFrameSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "AlphaXorBlendWithFrameSubFilter") + return; + + static double alpha = 1.0, alpha_max = 4.0; + cv::Mat copyf = frame.clone(), copyi = frame.clone(); + CallFilter(subfilter, copyf); + AlphaXorBlend(copyf, copyi, frame, alpha); + static int dir = 1; + procPos(dir, alpha, alpha_max, 4.1, 0.01); + AddInvert(frame); +} + +void ac::XorBlendSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "XorBlendSubFilter") + return; + + cv::Mat copyf = frame.clone(); + CallFilter(subfilter, copyf); + Xor(frame, copyf); + AddInvert(frame); +} + +void ac::FlipAlphaBlend(cv::Mat &frame) { + static int flip_ = -1; + static bool strobe = true; + cv::Mat copyi = frame.clone(), copyout; + if(strobe == true) { + cv::flip(copyi, copyout, flip_); + strobe = false; + AlphaBlend(copyi, copyout, frame, 0.5); + if(++flip_ > 1) + flip_ = -1; + + } else + strobe = true; + + AddInvert(frame); +} + +void ac::RandomFlipFilter(cv::Mat &frame) { + int value = -1; + int rnd = rand()%3; + value += rnd; + cv::Mat copyf = frame.clone(); + flip(copyf, frame, value); + AddInvert(frame); +} + +void ac::MirrorMedian(cv::Mat &frame) { + static bool on_off = true; + if(on_off == true) { + cv::Mat copyf = frame.clone(); + cv::flip(copyf,frame,0); + on_off = false; + } else + on_off = true; + + cv::Mat copyf = frame.clone(); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix[5]; + pix[0] = pixel; + pix[1] = copyf.at(frame.rows-z-1, i); + pix[2] = copyf.at(z, frame.cols-i-1); + pix[3] = copyf.at(frame.rows-z-1, frame.cols-i-1); + for(int j = 0; j < 3; ++j) + pixel[j] = pix[0][j] ^ pix[1][j] ^ pix[2][j] ^ pix[3][j]; + } + } + MedianBlend(frame); + AddInvert(frame); +} + +void ac::FlipMatrixCollection(cv::Mat &frame) { + static MatrixCollection<8> collection; + cv::Mat copyf[3], copyi = frame.clone(); + cv::flip(frame, copyf[0], -1); + cv::flip(frame, copyf[1],0); + cv::flip(frame, copyf[2], 1); + collection.shiftFrames(copyf[0]); + collection.shiftFrames(copyf[1]); + Smooth(copyf[2], &collection); + AlphaBlend(copyf[2], copyi, frame, 0.5); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::MirrorMatrixCollection(cv::Mat &frame) { + static MatrixCollection<12> collection; + cv::Mat copyf = frame.clone(); + Smooth(frame, &collection); + cv::Mat frame_copy = frame.clone(); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix[5]; + pix[0] = pixel; + pix[1] = copyf.at(frame.rows-z-1, i); + pix[2] = copyf.at(z, frame.cols-i-1); + pix[3] = copyf.at(frame.rows-z-1, frame.cols-i-1); + cv::Vec3b pixel2 = frame_copy.at(z, i); + cv::Vec3b pix2[5]; + pix2[0] = pixel2; + pix2[1] = frame_copy.at(frame.rows-z-1, i); + pix2[2] = frame_copy.at(z, frame.cols-i-1); + pix2[3] = frame_copy.at(frame.rows-z-1, frame.cols-i-1); + for(int j = 0; j < 3; ++j) { + pixel[j] = ((pix[0][j] & pix2[0][j]) ^ (pix[1][j] & pix2[1][j]) ^ (pix[2][j] & pix2[2][j])); + } + } + } + AddInvert(frame); +} + +void ac::MirrorMatrixSource(cv::Mat &frame) { + BlurFlip(frame); + BlendWithSource(frame); + MirrorMatrixCollection(frame); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::SelfScaleByFrame(cv::Mat &frame) { + cv::Mat copyf = frame.clone(); + static MatrixCollection<8> collection; + SelfAlphaScale(copyf); + collection.shiftFrames(copyf); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = collection.frames[3].at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = pixel[j] ^ pix[j]; + } + } + } + AddInvert(frame); +} + +void ac::SmoothMedianRotateSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "SmoothMedianRotateSubFilter") + return; + static MatrixCollection<16> collection; + cv::Mat copyf = frame.clone(), outf; + CallFilter(subfilter, copyf); + int off = -1; + int random_ = rand()%3; + off += random_; + cv::flip(copyf, outf, off); + collection.shiftFrames(outf); + Smooth(frame, &collection, false); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::SmoothCollectionAlphaBlend(cv::Mat &frame) { + static MatrixCollection<8> collection; + cv::Mat copyf = frame.clone(); + rainbowBlend(copyf); + Smooth(copyf, &collection); + BlendWithSource(copyf); + MedianBlur(frame); + MedianBlur(frame); + Xor(frame, copyf); + AddInvert(frame); +} + +void ac::XorSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "XorSubFilter") + return; + cv::Mat copyf = frame.clone(); + CallFilter(subfilter, copyf); + Xor(frame, copyf); + AddInvert(frame); +} +void ac::XorAlphaSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "XorAlphaSubFilter") + return; + cv::Mat copyf = frame.clone(); + CallFilter(subfilter, copyf); + static double alpha = 1.0, alpha_max = 4.0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = copyf.at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] = static_cast(pixel[j]*(alpha+1)) ^ static_cast(pix[j]*alpha); + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 4.1, 0.05); + AddInvert(frame); +} + + +void ac::BlurXorAlphaSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "BlurXorAlphaSubFilter") + return; + + cv::Mat copyf = frame.clone(); + cv::Mat copyi = frame.clone(); + MedianBlur(copyf); + MedianBlur(copyf); + CallFilter(subfilter, copyf); + MedianBlur(copyf); + MedianBlur(copyf); + Xor(copyi,copyf); + cv::Mat copye = frame.clone(); + AlphaBlend(copyi, copye, frame, 0.5); + AddInvert(frame); +} + +void ac::ImageXorFrame(cv::Mat &frame) { + if(blend_set == true) { + cv::Mat copye = frame.clone(); + cv::Mat copyf = frame.clone(), copyi; + cv::resize(blend_image, copyi, frame.size()); + Xor(copyf, copyi); + AlphaBlend(copyf, copye, frame, 0.8); + AddInvert(frame); + } +} + +void ac::ImageXorFunction(cv::Mat &frame) { + if(blend_set == true) { + cv::Mat image_resized; + cv::resize(blend_image, image_resized, frame.size()); + Xor(frame, image_resized); + AddInvert(frame); + } +} + +void ac::ImageXorAlphaBlend(cv::Mat &frame) { + if(blend_set == true) { + cv::Mat copyf = frame.clone(); + cv::Mat image_resized; + cv::resize(blend_image, image_resized, frame.size()); + Xor(copyf, image_resized); + static double alpha = 1.0, alpha_max = 4.0; + cv::Mat copyi = frame.clone(); + AlphaBlend(copyf, copyi, frame, alpha); + static int dir = 1; + procPos(dir, alpha, alpha_max, 4.1, 0.05); + AddInvert(frame); + } +} + +void ac::ImageAlphaXorMedianSubFilter(cv::Mat &frame) { + if(blend_set == true && subfilter != -1 && ac::draw_strings[subfilter] != "ImageAlphaXorMedianSubFilter") { + static double alpha = 1.0, alpha_max = 4.0; + cv::Mat copyf = frame.clone(), copyi = frame.clone(); + cv::Mat resized; + cv::resize(blend_image, resized, frame.size()); + CallFilter(subfilter, frame); + AlphaBlend(copyf, resized, frame, alpha); + Xor(frame, copyi); + MedianBlend(frame); + static int dir = 1; + procPos(dir, alpha, alpha_max, 4.1, 0.05); + AddInvert(frame); + } +} + +void ac::ImageSmoothAlphaXorSubFilter(cv::Mat &frame) { + if(blend_set == true && subfilter != -1 && ac::draw_strings[subfilter] != "ImageSmoothAlphaXorSubFilter") { + cv::Mat copyf = frame.clone(), copyi; + cv::Mat copye = frame.clone(); + static MatrixCollection<8> collection; + CallFilter(subfilter, copyf); + Smooth(copyf, &collection); + cv::resize(blend_image, copyi, frame.size()); + AlphaBlend(copyf,copyi,frame,0.5); + Xor(frame, copye); + AddInvert(frame); + } +} + +void ac::ImageXorMirrorFilter(cv::Mat &frame) { + if(blend_set == true) { + cv::Mat copyf = frame.clone(); + cv::Mat imgf; + cv::resize(blend_image, imgf, frame.size()); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b frame_values[5], image_values[5]; + cv::Vec3b &pixel = frame.at(z, i); + frame_values[0] = pixel; + frame_values[1] = copyf.at(copyf.rows-z-1, copyf.cols-i-1); + frame_values[2] = copyf.at(z, copyf.cols-i-1); + frame_values[3] = copyf.at(copyf.rows-z-1, i); + image_values[0] = imgf.at(z, i); + image_values[1] = imgf.at(imgf.rows-z-1, imgf.cols-i-1); + image_values[2] = imgf.at(z, imgf.cols-i-1); + image_values[3] = imgf.at(imgf.rows-z-1, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = frame_values[0][j]^image_values[0][j] ^ frame_values[1][j]^image_values[1][j] ^ frame_values[2][j]^image_values[2][j] ^ frame_values[3][j]^image_values[3][j]^pixel[j]; + } + } + } + AddInvert(frame); + } +} + +void ac::ImageXorSubFilter(cv::Mat &frame) { + if(blend_set == true && subfilter != -1 && ac::draw_strings[subfilter] != "ImageXorSubFilter") { + cv::Mat copyf = frame.clone(); + CallFilter(subfilter, copyf); + cv::Mat resized_blend; + cv::resize(blend_image, resized_blend, frame.size()); + static double scale = 0.5; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix1 = copyf.at(z, i); + cv::Vec3b pix2 = resized_blend.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = static_cast(pixel[j]*scale) ^ static_cast(pix1[j]*scale) ^ static_cast(pix2[j]*scale); + } + } + } + static int dir = 1; + if(dir == 1) { + scale += 0.01; + if(scale >= 1.0) + dir = 0; + } else { + scale -= 0.01; + if(scale <= 0.5) + dir = 1; + } + } +} diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter13.cpp b/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter13.cpp new file mode 100755 index 0000000..35571e6 --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter13.cpp @@ -0,0 +1,1094 @@ +/* + * Software written by Jared Bruni https://github.com/lostjared + + This software is dedicated to all the people that experience mental illness. + + Website: http://lostsidedead.com + YouTube: http://youtube.com/LostSideDead + Instagram: http://instagram.com/jaredbruni + Twitter: http://twitter.com/jaredbruni + Facebook: http://facebook.com/LostSideDead0x + + You can use this program free of charge and redistrubute it online as long + as you do not charge anything for this program. This program is meant to be + 100% free. + + BSD 2-Clause License + + Copyright (c) 2019, Jared Bruni + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + */ + +#include "ac.h" + + +void ac::ImageAlphaXorSubFilter(cv::Mat &frame) { + if(blend_set == true && subfilter != -1 && ac::draw_strings[subfilter] != "ImageAlphaXorSubFilter") { + cv::Mat copyf = frame.clone(), copyi = frame.clone();; + cv::Mat resized; + cv::resize(blend_image, resized, frame.size()); + cv::Mat out; + CallFilter(subfilter, copyi); + AlphaBlend(resized, copyi, out, 0.5); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = out.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = pixel[j]^pix[j]; + } + } + } + } + AddInvert(frame); +} + +void ac::SmoothTrailsBlend(cv::Mat &frame) { + static MatrixCollection<16> collection; + cv::Mat copyf = frame.clone(); + cv::Mat copyi = frame.clone(); + Smooth(copyf, &collection); + AlphaBlend(copyf, copyi, frame, 0.5); + AddInvert(frame); +} + +void ac::MatrixCollectionRGBXor(cv::Mat &frame) { + static MatrixCollection<12> collection; + cv::Mat copyf = frame.clone(); + MovementRGBTrails(copyf); + collection.shiftFrames(copyf); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Scalar sc; + for(int q = 0; q < collection.size(); ++q) { + cv::Vec3b pix = collection.frames[q].at(z, i); + for(int j = 0; j < 3; ++j) + sc[j] += pix[j]; + } + for(int j = 0; j < 3; ++j) { + int val = static_cast(sc[j]); + pixel[j] = pixel[j]^val; + } + } + } + BlendWithSource(frame); + AddInvert(frame); +} + +void ac::RainbowGlitch(cv::Mat &frame) { + SmoothTrailsBlend(frame); + MovementRGBTrails(frame); + AddInvert(frame); +} + +void ac::RainbowGlichStrobe(cv::Mat &frame) { + SmoothTrailsBlend(frame); + MovementRGBTrails(frame); + static bool negate = true; + if(negate == true) { + Negate(frame); + negate = false; + } else { + negate = true; + } + AddInvert(frame); +} + +void ac::NegateSwitchStrobe(cv::Mat &frame) { + static bool strobe_value = true; + if(strobe_value == true) { + Negate(frame); + strobe_value = false; + } else + strobe_value = true; + + AddInvert(frame); +} + +void ac::StrobeAlphaShuffle(cv::Mat &frame) { + cv::Mat copyf = frame.clone(), copyi = frame.clone(); + ShuffleAlpha(copyf); + static bool neg_ = true; + if(neg_ == true) { + Negate(copyf); + neg_ = false; + } else { + neg_ = true; + } + AlphaBlend(copyf, copyi, frame, 0.5); + AddInvert(frame); +} + +void ac::ShuffleAlphaWithRGB(cv::Mat &frame) { + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + ShuffleAlpha(copy1); + ShuffleRGB(copy2); + AlphaBlend(copy1, copy2, frame, 0.5); + AddInvert(frame); +} + +void ac::ShuffleAlphaSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "ShuffleAlphaSubFilter") + return; + cv::Mat copyf = frame.clone(), copyi = frame.clone(); + ShuffleAlpha(copyf); + CallFilter(subfilter, copyi); + AlphaBlend(copyf, copyi, frame, 0.5); + AddInvert(frame); +} + +void ac::ShuffleColorMap(cv::Mat &frame) { + static int index = 0; + static std::vector v{0,1,2,3,4,5,6,7,8,9,10,11}; + static auto rng = std::default_random_engine{}; + ac::setColorMap(v[index], frame); + ++index; + if(index > v.size()-1) { + index = 0; + std::shuffle(v.begin(), v.end(),rng); + } + AddInvert(frame); +} + +void ac::BlendWithRainbowSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "BlendWithRainbowSubFilter") + return; + blendFilterWithColorMap(subfilter, 4, frame); + AddInvert(frame); +} + +void ac::BlendWithJetSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "BlendWithJetSubFilter") + return; + blendFilterWithColorMap(subfilter, 2, frame); + AddInvert(frame); +} + +void ac::ColormapBlendSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "ColormapBlendSubFilter") + return; + cv::Mat copyf = frame.clone(), copyi = frame.clone(); + setColorMap(rand()%11, copyf); + setColorMap(rand()%11, copyi); + RGBColorTrails(copyi); + CallFilter(subfilter, copyf); + AlphaBlend(copyf, copyi, frame, 0.5); + AddInvert(frame); +} + +void ac::RandomColorMap(cv::Mat &frame) { + setColorMap(rand()%11, frame); + AddInvert(frame); +} + +void ac::SmoothMirrorBlurFlip(cv::Mat &frame) { + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + SmoothTrailsBlend(copy1); + MirrorBitwiseXor(copy1); + SmoothTrailsBlend(copy2); + BlurFlip(copy2); + AlphaBlend(copy1, copy2, frame, 0.5); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::RandomColorMapAlphaBlendSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "RandomColorMapAlphaBlendSubFilter") + return; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + RandomColorMap(copy1); + CallFilter(subfilter, copy1); + static double alpha = 1.0, alpha_max = 4.0; + AlphaBlend(copy1, copy2, frame, alpha); + static int dir = 1; + procPos(dir, alpha, alpha_max, 4.1, 0.005); + AddInvert(frame); +} + +void ac::RandomOrder(cv::Mat &frame) { + int color_order = 0; + static std::vector colors { 1,2,3,4 }; + static auto rng = std::default_random_engine{}; + static int index = static_cast(colors.size()+1); + if(index > colors.size()) { + std::shuffle(colors.begin(), colors.end(),rng); + index = 0; + } + color_order = colors[index++]; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &cur = frame.at(z, i); + SwitchOrder(cur, color_order); + } + } + AddInvert(frame); +} + +void ac::RandomOrderMedianBlendSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "RandomOrderMedianBlendSubFilter") + return; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + CallFilter(subfilter, copy1); + AlphaBlend(copy1, copy2, frame, 0.5); + MedianBlend(frame); + RandomOrder(frame); + AddInvert(frame); +} + + +void ac::MirrorOrder(cv::Mat &frame) { + cv::Mat copy1 = frame.clone(); + static int index = 0; + for(int z = 0; z < frame.rows-1; ++z) { + for(int i = 0; i < frame.cols-1; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix[6]; + pix[0] = copy1.at(z, i); + pix[1] = copy1.at(copy1.rows-z-1, i); + pix[2] = copy1.at(copy1.rows-z-1, copy1.cols-i-1); + pix[3] = copy1.at(z, copy1.cols-i-1); + pix[4] = copy1.at(z+1, i+1); + for(int j = 0; j < 3; ++j) + SwitchOrder(pix[j], index); + + for(int j = 0; j < 3; ++j) { + pixel[j] = pix[0][j] ^ pix[1][j] ^ pix[2][j] ^ pix[3][j] ^ pix[4][j] ^ pixel[j]; + } + } + } + ++index; + if(index > 4) + index = 1; + + AddInvert(frame); +} + +void ac::MirrorOrderSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "MirrorOrderSubFilter") + return; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + CallFilter(subfilter, copy1); + MirrorOrder(copy2); + AlphaBlend(copy1, copy2, frame, 0.5); + SmoothTrailsBlend(frame); + DarkenImage(frame, 4); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::BlurMirrorOrder(cv::Mat &frame) { + cv::Mat copy1 = frame.clone(); + MedianBlur(copy1); + MedianBlur(copy1); + MedianBlur(copy1); + static double alpha = 1.0, alpha_max = 4.0; + static int index = 0; + for(int z = 0; z < frame.rows-1; ++z) { + for(int i = 0; i < frame.cols-1; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix[6]; + pix[0] = copy1.at(z, i); + pix[1] = copy1.at(copy1.rows-z-1, i); + pix[2] = copy1.at(copy1.rows-z-1, copy1.cols-i-1); + pix[3] = copy1.at(z, copy1.cols-i-1); + pix[4] = copy1.at(z+1, i+1); + for(int j = 0; j < 3; ++j) + SwitchOrder(pix[j], index); + for(int j = 0; j < 3; ++j) { + pixel[j] = static_cast(((pix[0][j] ^ pix[1][j] ^ pix[2][j] ^ pix[3][j] ^ pix[4][j] ^ pixel[j])/8) * alpha); + } + } + } + ++index; + if(index > 4) + index = 1; + + static int dir = 1; + procPos(dir, alpha, alpha_max, 4.1, 0.05); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::AveragePixelMirror(cv::Mat &frame) { + cv::Mat copy1 = frame.clone(); + MedianBlur(copy1); + MedianBlur(copy1); + static int index = 0; + for(int z = 0; z < frame.rows-1; ++z) { + for(int i = 0; i < frame.cols-1; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix[6]; + pix[0] = copy1.at(z, i); + pix[1] = copy1.at(copy1.rows-z-1, i); + pix[2] = copy1.at(copy1.rows-z-1, copy1.cols-i-1); + pix[3] = copy1.at(z, copy1.cols-i-1); + cv::Scalar s; + for(int i = 0; i < 5; ++i) { + for(int j = 0; j < 3; ++j) { + s[j] += pix[i][j]; + } + } + for(int j = 0; j < 3; ++j) { + s[j] /= 4; + unsigned int value1 = static_cast(s[j]); + unsigned int value2 = pixel[j]%(1+value1); + pixel[j] = pixel[j]^value2; + } + } + } + ++index; + if(index > 4) + index = 1; + AddInvert(frame); +} + +void ac::ShuffleAlphaMedianBlend(cv::Mat &frame) { + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + ShuffleAlpha(copy1); + ShuffleAlpha(copy2); + AlphaBlend(copy1, copy2, frame, 0.5); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::MirrorOrderAlpha(cv::Mat &frame) { + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + MirrorOrder(copy1); + MirrorXorAll(copy2); + AlphaBlend(copy1, copy2, frame, 0.5); + MedianBlend(frame); +} + +void ac::FilterStrobeSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "FilterStrobeSubFilter") + return; + static bool flash = true; + if(flash == true) { + CallFilter(subfilter, frame); + Negate(frame); + flash = false; + } else { + flash = true; + CallFilter(subfilter, frame); + } + AddInvert(frame); +} + +void ac::ImageSubtractMedianBlend(cv::Mat &frame) { + if(blend_set == true) { + cv::Mat image1; + cv::resize(blend_image, image1, frame.size()); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = image1.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] -= (pixel[j] ^ pix[j])/6; + } + } + } + MedianBlend(frame); + } + AddInvert(frame); +} + +void ac::ImageDarkBlend(cv::Mat &frame) { + if(blend_set == true) { + cv::Mat reimage; + cv::resize(blend_image, reimage, frame.size()); + for(int z = 0; z < frame.rows; ++z) { + cv::Scalar value; + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = reimage.at(z, i); + for(int j = 0; j < 3; ++j) { + if(pix[j] == 0) pix[j] = 1; + unsigned int val = pixel[j]%(1+pix[j]); + pixel[j] = pixel[j]^val; + } + } + } + AddInvert(frame); + } +} + +void ac::ImageAverageDark(cv::Mat &frame) { + if(blend_set == true) { + cv::Mat reimage,frame_copy = frame.clone(); + cv::resize(blend_image,reimage, frame.size()); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix[5]; + pix[0] = frame_copy.at(z, i); + pix[1] = frame_copy.at(z, frame.cols-i-1); + pix[2] = frame_copy.at(frame.rows-z-1, i); + pix[3] = frame_copy.at(frame.rows-z-1, frame.cols-i-1); + cv::Scalar values; + for(int j = 0; j < 4; ++j) { + for(int q = 0; q < 3; ++q) { + values[j] += pix[j][q]; + } + } + cv::Vec3b color = reimage.at(z, i); + for(int j = 0; j < 3; ++j) { + values[j] /= (frame.rows * frame.cols); + unsigned int value = static_cast(values[j]); + color[j] /= 3; + pixel[j] += 50; + pixel[j] = color[j] ^ value ^ pixel[j]; + } + } + } + AddInvert(frame); + } +} + +void ac::ImageRemainderPixel(cv::Mat &frame) { + if(blend_set == true) { + cv::Mat reimage; + cv::resize(blend_image, reimage, frame.size()); + static double alpha = 1.0, alpha_max = 4.0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = reimage.at(z, i); + for(int j = 0; j < 3; ++j) { + unsigned int val = static_cast(pixel[j] * (1+alpha))%(1+pix[j]); + pixel[j] = pixel[j] ^ val; + } + } + } + static int dir = 1; + procPos(dir,alpha,alpha_max,4.1, 0.05); + AddInvert(frame); + } +} + +void ac::AverageLinesBlend(cv::Mat &frame) { + static double alpha = 1.0, alpha_max = 4.0; + for(int z = 0; z < frame.rows; ++z) { + unsigned int values[3] = {0, 0, 0}; + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + values[j] += pixel[j]; + } + } + values[0] /= frame.cols; + values[1] /= frame.cols; + values[2] /= frame.cols; + for(int i = 0; i < frame.cols; ++i ){ + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + if(values[j] == 0 || values[j] == 255) values[j] = 1; + pixel[j] += static_cast((pixel[j]%1+values[j])*alpha); + } + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 4.1, 0.05); + AddInvert(frame); +} + +void ac::SoftFeedbackMirror(cv::Mat &frame) { + SoftFeedbackResize64(frame); + MirrorBitwiseXor(frame); + AddInvert(frame); +} + +void ac::AverageVerticalLinesBlend(cv::Mat &frame) { + static double alpha = 1.0, alpha_max = 4.0; + for(int i = 0; i < frame.cols; ++i) { + unsigned int values[3] = {0, 0, 0}; + for(int z = 0; z < frame.rows; ++z) { + cv::Vec3b pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + values[j] += pixel[j]; + } + } + values[0] /= frame.cols; + values[1] /= frame.cols; + values[2] /= frame.cols; + for(int z = 0; z < frame.rows; ++z) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + if(values[j] == 0 || values[j] == 255) values[j] = 1; + pixel[j] += static_cast((pixel[j]%1+values[j])*alpha); + } + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 4.1, 0.05); + AddInvert(frame); +} + +void ac::LinesMedianBlend(cv::Mat &frame) { + AverageLinesBlend(frame); + AverageVerticalLinesBlend(frame); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::XorSquare(cv::Mat &frame) { + for(int i = 0; i < frame.cols; ++i) { + for(int z = 0; z < frame.rows; ++z) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = pixel[j] ^ i ^ z; + } + } + } + AddInvert(frame); +} + +void ac::PixelValuesPlusOne(cv::Mat &frame) { + cv::Mat copy1 = frame.clone(); + MedianBlur(copy1); + MedianBlur(copy1); + MedianBlur(copy1); + static double alpha = 1.0, alpha_max = 4.0; + for(int i = 0; i < frame.cols-1; ++i) { + for(int z = 0; z < frame.rows-1; ++z) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix[4]; + pix[0] = pixel; + pix[1] = copy1.at(z+1, i+1); + pix[2] = copy1.at(z+1, i); + pix[3] = copy1.at(z, i+1); + cv::Scalar values; + for(int q = 0; q < 4; ++q) { + for(int j = 0; j < 3; ++j) { + values[j] += pix[q][j]; + } + } + for(int j = 0; j < 3; ++j) { + unsigned int v = static_cast(values[j] * alpha); + pixel[j] = pixel[j] ^ v; + } + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 4.1, 0.05); + AddInvert(frame); +} + +void ac::AverageHorizontalFilter(cv::Mat &frame) { + static double alpha = 1.0, alpha_max = 4.0; + for(int z = 0; z < frame.rows; ++z) { + unsigned int values[3] = {0,0,0}; + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + values[j] += pixel[j]; + } + } + for(int j = 0; j < 3; ++j) { + values[j] /= frame.cols; + } + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = static_cast(pixel[j] * (1+alpha)) ^ static_cast(values[j] * alpha); + } + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 4.1, 0.05); + AddInvert(frame); +} + +void ac::AverageVerticalFilter(cv::Mat &frame) { + static double alpha = 1.0, alpha_max = 4.0; + for(int i = 0; i < frame.cols; ++i) { + unsigned int values[3] = {0,0,0}; + for(int z = 0; z < frame.rows; ++z) { + cv::Vec3b pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + values[j] += pixel[j]; + } + } + for(int j = 0; j < 3; ++j) { + values[j] /= frame.rows; + } + for(int z = 0; z < frame.rows; ++z) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = static_cast(pixel[j] * (1+alpha)) ^ static_cast(values[j] * alpha); + } + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 4.1, 0.05); + AddInvert(frame); +} + +void ac::GradientAlphaXorHorizontal(cv::Mat &frame) { + int iteration = frame.cols/255; + static double alpha = 1.0, alpha_max = 4.0; + for(int z = 0; z < frame.rows; ++z) { + int index = 0, index_value = 0; + for(int i = 0; i < frame.cols; ++i) { + index ++; + if((index%iteration)==0) { + index = 0; + index_value ++; + } + cv::Vec3b &pixel = frame.at(z, i); + for (int j = 0; j < 3; ++j) { + pixel[j] = static_cast(pixel[j]*(alpha+1))^static_cast(index_value*alpha); + } + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 4.1, 0.01); + AddInvert(frame); +} + +void ac::GradientAlphaXorVertical(cv::Mat &frame) { + int iteration = frame.rows/255; + static double alpha = 1.0, alpha_max = 4.0; + for(int i = 0; i < frame.cols; ++i) { + int index = 0, index_value = 0; + for(int z = 0; z < frame.rows; ++z) { + index ++; + if((index%iteration)==0) { + index = 0; + index_value ++; + } + cv::Vec3b &pixel = frame.at(z, i); + for (int j = 0; j < 3; ++j) { + pixel[j] = static_cast(pixel[j]*(alpha+1))^static_cast(index_value*alpha); + } + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 4.1, 0.01); + AddInvert(frame); +} + +void ac::BlendImageWithSubFilter(cv::Mat &frame) { + if(blend_set == false || subfilter == -1 || ac::draw_strings[subfilter] == "BlendImageWithSubFilter") + return; + cv::Mat copy1 = frame.clone(); + cv::Mat reimage; + cv::resize(blend_image, reimage, frame.size()); + CallFilter(subfilter, copy1); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix[3]; + pix[0] = pixel; + pix[1] = copy1.at(z, i); + pix[2] = reimage.at(z, i); + unsigned int values[3] = {0,0,0}; + for(int q = 0; q < 3; ++q) { + for(int j = 0; j < 3; ++j) { + values[j] += pix[q][j]; + } + } + for(int j = 0; j < 3; ++j) { + values[j] /= 3; + pixel[j] = pixel[j] ^ values[j]; + } + } + } + AddInvert(frame); +} + +void ac::BlendImageWithSubFilterAlpha(cv::Mat &frame) { + if(blend_set == false || subfilter == -1 || ac::draw_strings[subfilter] == "BlendImageWithSubFilter") + return; + static double alpha = 1.0, alpha_max = 4.0; + cv::Mat copy1 = frame.clone(); + cv::Mat reimage; + cv::resize(blend_image, reimage, frame.size()); + CallFilter(subfilter, copy1); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix[3]; + pix[0] = pixel; + pix[1] = copy1.at(z, i); + pix[2] = reimage.at(z, i); + unsigned int values[3] = {0,0,0}; + for(int q = 0; q < 3; ++q) { + for(int j = 0; j < 3; ++j) { + values[j] += pix[q][j]; + } + } + for(int j = 0; j < 3; ++j) { + values[j] /= 3; + pixel[j] = static_cast(pixel[j]*(alpha+1)) ^ static_cast(values[j]*alpha); + } + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 4.1, 0.01); + AddInvert(frame); +} + + +void ac::MedianBlendSoft(cv::Mat &frame) { + static MatrixCollection<8> collection; + MedianBlur(frame); + collection.shiftFrames(frame); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Scalar value; + for(int j = 0; j < collection.size(); ++j) { + cv::Vec3b pixel = collection.frames[j].at(z, i); + for(int q = 0; q < 3; ++q) { + value[q] += pixel[q]; + } + } + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + int val = 1+static_cast(value[j]); + pixel[j] = static_cast(pixel[j] ^ val); + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } +} + +void ac::AndImageSubFilterXor(cv::Mat &frame) { + if(blend_set == false || subfilter == -1 || ac::draw_strings[subfilter] == "AndImageSubFilterXor") + return; + cv::Mat copy1 = frame.clone(), reimage; + cv::resize(blend_image, reimage, frame.size()); + CallFilter(subfilter, copy1); + static double alpha = 1.0, alpha_max = 4.0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix[2]; + pix[0] = reimage.at(z, i); + pix[1] = copy1.at(z, i); + unsigned int value = 0; + for(int j = 0; j < 3; ++j) { + value = pix[0][j] & pix[1][j]; + pixel[j] = pixel[j] ^ value; + } + + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 4.1, 0.01); + AddInvert(frame); +} + +void ac::AlphaBlendImageSubFilterXor(cv::Mat &frame) { + if(blend_set == false || subfilter == -1 || ac::draw_strings[subfilter] == "AlphaBlendImageSubFilterXor") + return; + cv::Mat reimage; + cv::Mat copy1 = frame.clone(), copy2; + cv::resize(blend_image, reimage, frame.size()); + CallFilter(subfilter, copy1); + AlphaBlend(copy1, reimage, copy2, 0.5); + Xor(frame, copy2); + AddInvert(frame); +} + +void ac::AlphaBlendImageSubFilterXorRev(cv::Mat &frame) { + if(blend_set == false || subfilter == -1 || ac::draw_strings[subfilter] == "AlphaBlendImageSubFilterXorRev") + return; + cv::Mat reimage, copy1; + cv::resize(blend_image, reimage, frame.size()); + CallFilter(subfilter, reimage); + AlphaBlend(frame, reimage, copy1, 0.5); + Xor(frame, copy1); + AddInvert(frame); +} + +void ac::ParticleReleaseXor(cv::Mat &frame) { + cv::Mat copy1 = frame.clone(); + ParticleRelease(copy1); + static double alpha = 1.0, alpha_max = 4.0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = copy1.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = static_cast(pixel[j] * (1+alpha)) ^ static_cast(pix[j] * alpha); + } + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 4.1, 0.05); + AddInvert(frame); + +} + +void ac::ParticleReleaseXorVec(cv::Mat &frame) { + cv::Mat copy1 = frame.clone(); + ParticleRelease(copy1); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = copy1.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = pixel[j]^pix[j]; + } + } + } + AddInvert(frame); +} + +void ac::ParticleReleaseAlphaBlend(cv::Mat &frame) { + cv::Mat copy1 = frame.clone(); + ParticleRelease(copy1); + static double alpha = 1.0, alpha_max = 4.0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = copy1.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = static_cast(pixel[j]*(alpha+1)) + static_cast(pix[j]*alpha); + } + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 4.1, 0.01); + AddInvert(frame); +} + +void ac::ParticleReleaseWithImage(cv::Mat &frame) { + if(blend_set == false) + return; + cv::Mat copy1; + cv::Mat copy2 = frame.clone(); + cv::resize(blend_image, copy1, frame.size()); + ParticleRelease(copy1); + AlphaBlend(copy1, copy2, frame, 0.5); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::ParticleReleaseSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "ParticleReleaseSubFilter") + return; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + CallFilter(subfilter, copy2); + AlphaBlend(copy1, copy2, frame, 0.5); + MedianBlend(frame); + ParticleRelease(frame); + AddInvert(frame); +} + +void ac::ParticleReleaseImageSubFilter(cv::Mat &frame) { + if(blend_set == false || subfilter == -1 || ac::draw_strings[subfilter] == "ParticleReleaseImageSubFilter") + return; + cv::Mat copy1 = frame.clone(), reimage; + cv::resize(blend_image, reimage, frame.size()); + CallFilter(subfilter, reimage); + AlphaBlend(copy1, reimage, frame, 0.5); + ParticleRelease(frame); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::ImageEnergy(cv::Mat &frame) { + if(blend_set == false) + return; + pushSubFilter(filter_map["ExactImage"]); + SmoothSubFilter32(frame); + MedianBlend(frame); + popSubFilter(); + AddInvert(frame); +} + + +void ac::ImageEnergySubFilter(cv::Mat &frame) { + if(blend_set == false || subfilter == -1 || ac::draw_strings[subfilter] == "ImageEnergySubFilter") + return; + SmoothSubFilter32(frame); + SmoothImageAlphaBlend(frame); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::ImageDistortion(cv::Mat &frame) { + if(blend_set == false) + return; + cv::Mat copy1 = frame.clone(), copy2; + cv::resize(blend_image, copy2, frame.size()); + pushSubFilter(ac::filter_map["SmoothImageAlphaBlend"]); + EnergizeSubFilter(copy1); + popSubFilter(); + pushSubFilter(ac::filter_map["ExactImage"]); + SmoothSubFilter(copy2); + popSubFilter(); + AlphaBlend(copy1, copy2, frame, 0.5); + AddInvert(frame); +} + +void ac::ImageDistortionSubFilter(cv::Mat &frame) { + if(blend_set == false || subfilter == -1 || ac::draw_strings[subfilter] == "ImageDistortionSubFilter") + return; + cv::Mat copy1 = frame.clone(); + cv::Mat copy2; + cv::resize(blend_image,copy2,frame.size()); + CallFilter(subfilter, copy1); + pushSubFilter(filter_map["ExactImage"]); + SmoothImageAlphaBlend(copy2); + popSubFilter(); + AlphaBlend(copy1, copy2, frame, 0.5); + AddInvert(frame); +} + +void ac::SmoothExactImageXorAlpha(cv::Mat &frame) { + if(blend_set == false) + return; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + pushSubFilter(filter_map["ExactImage"]); + SmoothSubFilter16(copy1); + popSubFilter(); + pushSubFilter(filter_map["XorAlpha"]); + SmoothSubFilter16(copy2); + popSubFilter(); + AlphaBlend(copy1, copy2, frame, 0.5); + AddInvert(frame); +} + +void ac::FeedbackColormap(cv::Mat &frame) { + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + pushSubFilter(-1); + SoftFeedbackResizeSubFilter64(copy1); + popSubFilter(); + pushSubFilter(filter_map["StrobeSort"]); + ColormapBlendSubFilter(copy2); + popSubFilter(); + MedianBlend(copy2); + AlphaBlend(copy1, copy2, frame, 0.5); + AddInvert(frame); +} + +void ac::SmoothImageAlphaBlendMedian(cv::Mat &frame) { + if(blend_set == false) + return; + cv::Mat copy1 = frame.clone(), reimage; + cv::resize(blend_image, reimage, frame.size()); + SmoothImageAlphaBlend(reimage); + MedianBlend(copy1); + MedianBlend(reimage); + AlphaBlend(copy1, reimage, frame, 0.5); + AddInvert(frame); +} + +void ac::ImageDarkenSmoothMedian(cv::Mat &frame) { + if(blend_set == false) + return; + DarkenFilter(frame); + SmoothImageAlphaBlendMedian(frame); + pushSubFilter(filter_map["RGBColorTrails"]); + SmoothSubFilter32(frame); + popSubFilter(); + MedianBlend(frame); + AddInvert(frame); +} + + +void ac::XorReverseImageSmooth(cv::Mat &frame) { + if(blend_set == false) + return; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(), reimage; + cv::resize(blend_image, reimage, frame.size()); + Xor(copy1, reimage); + Reverse(reimage); + Xor(copy2, reimage); + pushSubFilter(filter_map["ExactImage"]); + SmoothSubFilter32(copy1); + popSubFilter(); + AlphaBlend(copy1, copy2, frame, 0.5); + MedianBlend(frame); +} + +void ac::ReverseSubFilterBlend(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "ReverseSubFilterBlend") + return; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + CallFilter(subfilter, copy1); + Reverse(copy2); + CallFilter(subfilter, copy2); + AlphaBlend(copy1, copy2, frame, 0.5); +} + +void ac::ReverseSubFilterXor(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "ReverseSubFilterXor") + return; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + Reverse(copy1); + CallFilter(subfilter, copy1); + CallFilter(subfilter, copy2); + Xor(copy1, frame); + Xor(copy2, frame); + AlphaBlend(copy1, copy2, frame, 0.5); +} + +void ac::ImageReverseSubFilter(cv::Mat &frame) { + if(blend_set == false || subfilter == -1 || ac::draw_strings[subfilter] == "ImageReverseSubFilter") + return; + + cv::Mat reimage; + cv::resize(blend_image, reimage, frame.size()); + cv::Mat all_frames[3]; + cv::flip(frame, all_frames[0], -1); + cv::flip(frame, all_frames[1], 0); + cv::flip(frame, all_frames[2], 1); + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + for(int z = 0; z < copy1.rows; ++z) { + for(int i = 0; i < copy1.cols; ++i){ + cv::Vec3b &pixel = copy1.at(z, i); + cv::Vec3b pix[4]; + for(int j = 0; j < 3; ++j) { + pix[j] = all_frames[j].at(z, i); + } + for(int j = 0; j < 3; ++j) { + pixel[j] = pix[0][j] ^ pix[1][j] ^ pix[2][j] ^ pixel[j]; + } + } + } + static MatrixCollection<8> collection; + Smooth(copy1, &collection); + CallFilter(subfilter, reimage); + Xor(reimage, copy1); + AlphaBlend(reimage, copy2, frame, 0.5); + DarkenFilter(frame); + MedianBlend(frame); +} + +void ac::SmoothRainbowMedian(cv::Mat &frame) { + cv::Mat copy1 = frame.clone(); + pushSubFilter(filter_map["RainbowXorBlend"]); // push new filter to stop of stack + SmoothSubFilter32(frame);// Call function with SubFilter + popSubFilter();// pop subfilter off of stack + DarkenFilter(frame); + MedianBlend(frame);// median blend + cv::Mat copy2 = frame.clone(); + AlphaBlend(copy1, copy2, frame, 0.5); +} diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter14.cpp b/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter14.cpp new file mode 100755 index 0000000..1a465b7 --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter14.cpp @@ -0,0 +1,1109 @@ +/* + * Software written by Jared Bruni https://github.com/lostjared + + This software is dedicated to all the people that experience mental illness. + + Website: http://lostsidedead.com + YouTube: http://youtube.com/LostSideDead + Instagram: http://instagram.com/jaredbruni + Twitter: http://twitter.com/jaredbruni + Facebook: http://facebook.com/LostSideDead0x + + You can use this program free of charge and redistrubute it online as long + as you do not charge anything for this program. This program is meant to be + 100% free. + + BSD 2-Clause License + + Copyright (c) 2019, Jared Bruni + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + */ + +#include "ac.h" + + +void ac::MirrorAlphaBlend(cv::Mat &frame) { + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(), copy3 = frame.clone(), copy4; + MirrorBitwiseXor(copy1); + MirrorXorAll(copy2); + AlphaBlend(copy1, copy2, copy4, 0.5); + AlphaBlend(copy3, copy4, frame, 0.5); + BlendWithSource(frame); + DarkenFilter(frame); + MirrorBitwiseXor(frame); + AddInvert(frame); +} + +void ac::ImageSmoothMedianBlend(cv::Mat &frame) { + if(blend_set == false) + return; + + rainbowBlend(frame); + pushSubFilter(filter_map["ExactImage"]); + SmoothSubFilter32(frame); + popSubFilter(); + DarkenFilter(frame); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::ImageSmoothMedianSubFilter(cv::Mat &frame) { + if(blend_set == false || subfilter == -1 || ac::draw_strings[subfilter] == "ImageSmoothMedianSubFilter") + return; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + rainbowBlend(copy1); + pushSubFilter(filter_map["ExactImage"]); + SmoothSubFilter32(copy1); + popSubFilter(); + DarkenFilter(copy1); + MedianBlend(copy1); + AlphaBlend(copy1, copy2, frame, 0.5); + CallFilter(subfilter, frame); + AddInvert(frame); + +} + +void ac::ImageAlphaXorMedianBlend(cv::Mat &frame) { + if(blend_set == false) + return; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(), reimage; + cv::resize(blend_image, reimage, frame.size()); + SmoothImageAlphaBlend(copy1); + ImageSmoothMedianBlend(copy2); + static double alpha = 1.0, alpha_max = 4.0; + AlphaXorBlend(copy1, copy2, frame, alpha); + static int dir = 1; + procPos(dir, alpha, alpha_max, 4.1, 0.01); + AddInvert(frame); +} + +// use with Custom as Subfilter +void ac::MatrixCollectionBlend(cv::Mat &frame) { + static MatrixCollection<8> collection; + cv::Mat copy1 = frame.clone(); + collection.shiftFrames(copy1); + for(int i = 0; i < collection.size(); ++i) { + ShuffleAlpha(collection.frames[i]); + MedianBlur(collection.frames[i]); + } + Smooth(frame, &collection, false); + AddInvert(frame); +} + +// use with Custom goes good with RainbowXorBlend +void ac::MatrixCollectionSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "MatrixCollectionSubFilter") + return; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + static MatrixCollection<4> collection; + collection.shiftFrames(frame); + for(int i = 0; i < collection.size(); ++i) { + CallFilter(subfilter, collection.frames[i]); + } + Smooth(copy2, &collection, false); + AlphaBlend(copy1, copy2, frame, 0.5); + AddInvert(frame); +} + +void ac::MatrixCollectionImageSubFilter(cv::Mat &frame) { + if(blend_set == false || subfilter == -1 || ac::draw_strings[subfilter] == "MatrixCollectionImageSubFilter") + return; + static MatrixCollection<8> collection; + cv::Mat copy1 = frame.clone(), reimage; + cv::resize(blend_image, reimage, frame.size()); + CallFilter(subfilter, copy1); + collection.shiftFrames(reimage); + collection.shiftFrames(copy1); + Smooth(copy1, &collection, false); + AlphaBlend(copy1, reimage, frame, 0.5); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::MatrixCollectionBlurAlpha(cv::Mat &frame) { + static MatrixCollection<4> collection; + static double alpha = 1.0, alpha_max = 4.0; + cv::Mat copy1 = frame.clone(); + MedianBlend(copy1); + collection.shiftFrames(copy1); + Smooth(frame, &collection); + for(int z = 0; z < frame.rows; ++z) { + cv::Vec3b values[4]; + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int q = 0; q < collection.size(); ++q) { + values[q] = collection.frames[q].at(z, i); + } + for(int j = 0; j < 3; ++j) { + pixel[j] = (values[0][j] ^ values[1][j] ^ values[2][j])^pixel[j]; + } + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 4.1, 0.01); + AddInvert(frame); +} + +void ac::MatrixCollectionXor(cv::Mat &frame) { + static MatrixCollection<16> collection; + collection.shiftFrames(frame); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix[16]; + cv::Vec3b copypix = pixel; + for(int q = 0; q < collection.size(); ++q) { + pix[q] = collection.frames[q].at(z, i); + } + for(int j = 0; j < 3; ++j) { + for(int r = 0; r < collection.size(); ++r) { + copypix[j] ^= pix[r][j]; + } + pixel[j] = copypix[j]; + } + } + } + AddInvert(frame); +} + +void ac::MatrixCollectionXor32(cv::Mat &frame) { + static MatrixCollection<32> collection; + collection.shiftFrames(frame); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix[32]; + cv::Vec3b copypix = pixel; + for(int q = 0; q < collection.size(); ++q) { + pix[q] = collection.frames[q].at(z, i); + } + for(int j = 0; j < 3; ++j) { + for(int r = 0; r < collection.size(); ++r) { + copypix[j] ^= pix[r][j]; + } + pixel[j] = copypix[j]; + } + } + } + AddInvert(frame); +} + +void ac::MatrixCollectionRandomColorMap(cv::Mat &frame) { + static MatrixCollection<16> collection; + cv::Mat copy1 = frame.clone(); + RandomColorMap(copy1); + collection.shiftFrames(copy1); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix[16]; + cv::Vec3b copypix = pixel; + for(int q = 0; q < collection.size(); ++q) { + pix[q] = collection.frames[q].at(z, i); + } + for(int j = 0; j < 3; ++j) { + for(int r = 0; r < collection.size(); ++r) { + copypix[j] ^= pix[r][j]; + } + pixel[j] = copypix[j]; + } + } + } + AddInvert(frame); +} + +void ac::MatrixCollectionDarkXor(cv::Mat &frame) { + static MatrixCollection<32> collection; + collection.shiftFrames(frame); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix[32]; + cv::Vec3b copypix = pixel; + for(int q = 0; q < collection.size(); ++q) { + pix[q] = collection.frames[q].at(z, i); + } + for(int j = 0; j < 3; ++j) { + for(int r = 0; r < collection.size(); ++r) { + copypix[j] ^= pix[r][j]; + } + pixel[j] = copypix[j]^pixel[j]; + } + } + } + AddInvert(frame); + +} + +void ac::MatrixCollectionRGB(cv::Mat &frame) { + static MatrixCollection<32> collection; + static int counter = 0; + cv::Mat copy1 = frame.clone(); + switch(counter) { + case 0: + AllRed(copy1); + break; + case 1: + AllGreen(copy1); + break; + case 2: + AllBlue(copy1); + break; + } + ++counter; + if(counter > 2) + counter = 0; + collection.shiftFrames(copy1); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix[32]; + cv::Vec3b copypix = pixel; + for(int q = 0; q < collection.size(); ++q) { + pix[q] = collection.frames[q].at(z, i); + } + for(int j = 0; j < 3; ++j) { + for(int r = 0; r < collection.size(); ++r) { + copypix[j] ^= pix[r][j]; + } + pixel[j] = copypix[j]; + } + } + } + AddInvert(frame); +} + +void ac::TrailsSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "TrailsSubFilter") + return; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + MatrixCollectionXor(copy1); + CallFilter(subfilter, copy2); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = copy1.at(z, i), pix2 = copy2.at(z, i); + cv::Vec3b lv(100, 100, 100); + cv::Vec3b hv(100, 100, 100); + if(colorBounds(pix,pixel,lv, hv)) { + pixel = pix; + } else { + pixel = pix2; + } + } + } + AddInvert(frame); +} + +// difference between frames +void ac::TrailsSubFilter32(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "DifferenceSubFilter") + return; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + MatrixCollectionXor32(copy1); + CallFilter(subfilter, copy2); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = copy1.at(z, i), pix2 = copy2.at(z, i); + cv::Vec3b lv(100, 100, 100); + cv::Vec3b hv(100, 100, 100); + if(colorBounds(pix,pixel,lv, hv)) { + pixel = pix; + } else { + pixel = pix2; + } + } + } + AddInvert(frame); +} + +void ac::CompareWithSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "DifferenceSubFilter") + return; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + CallFilter(subfilter, copy2); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix1 = copy1.at(z, i), pix2 = copy2.at(z, i); + cv::Vec3b lv(100, 100, 100); + cv::Vec3b hv(100, 100, 100); + if(colorBounds(pix1,pix2,lv, hv)) { + pixel = pix2; + } else { + pixel = pix1; + } + } + } + AddInvert(frame); +} + +void ac::MedianTrails(cv::Mat &frame) { + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + pushSubFilter(filter_map["RandomColorMap"]); + TrailsSubFilter(copy1); + popSubFilter(); + MedianBlend(copy2); + AlphaBlend(copy1,copy2,frame,0.5); + AddInvert(frame); +} + +void ac::SmoothMedianBlend(cv::Mat &frame) { + pushSubFilter(filter_map["MatrixCollectionXor"]); + SmoothSubFilter(frame); + popSubFilter(); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::ColorTransition(cv::Mat &frame) { + static int val[3] = {rand()%255,rand()%255,rand()%255}; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] += val[j]; + } + } + } + static int dir[3] = {1,1,1}; + static int speed[3] = {1,1,1}; + for(int j = 0; j < 3; ++j) { + if(dir[j] == 1) { + val[j] += speed[j]; + if(val[j] >= 255) { + val[j] = rand()%255; + dir[j] = 0; + ++speed[j]; + if(speed[j] > 5) speed[j] = 1; + } + } else if(dir[j] == 0) { + val[j] -= speed[j]; + if(val[j] <= 1) { + val[j] = rand()%255; + dir[j] = 1; + ++speed[j]; + if(speed[j] > 5) speed[j] = 1; + } + } + } + AddInvert(frame); +} + +void ac::ColorTransitionMedian(cv::Mat &frame) { + ColorTransition(frame); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::ColorTransitionRandom(cv::Mat &frame) { + static int val[3] = {rand()%255,rand()%255,rand()%255}; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] += val[j]; + } + } + } + static int dir[3] = {rand()%2,rand()%2,rand()%2}; + static int speed[3] = {rand()%5,rand()%5,rand()%5}; + for(int j = 0; j < 3; ++j) { + if(dir[j] == 1) { + val[j] += speed[j]; + if(val[j] >= 255) { + val[j] = rand()%255; + dir[j] = rand()%2; + ++speed[j]; + if(speed[j] > 5) speed[j] = 1; + } + } else if(dir[j] == 0) { + val[j] -= speed[j]; + if(val[j] <= 1) { + val[j] = rand()%255; + dir[j] = rand()%2; + ++speed[j]; + if(speed[j] > 5) speed[j] = 1; + } + } + } + AddInvert(frame); +} + +void ac::ColorTransitionRandomMedian(cv::Mat &frame) { + ColorTransitionRandom(frame); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::ColorTransitionSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "ColorTransitionSubFilter") + return; + cv::Mat copy1 = frame.clone(); + cv::Mat copy2 = frame.clone(); + CallFilter(subfilter, copy1); + ColorTransitionRandomMedian(copy2); + AlphaBlend(copy1, copy2, frame, 0.5); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::ColorTransitionImageSubFilter(cv::Mat &frame) { + if(blend_set == false || subfilter == -1 || ac::draw_strings[subfilter] == "ColorTransitionImageSubFilter") + return; + cv::Mat copy1 = frame.clone(), copy2; + cv::resize(blend_image, copy2, frame.size()); + CallFilter(subfilter, copy1); + CallFilter(subfilter, copy2); + AlphaBlend(copy1, copy2, frame, 0.5); + AddInvert(frame); +} + +void ac::CurtainSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "CurtainSubFilter") + return; + if(testSize(frame) == false) + return; + static int start = 0; + static int direction = 1; + static double alpha = 1.0, alpha_max = 7.0; + cv::Mat frame_copy = frame.clone(); + CallFilter(subfilter, frame_copy); + for(int z = 0; z < frame.rows; ++z) { + if(direction == 1) { + for(int i = 0; i < start; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b copy_pix = frame_copy.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] ^= static_cast(copy_pix[j]+pixel[j]); + } + } + } else { + + for(int i = frame.cols-1; i > start; --i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b copy_pix = frame_copy.at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] ^= static_cast(copy_pix[j]+pixel[j]); + } + } + } + if(direction == 1) { + start += 40; + if(start > frame.cols-1) { + direction = 0; + } + } else { + start -= 40; + if(start <= 1) { + direction = 1; + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max); + AddInvert(frame); +} + + +void ac::RandomTrails(cv::Mat &frame) { + pushSubFilter(filter_map["Random Filter"]); + TrailsSubFilter(frame); + popSubFilter(); + AddInvert(frame); +} + +void ac::RandomTrailsSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "RandomTrailsSubFilter") + return; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + pushSubFilter(filter_map["Random Filter"]); + TrailsSubFilter(copy1); + popSubFilter(); + CallFilter(subfilter, copy2); + AlphaBlend(copy1, copy2, frame, 0.5); + AddInvert(frame); +} + +void ac::CosSinMedianBlend(cv::Mat &frame) { + pushSubFilter(filter_map["CosSinMultiply"]); + SmoothSubFilter(frame); + popSubFilter(); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::TrailsRGB(cv::Mat &frame) { + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + MatrixTrailsXorRandom(copy1); + StrobeXor(copy2); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = copy1.at(z, i), pix2 = copy2.at(z, i); + cv::Vec3b lv(100, 100, 100); + cv::Vec3b hv(100, 100, 100); + if(colorBounds(pix,pixel,lv, hv)) { + pixel = pix; + } else { + pixel = pix2; + } + } + } + AddInvert(frame); +} + +void ac::MatrixTrailsXorRandom(cv::Mat &frame) { + static MatrixCollection<16> collection; + collection.shiftFrames(frame); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix[16]; + cv::Vec3b copypix = pixel; + for(int q = 0; q < collection.size(); ++q) { + pix[q] = collection.frames[q].at(z, i); + } + + for(int j = 0; j < 3; ++j) { + for(int r = 0; r < collection.size(); ++r) { + copypix[j] ^= pix[r][j]; + } + pixel[j] = copypix[j]; + } + if(copypix != pixel) { + for(int j = 0; j < 3; ++j) { + pixel[j] = rand()%256; + } + } + } + } + AddInvert(frame); +} + + +void ac::CosSinMultiplyCollectionXor(cv::Mat &frame) { + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + cossinMultiply(copy1); + MatrixCollectionXor(copy2); + AlphaBlend(copy1, copy2, frame, 0.5); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::Filter8_Blend(cv::Mat &frame) { + static MatrixCollection<8> collection; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + filter8(copy1); + Smooth(copy1, &collection); + MedianBlend(copy2); + AlphaBlend(copy1, copy2, frame, 0.5); + AddInvert(frame); +} + +void ac::Filter8_SubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "Filter8_SubFilter") + return; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + filter8(copy1); + CallFilter(subfilter, copy1); + AlphaBlend(copy1, copy2, frame, 0.5); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::RandomSmoothAlphaMedian(cv::Mat &frame) { + static MatrixCollection<8> collection; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + randomFilter(copy1); + Smooth(copy1, &collection); + AlphaBlend(copy1, copy2, frame, 0.5); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::RandomAlphaBlendFilter(cv::Mat &frame) { + static MatrixCollection<8> collection1, collection2; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(), copy3 = frame.clone(), copy4, copy5; + randomFilter(copy1); + Smooth(copy1, &collection1); + randomFilter(copy2); + Smooth(copy2, &collection2); + AlphaBlend(copy1, copy3, copy4, 0.5); + AlphaBlend(copy2, copy3, copy5, 0.5); + AlphaBlend(copy4, copy5, frame, 0.5); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::RandomMirrorBitwiseXor(cv::Mat &frame) { + static MatrixCollection<16> collection; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + randomFilter(copy1); + Smooth(copy1, &collection); + MirrorBitwiseXor(copy2); + AlphaBlend(copy1, copy2, frame, 0.5); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::SquareDivideSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "SquareDivideSubFilter") + return; + static MatrixCollection<4> collection; + collection.shiftFrames(frame); + cv::Mat copy1 = frame.clone(); + int pos_x = 0, pos_y = 0; + int index = 0; + int size_w = frame.cols/2; + int size_h = frame.rows/2; + cv::Mat resized[4]; + for(int i = 0; i < 2; ++i) { + for(int z = 0; z < 2; ++z) { + pos_x = i*size_w; + pos_y = z*size_h; + cv::resize(collection.frames[index], resized[index], cv::Size(size_w, size_h)); + randomFilter(resized[index]); + copyMat(resized[index], 0, 0, frame, pos_x, pos_y, size_w, size_h); + ++index; + } + } + CallFilter(subfilter, copy1); + cv::Mat fcopy = frame.clone(); + AlphaBlend(copy1, frame, fcopy, 0.5); + frame = fcopy.clone(); + AddInvert(frame); +} + +void ac::SquareSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "SquareSubFilter") + return; + static MatrixCollection<8> collection; + collection.shiftFrames(frame); + int pos_x = 0, pos_y = 0; + int index = 0; + int size_w = frame.cols/2; + int size_h = frame.rows/2; + cv::Mat resized[8]; + for(int i = 0; i < 2; ++i) { + for(int z = 0; z < 2; ++z) { + pos_x = i*size_w; + pos_y = z*size_h; + cv::resize(collection.frames[index], resized[index], cv::Size(size_w, size_h)); + CallFilter(subfilter, resized[index]); + copyMat(resized[index], 0, 0, frame, pos_x, pos_y, size_w, size_h); + ++index; + } + } + AddInvert(frame); +} + +void ac::SquareSubFilter8(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "SquareSubFilter8") + return; + constexpr int num_s = 4; + static MatrixCollection collection; + collection.shiftFrames(frame); + int pos_x = 0, pos_y = 0; + int index = 0; + int size_w = frame.cols/num_s; + int size_h = frame.rows/num_s; + cv::Mat resized[num_s*num_s]; + for(int i = 0; i < num_s; ++i) { + for(int z = 0; z < num_s; ++z) { + pos_x = i*size_w; + pos_y = z*size_h; + cv::resize(collection.frames[index], resized[index], cv::Size(size_w, size_h)); + CallFilter(subfilter, resized[index]); + copyMat(resized[index], 0, 0, frame, pos_x, pos_y, size_w, size_h); + ++index; + } + } + AddInvert(frame); +} + +void ac::SquareRandomFilter(cv::Mat &frame) { + constexpr int num_s = 4; + int pos_x = 0, pos_y = 0; + int index = 0; + int size_w = frame.cols/num_s; + int size_h = frame.rows/num_s; + cv::Mat resized[num_s*num_s]; + for(int i = 0; i < num_s; ++i) { + for(int z = 0; z < num_s; ++z) { + pos_x = i*size_w; + pos_y = z*size_h; + resized[index].create(cv::Size(size_w, size_h),CV_8UC3); + copyMat(frame, Rect(pos_x, pos_y, size_w, size_h), resized[index], Rect(0, 0, size_w, size_h)); + randomFilter(resized[index]); + copyMat(resized[index], Rect(0, 0, size_w, size_h), frame, Rect(pos_x, pos_y, size_w, size_h)); + ++index; + } + } + AddInvert(frame); +} + +void ac::SquareRandomSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "SquareRandomSubFilter") + return; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + constexpr int num_s = 4; + static MatrixCollection collection; + int pos_x = 0, pos_y = 0; + int index = 0; + int size_w = frame.cols/num_s; + int size_h = frame.rows/num_s; + cv::Mat resized[num_s*num_s]; + for(int i = 0; i < num_s; ++i) { + for(int z = 0; z < num_s; ++z) { + pos_x = i*size_w; + pos_y = z*size_h; + resized[index].create(cv::Size(size_w, size_h),CV_8UC3); + copyMat(copy1, Rect(pos_x, pos_y, size_w, size_h), resized[index], Rect(0, 0, size_w, size_h)); + randomFilter(resized[index]); + CallFilter(subfilter, resized[index]); + copyMat(resized[index], Rect(0, 0, size_w, size_h), copy2, Rect(pos_x, pos_y, size_w, size_h)); + ++index; + } + } + AlphaBlend(copy1, copy2, frame, 0.5); + Smooth(frame, &collection); + AddInvert(frame); +} + + +void ac::ColorExpand(cv::Mat &frame) { + static int color_value[3] = {rand()%255,rand()%255,rand()%255}; + static int dir[3] = {rand()%2, rand()%2, rand()%2}; + static int max_dir[3] = {rand()%2, rand()%2, rand()%2}; + static int s_max[3] = {rand()%255, rand()%255, rand()%255}; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] += color_value[j]; + } + } + for(int q = 0; q < 3; ++q) { + if(dir[q] == 0) { + ++color_value[q]; + if(color_value[q] > s_max[q]) { + dir[q] = 1; + if(max_dir[q] == 0) { + s_max[q] += 5; + if(s_max[q] > 255) { + max_dir[q] = 1; + } + } else { + s_max[q] -= 5; + if(s_max[q] <= 1) { + max_dir[q] = 0; + } + } + } + + } else { + --color_value[q]; + if(color_value[q] <= 1) { + dir[q] = 0; + if(max_dir[q] == 0) { + s_max[q] += 5; + if(s_max[q] > 255) { + max_dir[q] = 1; + } + } else { + s_max[q] -= 5; + if(s_max[q] <= 1) { + max_dir[q] = 0; + } + } + } + } + } + AddInvert(frame); +} + +void ac::ColorExpandSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "ColorExpandSubFilter") + return; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + CallFilter(subfilter, copy1); + ColorExpand(copy2); + static double alpha = 1.0, alpha_max = 4.0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix[2]; + static int pixval[3] = {0,0,0}; + pix[0] = copy1.at(z, i); + pix[1] = copy2.at(z, i); + for(int j = 0; j < 3; ++j) { + pixval[j] = pix[0][j] ^ pix[1][j]; + pixval[j] /= 3; + pixel[j] = pixval[j] ^ static_cast(pixel[j]*(alpha+1)); + } + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max); + AddInvert(frame); +} + +void ac::RotateImage(cv::Mat &frame) { + if(blend_set == false) + return; + static int fcode = -1; + cv::Mat img, copy1; + cv::resize(blend_image, img, frame.size()); + cv::flip(img, copy1, fcode); + frame = copy1.clone(); + ++fcode; + if(fcode > 1) + fcode = -1; + AddInvert(frame); +} + +void ac::RotateBlendImage(cv::Mat &frame) { + cv::Mat img_copy = frame.clone(), image1 = frame.clone(); + RotateImage(img_copy); + AlphaBlend(img_copy, image1, frame, 0.5); + AddInvert(frame); +} + +void ac::RotateImageSubFilter(cv::Mat &frame) { + if(blend_set == false || subfilter == -1 || ac::draw_strings[subfilter] == "RotateImageSubFilter") + return; + + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + RotateBlendImage(copy1); + CallFilter(subfilter, copy2); + AlphaBlend(copy1, copy2, frame, 0.5); + AddInvert(frame); +} + +void ac::RotateAlphaBlendImage(cv::Mat &frame) { + if(blend_set == false) + return; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + RotateImage(copy1); + static double alpha = 1.0, alpha_max = 2.5; + AlphaBlend(copy1, copy2, frame, alpha); + static int dir = 1; + procPos(dir, alpha, alpha_max, 2.4, 0.01); + AddInvert(frame); +} + +void ac::FlipShuffle(cv::Mat &frame) { + static auto rng = std::default_random_engine{}; + static std::vector flip_codes {-1, 0, 1}; + static int offset = 0; + cv::Mat copy1 = frame.clone(); + cv::flip(copy1, frame, flip_codes[offset]); + ++offset; + if(offset > flip_codes.size()) { + offset = 0; + std::shuffle(flip_codes.begin(), flip_codes.end(), rng); + } + AddInvert(frame); +} + +void ac::FlipRandom(cv::Mat &frame) { + cv::Mat copy1 = frame.clone(); + int offset = -1; + offset += rand()%3; + cv::flip(copy1, frame, offset); + AddInvert(frame); +} + +void ac::FlipOrder(cv::Mat &frame) { + static int offset = -1; + cv::Mat copy1 = frame.clone(); + cv::flip(copy1, frame, offset); + ++offset; + if(offset > 1) + offset = -1; + AddInvert(frame); +} + +void ac::FlipStrobeSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "FlipStrobeSubFilter") + return; + static int offset = 0; + if(offset == 0) { + FlipOrder(frame); + CallFilter(subfilter,frame); + offset = 1; + } else { + Negate(frame); + offset = 0; + } + AddInvert(frame); +} + + +void ac::MirrorBlendFrame(cv::Mat &frame) { + cv::Mat copy1 = frame.clone(), copy2; + cv::flip(copy1, copy2, 1); + AlphaBlend(copy1, copy2, frame, 0.5); + AddInvert(frame); +} + +void ac::MirrorBlendVertical(cv::Mat &frame) { + cv::Mat copy1 = frame.clone(), copy2; + cv::flip(copy1, copy2, 0); + AlphaBlend(copy1, copy2, frame, 0.5); + AddInvert(frame); +} + +void ac::MirrorVerticalAndHorizontal(cv::Mat &frame) { + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + MirrorBlendFrame(copy1); + MirrorBlendVertical(copy2); + AlphaBlend(copy1, copy2, frame, 0.5); + AddInvert(frame); +} + +void ac::BlendFor360(cv::Mat &frame) { + const int width = 100; + double inc_val = 1.0/width; + double alpha1 = 1.0; + double alpha2 = 0.0; + cv::Mat copy1 = frame.clone(); + for(int z = 0; z < frame.rows; ++z) { + alpha1 = 1.0; + alpha2 = 0.0; + for(int i = width-1; i >= 0; --i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = copy1.at(z, copy1.cols-i-1); + for(int j = 0; j < 3; ++j) { + pixel[j] = static_cast((pixel[j]*alpha1)+(pix[j]*alpha2)); + } + alpha1 -= inc_val; + alpha2 += inc_val; + } + } + /* + for(int z = 0; z < frame.rows; ++z) { + alpha1 = 0.1; + alpha2 = 0.9; + for(int i = width-1; i >= 0; --i) { + cv::Vec3b &pixel = frame.at(z, copy1.cols-i-1); + cv::Vec3b pix = copy1.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = static_cast((pixel[j]*alpha1)+(pix[j]*alpha2)); + } + alpha1 += inc_val; + alpha2 -= inc_val; + } + } + */ + AddInvert(frame); +} + +void ac::MirrorSidesMedian(cv::Mat &frame) { + MirrorXorAll(frame); + MirrorVerticalAndHorizontal(frame); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::MirrorSidesSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "MirrorSidesSubFilter") + return; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + MirrorXorAll(copy1); + MirrorVerticalAndHorizontal(frame); + CallFilter(subfilter, copy2); + AlphaBlend(copy1, copy2, frame, 0.5); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::MedianFrameAlphaBlendSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "MedianFrameAlphaBlendSubFilter") + return; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + CallFilter(subfilter, copy1); + AlphaBlend(copy1, copy2,frame, 0.5); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::MedianSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "MedianSubFilter") + return; + static MatrixCollection<8> collection1, collection2; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone();; + CallFilter(subfilter, copy1); + randomFilter(copy2); + collection1.shiftFrames(copy1); + collection2.shiftFrames(copy2); + Smooth(copy1, &collection1, false); + Smooth(copy2, &collection2, false); + MedianBlend(copy1); + MedianBlend(copy2); + AlphaBlend(copy1, copy2, frame, 0.5); + AddInvert(frame); +} + +void ac::ColorXorScale(cv::Mat &frame) { + static int rgb[3] = {rand()%255, rand()%255, rand()%255}; + static int dir[3] = {1,1,1}; + static double alpha = 1.0, alpha_max = 4.0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = static_cast(pixel[j] * (1+alpha)) ^ static_cast(rgb[j] * alpha); + } + } + } + for(int j = 0; j < 3; ++j) { + if(dir[j] == 1) { + ++rgb[j]; + if(rgb[j] >= 255) + dir[j] = 0; + + } else { + --rgb[j]; + if(rgb[j] <= 1) + dir[j] = 1; + } + + } + static int d = 1; + procPos(d, alpha, alpha_max, 4.1, 0.01); + AddInvert(frame); +} + +void ac::ColorXorScaleSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "ColorXorScaleSubFilter") + return; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + ColorXorScale(copy1); + CallFilter(subfilter, copy2); + AlphaBlend(copy1, copy2, frame, 0.5); + AddInvert(frame); +} diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter15.cpp b/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter15.cpp new file mode 100755 index 0000000..93f762c --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter15.cpp @@ -0,0 +1,1062 @@ +/* + * Software written by Jared Bruni https://github.com/lostjared + + This software is dedicated to all the people that experience mental illness. + + Website: http://lostsidedead.com + YouTube: http://youtube.com/LostSideDead + Instagram: http://instagram.com/jaredbruni + Twitter: http://twitter.com/jaredbruni + Facebook: http://facebook.com/LostSideDead0x + + You can use this program free of charge and redistrubute it online as long + as you do not charge anything for this program. This program is meant to be + 100% free. + + BSD 2-Clause License + + Copyright (c) 2019, Jared Bruni + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + */ + +#include "ac.h" + +void ac::ImageXorScale(cv::Mat &frame) { + if(blend_set == false) + return; + cv::Mat reimage; + cv::resize(blend_image, reimage, frame.size()); + static int scale = rand()%255; + static int dir = rand()%2; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b copy_pix = reimage.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = pixel[j]^copy_pix[j]^scale; + } + } + } + if(dir == 1) { + ++scale; + if(scale >= 255) + dir = 0; + } else { + --scale; + if(scale <= 1) + dir = 1; + } + AddInvert(frame); +} + +void ac::MatrixCollectionShiftSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "MatrixCollectionShiftSubFilter") + return; + static MatrixCollection<32> collection; + cv::Mat copy1 = frame.clone(); + CallFilter(subfilter, copy1); + Smooth(copy1, &collection); + cv::Mat copy2 = frame.clone(); + AlphaBlend(copy1, copy2, frame, 0.5); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::MatrixCollectionImageShiftSubFilter(cv::Mat &frame) { + if(blend_set == false || subfilter == -1 || ac::draw_strings[subfilter] == "MatrixCollectionImageShiftSubFilter") + return; + cv::Mat reimage, copy1 = frame.clone(); + cv::resize(blend_image, reimage, frame.size()); + CallFilter(subfilter, reimage); + static MatrixCollection<32> collection; + Smooth(reimage, &collection); + AlphaBlend(reimage, copy1, frame, 0.5); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::MatrixCollectionSmoothAlphaBlend(cv::Mat &frame) { + static MatrixCollection<32> collection; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + Smooth(copy1, &collection); + AlphaBlend(copy1, copy2, frame, 0.5); + AddInvert(frame); +} + +void ac::MatrixCollectionBlurImageXorAlpha(cv::Mat &frame) { + if(blend_set == false) + return; + static MatrixCollection<8> collection; + static MatrixCollection<8> image_collection; + cv::Mat copy1 = frame.clone(), copy2; + cv::resize(blend_image, copy2, frame.size()); + XorAlpha(copy2); + Smooth(copy2, &image_collection); + Smooth(copy1, &collection); + AlphaBlend(copy1, copy2, frame, 0.5); + AddInvert(frame); +} + +void ac::MatrixCollectionBlurImageSubFilter(cv::Mat &frame) { + if(blend_set == false || subfilter == -1 || ac::draw_strings[subfilter] == "MatrixCollectionBlurImageSubFilter") + return; + static MatrixCollection<8> collection; + static MatrixCollection<8> image_collection; + cv::Mat copy1 = frame.clone(), copy2; + cv::resize(blend_image, copy2, frame.size()); + CallFilter(subfilter, copy2); + Smooth(copy2, &image_collection); + Smooth(copy1, &collection); + AlphaBlend(copy1, copy2, frame, 0.5); + AddInvert(frame); +} + +void ac::MatrixCollectionBlurImageSubFilter16(cv::Mat &frame) { + if(blend_set == false || subfilter == -1 || ac::draw_strings[subfilter] == "MatrixCollectionBlurImageSubFilter16") + return; + static MatrixCollection<16> collection; + static MatrixCollection<16> image_collection; + cv::Mat copy1 = frame.clone(), copy2; + cv::resize(blend_image, copy2, frame.size()); + CallFilter(subfilter, copy2); + Smooth(copy2, &image_collection); + Smooth(copy1, &collection); + AlphaBlend(copy1, copy2, frame, 0.5); + AddInvert(frame); +} + +void ac::ImageAlphaBlendSubFilter(cv::Mat &frame) { + if(blend_set == false || subfilter == -1 || ac::draw_strings[subfilter] == "ImageAlphaBlendSubFilter") + return; + static double alpha = 1.0, alpha_max = 4.0; + cv::Mat reimage; + cv::resize(blend_image, reimage, frame.size()); + CallFilter(subfilter, reimage); + cv::Mat copy1 = frame.clone(); + AlphaBlend(copy1, reimage, frame, alpha); + static int dir = 1; + procPos(dir, alpha, alpha_max, 4.1, 0.01); + AddInvert(frame); +} + +void ac::MultipleMatrixCollectionSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "MultipleMatrixCollectionSubFilter") + return; + static MatrixCollection<16> collection; + static MatrixCollection<16> filter_collection; + static MatrixCollection<16> fcollection; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + CallFilter(subfilter, copy1); + Smooth(copy1, &filter_collection); + Smooth(copy2, &collection); + AlphaBlend(copy1, copy2, frame, 0.5); + Smooth(frame, &fcollection); + MedianBlend(frame); + AddInvert(frame); +} + +// use MedianBlend as Subfilter for cool efffect +void ac::BlurAlphaSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "BlurAlphaSubFilter") + return; + static MatrixCollection<8> collection1,collection2; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + CallFilter(subfilter, copy1); + Smooth(copy1, &collection1); + Smooth(copy2, &collection2); + AlphaBlend(copy1, copy2, frame, 0.5); + CallFilter(subfilter, frame); + AddInvert(frame); +} + +void ac::BlurImageSubFilter(cv::Mat &frame) { + if(blend_set == false || subfilter == -1 || ac::draw_strings[subfilter] == "BlurImageSubFilter") + return; + static MatrixCollection<8> collection1, collection2, collection3; + cv::Mat copy1 = frame.clone(), reimage; + cv::resize(blend_image, reimage, frame.size()); + CallFilter(subfilter, copy1); + CallFilter(subfilter, reimage); + Smooth(copy1, &collection1); + Smooth(reimage, &collection2); + AlphaBlend(copy1, reimage, frame, 0.5); + Smooth(frame, &collection3); + AddInvert(frame); +} + +void ac::MedianBlendSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "MedianBlendSubFilter") + return; + static MatrixCollection<8> collection; + int r = 3+(rand()%3); + for(int i = 0; i < r; ++i) + MedianBlur(frame); + CallFilter(subfilter, frame); + cv::Mat copy1 = frame.clone(); + collection.shiftFrames(frame); + MatrixBlend(frame, &collection); + cv::Mat copy2 = frame.clone(); + AlphaBlend(copy1, copy2, frame, 0.5); + AddInvert(frame); +} + +void ac::MedianBlendImageSubFilter(cv::Mat &frame) { + if(blend_set == false || subfilter == -1 || ac::draw_strings[subfilter] == "MedianBlendImageSubFilter") + return; + static MatrixCollection<8> collection; + int r = 3+(rand()%3); + for(int i = 0; i < r; ++i) + MedianBlur(frame); + cv::Mat reimage; + cv::resize(blend_image, reimage, frame.size()); + CallFilter(subfilter, reimage); + CallFilter(subfilter, frame); + collection.shiftFrames(frame); + MatrixBlend(frame, &collection); + cv::Mat copy1 = frame.clone(); + AlphaBlend(copy1, reimage, frame, 0.5); + AddInvert(frame); +} + +void ac::MedianBlendSelfBlend(cv::Mat &frame) { + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + MedianBlend(copy1); + AlphaBlend(copy1, copy2, frame, 0.5); + AddInvert(frame); +} + +void ac::BlendHalfSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "BlendHalfSubFilter") + return; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + CallFilter(subfilter, copy1); + AlphaBlend(copy1, copy2, frame, 0.5); + AddInvert(frame); +} + +void ac::BlurImageAlphaBlend(cv::Mat &frame) { + if(blend_set == false) + return; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + cv::Mat reimage; + cv::resize(blend_image, reimage, frame.size()); + int r = 3+(rand()%3); + for(int j = 0; j < r; ++j) { + MedianBlur(copy1); + MedianBlur(reimage); + } + AlphaBlend(copy1, reimage, frame, 0.5); + AddInvert(frame); +} + +void ac::BlurImageAlphaBlendSubFilter(cv::Mat &frame) { + if(blend_set == false || subfilter == -1 || ac::draw_strings[subfilter] == "BlurImageAlphaBlendSubFilter") + return; + cv::Mat reimage, copy1 = frame.clone(); + cv::resize(blend_image, reimage, frame.size()); + int r = 3+(rand()%3); + for(int j = 0; j < r; ++j) { + MedianBlur(copy1); + MedianBlur(reimage); + } + CallFilter(subfilter, copy1); + CallFilter(subfilter, reimage); + AlphaBlend(copy1, reimage, frame, 0.5); + AddInvert(frame); +} + +void ac::BlurImageAlphaBlendScaleSubFilter(cv::Mat &frame) { + if(blend_set == false || subfilter == -1 || ac::draw_strings[subfilter] == "BlurImageAlphaBlendScaleSubFilter") + return; + cv::Mat reimage, copy1 = frame.clone(); + cv::resize(blend_image, reimage, frame.size()); + int r = 3+(rand()%3); + for(int j = 0; j < r; ++j) { + MedianBlur(copy1); + MedianBlur(reimage); + } + CallFilter(subfilter, copy1); + CallFilter(subfilter, reimage); + double alpha = 1.0, alpha_max = 4.0; + static int dir = 1; + AlphaBlend(copy1, reimage, frame, alpha); + procPos(dir, alpha, alpha_max, 4.1, 0.01); + AddInvert(frame); +} + +void ac::RandomAmountOfMedianBlur(cv::Mat &frame) { + int r = 1+(rand()%5); + for(int j = 0; j < r; ++j) + MedianBlur(frame); + AddInvert(frame); +} + +void ac::Bitwise_XOR_BlendFrame(cv::Mat &frame) { + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + Bitwise_XOR(copy1); + AlphaBlend(copy1, copy2, frame, 0.5); + AddInvert(frame); +} + +void ac::AlphaBlendWithSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "AlphaBlendWithSubFilter") + return; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + CallFilter(subfilter, copy1); + AlphaBlend(copy1, copy2, frame, 0.5); + AddInvert(frame); +} + +void ac::AlphaBlendScaleWithSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "AlphaBlendScaleWithSubFilter") + return; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + CallFilter(subfilter, copy1); + static double alpha = 1.0, alpha_max = 3.0; + static int dir = 1; + AlphaBlend(copy1, copy2, frame, alpha); + procPos(dir, alpha, alpha_max, 3.1, 0.01); + AddInvert(frame); +} + +void ac::GaussianBlendEx(cv::Mat &frame) { + static MatrixCollection<8> collection; + int r = 3+(rand()%3); + for(int i = 0; i < r; ++i) + GaussianBlur(frame); + collection.shiftFrames(frame); + MatrixBlend(frame, &collection); + AddInvert(frame); +} + +void ac::SimpleMatrixBlend(cv::Mat &frame) { + static MatrixCollection<8> collection; + collection.shiftFrames(frame); + MatrixBlend(frame, &collection); + AddInvert(frame); +} + +void ac::MatrixBlendSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "MatrixBlendSubFilter") + return; + static MatrixCollection<8> collection; + CallFilter(subfilter, frame); + collection.shiftFrames(frame); + MatrixBlend(frame, &collection); + AddInvert(frame); +} + +void ac::SmoothMatrixBlendSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "SmoothMatrixBlendSubFilter") + return; + static MatrixCollection<8> collection1, collection2; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + Smooth(copy1, &collection1); + CallFilter(subfilter, copy1); + for(int i = 0; i < 3; ++i) + MedianBlur(copy2); + CallFilter(subfilter, copy2); + collection2.shiftFrames(copy2); + MatrixBlend(copy2, &collection2); + AlphaBlend(copy1, copy2, frame, 0.5); + AddInvert(frame); +} + +void ac::BlurSmoothSubFilterAlphaBlend(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "BlurSmoothSubFilter") + return; + static MatrixCollection<8> collection; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + CallFilter(subfilter, copy1); + AlphaBlend(copy1, copy2, frame, 0.5); + Smooth(frame, &collection); + AddInvert(frame); +} + +void ac::BlurSmoothAlphaXorBlendSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "BlurSmoothAlphaXorBlendSubFilter") + return; + static MatrixCollection<8> collection; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + CallFilter(subfilter, copy1); + AlphaXorBlend(copy1, copy2, frame, 0.5); + Smooth(frame, &collection); + AddInvert(frame); +} + +void ac::BlurTwiceSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "BlurTwiceSubFilter") + return; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + for(int i = 0; i < 3; ++i) { + MedianBlur(copy1); + GaussianBlur(copy2); + } + CallFilter(subfilter, copy1); + CallFilter(subfilter, copy2); + AlphaBlend(copy1, copy2, frame, 0.5); + AddInvert(frame); +} + +void ac::BlurFrameBlendSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "BlurFrameBlendSubFilter") + return; + static int index = 0; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + for(int i = 0; i < 3; ++i) { + if(index == 0) { + MedianBlur(copy1); + GaussianBlur(copy2); + } else { + MedianBlur(copy2); + GaussianBlur(copy1); + } + } + ++index; + if(index > 1) + index = 0; + CallFilter(subfilter, copy2); + AlphaBlend(copy1, copy2, frame, 0.5); + AddInvert(frame); +} + +void ac::BlurFrameSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "BlurFrameSubFilter") + return; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + for(int i = 0; i < 3; ++i) { + MedianBlur(copy1); + } + static MatrixCollection<8> collection; + Smooth(copy1, &collection); + CallFilter(subfilter, copy2); + AlphaBlend(copy1, copy2, frame, 0.5); + AddInvert(frame); +} + +void ac::BlurSmoothMatrix(cv::Mat &frame) { + static MatrixCollection<16> collection; + GaussianBlur(frame); + MedianBlur(frame); + Smooth(frame, &collection); + AddInvert(frame); +} + +void ac::MedianBlurInc(cv::Mat &frame) { + int fps = static_cast(ac::fps); + static int dir = 1; + static int offset = 1, frame_counter = 1; + + for(int i = 0; i < offset; ++i) + MedianBlur(frame); + + if((frame_counter%fps) == 0) { + if(dir == 1) { + ++offset; + if(offset > 8) { + dir = 0; + } + } else { + --offset; + if(offset <= 1) { + dir = 1; + } + } + } + ++frame_counter; + AddInvert(frame); +} + +void ac::GaussianBlurInc(cv::Mat &frame) { + int fps = static_cast(ac::fps); + static int dir = 1; + static int offset = 1, frame_counter = 1; + + for(int i = 0; i < offset; ++i) + GaussianBlur(frame); + + if((frame_counter%fps) == 0) { + if(dir == 1) { + ++offset; + if(offset > 8) { + dir = 0; + } + } else { + --offset; + if(offset <= 1) { + dir = 1; + } + } + } + ++frame_counter; + AddInvert(frame); +} + +void ac::BlurSmoothMedianInc(cv::Mat &frame) { + static MatrixCollection<16> collection; + MedianBlurInc(frame); + Smooth(frame, &collection); + AddInvert(frame); +} + +void ac::BlurSmoothGaussianInc(cv::Mat &frame) { + static MatrixCollection<16> collection; + GaussianBlurInc(frame); + Smooth(frame, &collection); + AddInvert(frame); +} + +void ac::BlurMatrixCollectionXor(cv::Mat &frame) { + static MatrixCollection<8> collection; + cv::Mat copy1 = frame.clone(); + MedianBlurInc(copy1); + Smooth(copy1, &collection); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Scalar values; + for(int q = 0; q < collection.size(); ++q) { + cv::Vec3b pix = collection.frames[q].at(z, i); + for(int j = 0; j < 3; ++j) + values[j] += pix[j]; + } + cv::Vec3b cpix = copy1.at(z, i); + for(int j = 0; j < 3; ++j) { + values[j] /= 3; + int val = static_cast(values[j]); + pixel[j] = (val^cpix[j])^pixel[j]; + } + } + } + AddInvert(frame); +} + +void ac::MatrixCollection8XorSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "MatrixCollection8XorSubFilter") + return; + static MatrixCollection<8> collection; + cv::Mat copy1 = frame.clone(); + CallFilter(subfilter, copy1); + Smooth(copy1, &collection); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Scalar values; + cv::Vec3b &pixel = frame.at(z, i); + for(int q = 0; q < collection.size(); ++q) { + cv::Vec3b pix = collection.frames[q].at(z, i); + for(int j = 0; j < 3; ++j) + values[j] += pix[j]; + } + for(int j = 0; j < 3; ++j) { + values[j] /= collection.size(); + int value = static_cast(values[j]); + pixel[j] = pixel[j]^value; + } + } + } + cv::Mat copy2 = frame.clone(); + AlphaBlend(copy1, copy2, frame, 0.5); + AddInvert(frame); +} + +void ac::BlurSmoothRevFilter(cv::Mat &frame) { + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + BlurSmoothMatrix(copy1); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix[4]; + pix[0] = pixel; + pix[1] = copy1.at(z, frame.cols-i-1); + pix[2] = copy1.at(frame.rows-z-1, i); + pix[3] = copy1.at(frame.rows-z-1, frame.cols-i-1); + cv::Scalar values; + for(int q = 0; q < 4; ++q) { + for(int j = 0; j < 3; ++j) + values[j] += pix[q][j]; + } + for(int j = 0; j < 3; ++j) { + values[j] /= 3; + int value = static_cast(values[j]); + pixel[j] = pixel[j]^value; + } + } + } + AddInvert(frame); +} + +void ac::SurroundingPixels(cv::Mat &frame) { + cv::Mat copy1 = frame.clone(); + for(int z = 0; z < frame.rows-1; ++z) { + for(int i = 0; i < frame.cols-1; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix[4]; + pix[0] = pixel; + pix[1] = copy1.at(z, i+1); + pix[2] = copy1.at(z+1, i); + pix[3] = copy1.at(z+1, i+1); + cv::Scalar values; + for(int q = 0; q < 4; ++q) { + for(int j = 0; j < 3; ++j) { + values[j] += pix[q][j]; + } + } + for(int j = 0; j < 3; ++j) { + values[j] /= 4; + int value = static_cast(values[j]); + pixel[j] = pixel[j]^value; + } + } + } + AddInvert(frame); +} + +void ac::SurroundingPixelsAlpha(cv::Mat &frame) { + double alpha = 1.0, alpha_max = 4.0; + cv::Mat copy1 = frame.clone(); + for(int z = 0; z < frame.rows-1; ++z) { + for(int i = 0; i < frame.cols-1; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix[4]; + pix[0] = pixel; + pix[1] = copy1.at(z, i+1); + pix[2] = copy1.at(z+1, i); + pix[3] = copy1.at(z+1, i+1); + cv::Scalar values; + for(int q = 0; q < 4; ++q) { + for(int j = 0; j < 3; ++j) { + values[j] += pix[q][j]; + } + } + for(int j = 0; j < 3; ++j) { + values[j] /= 3; + pixel[j] = static_cast(pixel[j]*(alpha+1))+static_cast(values[j]*alpha); + } + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 4.1, 0.01); + AddInvert(frame); +} + +void ac::MatrixCollectionSurroundingPixels(cv::Mat &frame) { + static MatrixCollection<32> collection; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + for(int z = 0; z < frame.rows-1; ++z) { + for(int i = 0; i < frame.cols-1; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix[4]; + pix[0] = pixel; + pix[1] = copy1.at(z, i+1); + pix[2] = copy1.at(z+1, i); + pix[3] = copy1.at(z+1, i+1); + cv::Scalar values; + for(int q = 0; q < 4; ++q) { + for(int j = 0; j < 3; ++j) { + values[j] += pix[q][j]; + } + } + for(int j = 0; j < 3; ++j) { + values[j] /= 4; + int value = static_cast(values[j]); + pixel[j] = pixel[j]^value; + } + } + } + Smooth(frame, &collection); + MedianBlend(frame); + cv::Mat copy3 = frame.clone(); + AlphaBlend(copy2, copy3, frame, 0.5); + AddInvert(frame); +} + + +void ac::MatrixCollectionSurroundingPixelsSubFilter(cv::Mat &frame) { + static MatrixCollection<32> collection; + if(subfilter == -1 || ac::draw_strings[subfilter] == "MatrixCollectionSurroundingPixelsSubFilter") + return; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + for(int z = 0; z < frame.rows-1; ++z) { + for(int i = 0; i < frame.cols-1; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix[4]; + pix[0] = pixel; + pix[1] = copy1.at(z, i+1); + pix[2] = copy1.at(z+1, i); + pix[3] = copy1.at(z+1, i+1); + cv::Scalar values; + for(int q = 0; q < 4; ++q) { + for(int j = 0; j < 3; ++j) { + values[j] += pix[q][j]; + } + } + for(int j = 0; j < 3; ++j) { + values[j] /= 4; + int value = static_cast(values[j]); + pixel[j] = pixel[j]^value; + } + } + } + CallFilter(subfilter, frame); + Smooth(frame, &collection); + MedianBlend(frame); + cv::Mat copy3 = frame.clone(); + AlphaBlend(copy2, copy3, frame, 0.5); + AddInvert(frame); +} + +void ac::MatrixCollectionSurroundingPixelsImage(cv::Mat &frame) { + if(blend_set == false) + return; + static MatrixCollection<32> collection; + cv::Mat reimage; + cv::resize(blend_image, reimage, frame.size()); + cv::Mat copyx = frame.clone(); + AlphaBlend(copyx, reimage, frame, 0.5); + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + for(int z = 0; z < frame.rows-1; ++z) { + for(int i = 0; i < frame.cols-1; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix[4]; + pix[0] = pixel; + pix[1] = copy1.at(z, i+1); + pix[2] = copy1.at(z+1, i); + pix[3] = copy1.at(z+1, i+1); + cv::Scalar values; + for(int q = 0; q < 4; ++q) { + for(int j = 0; j < 3; ++j) { + values[j] += pix[q][j]; + } + } + for(int j = 0; j < 3; ++j) { + values[j] /= 4; + int value = static_cast(values[j]); + pixel[j] = pixel[j]^value; + } + } + } + cv::Mat copy3 = frame.clone(); + AlphaBlend(copy2, copy3, frame, 0.5); + AddInvert(frame); +} + +void ac::MatrixCollectionSurroundingPixelsImageSubFilter(cv::Mat &frame) { + if(blend_set == false || subfilter == -1 || ac::draw_strings[subfilter] == "MatrixCollectionSurroundingPixelsImageSubFilter") + return; + static MatrixCollection<16> collection; + cv::Mat reimage; + cv::resize(blend_image, reimage, frame.size()); + cv::Mat copyx = frame.clone(); + CallFilter(subfilter, copyx); + AlphaBlend(copyx, reimage, frame, 0.5); + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + for(int z = 0; z < frame.rows-1; ++z) { + for(int i = 0; i < frame.cols-1; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix[4]; + pix[0] = pixel; + pix[1] = copy1.at(z, i+1); + pix[2] = copy1.at(z+1, i); + pix[3] = copy1.at(z+1, i+1); + cv::Scalar values; + for(int q = 0; q < 4; ++q) { + for(int j = 0; j < 3; ++j) { + values[j] += pix[q][j]; + } + } + for(int j = 0; j < 3; ++j) { + values[j] /= 4; + int value = static_cast(values[j]); + pixel[j] = pixel[j]^value; + } + } + } + cv::Mat copy3 = frame.clone(); + AlphaBlend(copy2, copy3, frame, 0.5); + AddInvert(frame); +} + +void ac::ImageTransparent(cv::Mat &frame) { + if(blend_set == false) + return; + cv::Mat copy1 = frame.clone(), reimage, copy2 = frame.clone(); + cv::resize(blend_image, reimage, copy1.size()); + AlphaBlend(copy1, reimage, frame, 0.5); + static MatrixCollection<8> collection; + Smooth(frame, &collection); + cv::Mat cp1 = frame.clone(); + AlphaBlend(cp1, copy2, frame, 0.5); + AddInvert(frame); +} + +void ac::MatrixImageAlphaBlendSubFilter(cv::Mat &frame) { + if(blend_set == false || subfilter == -1 || ac::draw_strings[subfilter] == "ImageSubFilter1") + return; + cv::Mat copy1 = frame.clone(), copy2, reimage; + cv::resize(blend_image, reimage, frame.size()); + CallFilter(subfilter, reimage); + AlphaBlend(copy1, reimage, copy2, 0.5); + static MatrixCollection<8> collection; + Smooth(copy2, &collection); + AlphaBlend(copy1, copy2, frame, 0.5); + CallFilter(subfilter, frame); +} + +void ac::ImageAlphaCollectionSmoothBlend(cv::Mat &frame) { + if(blend_set == false) + return; + static MatrixCollection<8> collection; + cv::Mat copy1 = frame.clone(), reimage, copy2; + cv::resize(blend_image, reimage, frame.size()); + AlphaBlend(copy1, reimage, copy2, 0.8); + Smooth(copy2, &collection); + AlphaBlend(copy1, copy2, frame, 0.5); + static MatrixCollection<8> collection2; + Smooth(frame, &collection2); + AddInvert(frame); +} + +void ac::ImageRandomColormap(cv::Mat &frame) { + if(blend_set == false) + return; + cv::Mat copy1; + cv::resize(blend_image, copy1, frame.size()); + ShuffleColorMap(copy1); + frame = copy1.clone(); + AddInvert(frame); +} + +void ac::ImageRandomColormapAlphaBlend(cv::Mat &frame) { + if(blend_set == false) + return; + cv::Mat copy1 = frame.clone(), copyimg; + cv::resize(blend_image, copyimg, frame.size()); + ShuffleColorMap(copyimg); + AlphaBlend(copy1, copyimg, frame, 0.5); + AddInvert(frame); +} + +void ac::ImageRandomColormapAlphaScale(cv::Mat &frame) { + if(blend_set == false) + return; + static double alpha = 1.0, alpha_max = 4.0; + cv::Mat copy1 = frame.clone(), copyimg; + cv::resize(blend_image, copyimg, frame.size()); + ShuffleColorMap(copyimg); + AlphaBlend(copy1, copyimg, frame, alpha); + AddInvert(frame); + static int dir = 1; + procPos(dir, alpha, alpha_max, 4.1, 0.01); +} + +void ac::ImageRandomColormapSubFilter(cv::Mat &frame) { + if(blend_set == false || subfilter == -1 || ac::draw_strings[subfilter] == "ImageRandomColormapSubFilter") + return; + cv::Mat copy1 = frame.clone(), copyimg; + cv::resize(blend_image, copyimg, frame.size()); + CallFilter(subfilter, copyimg); + ShuffleColorMap(copyimg); + AlphaBlend(copy1, copyimg, frame, 0.5); + AddInvert(frame); +} + +void ac::ImageShuffle(cv::Mat &frame) { + if(blend_set == false) + return; + cv::Mat imgcopy; + cv::resize(blend_image, imgcopy, frame.size()); + randomFilter(imgcopy); + frame = imgcopy.clone(); + AddInvert(frame); +} + +void ac::ImageSubFilter(cv::Mat &frame) { + if(blend_set == false || subfilter == -1 || ac::draw_strings[subfilter] == "ImageSubFilter") + return; + cv::Mat reimage; + cv::resize(blend_image, reimage, frame.size()); + CallFilter(subfilter, reimage); + frame = reimage.clone(); + AddInvert(frame); +} + +void ac::ImageAlphaBlendWithFrameSubFilter(cv::Mat &frame) { + if(blend_set == false || subfilter == -1 || ac::draw_strings[subfilter] == "ImageAlphaBlendWithFrameSubFilter") + return; + cv::Mat copy1 = frame.clone(), reimage; + cv::resize(blend_image, reimage, frame.size()); + CallFilter(subfilter, reimage); + AlphaBlend(copy1, reimage, frame, 0.5); + AddInvert(frame); +} + +void ac::ImageFadeInOut(cv::Mat &frame) { + if(blend_set == false) + return; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(), reimage; + cv::resize(blend_image, reimage, frame.size()); + static MatrixCollection<8> collection; + static double alpha = 1.0, alpha_max = 4.0; + AlphaBlendDouble(copy1, reimage, copy2, 1.0, alpha); + Smooth(copy2, &collection); + static int dir = 1; + procPos(dir, alpha, alpha_max, 4.1, 0.01); + AlphaBlendDouble(copy1, copy2, frame, 0.3, 0.8); + AddInvert(frame); +} + +void ac::ImageFadeBlackInOut(cv::Mat &frame) { + if(blend_set == false) + return; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(), reimage; + cv::resize(blend_image, reimage, frame.size()); + static double alpha = 1.0; + AlphaBlendDouble(copy1, reimage, frame, 1.0, alpha); + static int dir = 1; + AlphaMovementMaxMin(alpha, dir, 0.01, 1.0, 0.1); + AddInvert(frame); +} + + +void ac::ImageFadeBlackInOutSubFilter(cv::Mat &frame) { + if(blend_set == false || subfilter == -1 || ac::draw_strings[subfilter] == "ImageFadeBlackInOutSubFilter") + return; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(), reimage; + cv::resize(blend_image, reimage, frame.size()); + ImageFadeBlackInOut(copy1); + CallFilter(subfilter, copy1); + static double alpha = 1.0; + AlphaBlendDouble(copy2, copy1, frame, 1.0, alpha); + static int dir = 1; + AlphaMovementMaxMin(alpha, dir, 0.01, 1.0, 0.1); + AddInvert(frame); +} + +void ac::ImageFadeFrameInOut(cv::Mat &frame) { + if(blend_set == false) + return; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(), reimage; + cv::resize(blend_image, reimage, frame.size()); + static double alpha = 1.0; + AlphaBlendDouble(copy1, reimage, frame, alpha, 1.0); + static int dir = 1; + AlphaMovementMaxMin(alpha, dir, 0.01, 1.0, 0.1); + AddInvert(frame); +} + + +void ac::ImageFadeFrameInOutSubFilter(cv::Mat &frame) { + if(blend_set == false || subfilter == -1 || ac::draw_strings[subfilter] == "ImageFadeFrameInOutSubFilter") + return; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(), reimage; + cv::resize(blend_image, reimage, frame.size()); + CallFilter(subfilter, reimage); + static double alpha = 1.0; + AlphaBlendDouble(copy1, reimage, frame, alpha, 1.0); + static int dir = 1; + AlphaMovementMaxMin(alpha, dir, 0.01, 1.0, 0.1); + AddInvert(frame); +} + +void ac::ImageFadeDouble(cv::Mat &frame) { + if(blend_set == false) + return; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(), reimage; + cv::resize(blend_image, reimage, frame.size()); + static double alpha1 = 1.0, alpha2 = 1.0; + AlphaBlendDouble(copy1, reimage, frame, alpha1, alpha2); + static int dir1 = 1, dir2 = 0; + AlphaMovementMaxMin(alpha1, dir1, 0.01, 1.0, 0.1); + AlphaMovementMaxMin(alpha2, dir2, 0.05, 1.0, 0.1); + AddInvert(frame); +} + + +void ac::BlendSubFilterAndImage(cv::Mat &frame) { + if(blend_set == false || subfilter == -1 || ac::draw_strings[subfilter] == "BlendSubFilterAndImage") + return; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(), reimage; + cv::resize(blend_image, reimage, frame.size()); + static double alpha1 = 0.1, alpha2 = 1.0; + static int dir1 = 1, dir2 = 0; + AlphaMovementMaxMin(alpha1, dir1, 0.01, 1.5, 0.1); + AlphaMovementMaxMin(alpha2, dir2, 0.05, 1.5, 0.1); + CallFilter(subfilter, copy1); + AlphaBlendDouble(copy1, reimage, frame, alpha1, alpha2); + AddInvert(frame); +} + +void ac::FadeSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "FadeSubFilter") + return; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + CallFilter(subfilter, copy2); + static double alpha1 = 0.1, alpha2 = 1.0; + static int dir1 = 1, dir2 = 0; + AlphaMovementMaxMin(alpha1, dir1, 0.01, 1.0, 0.1); + AlphaMovementMaxMin(alpha2, dir2, 0.01, 1.0, 0.1); + AlphaBlendDouble(copy1, copy2, frame, alpha1, alpha2); + AddInvert(frame); +} + +void ac::FadeSubFilterRev(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "FadeSubFilterRev") + return; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + DarkenFilter(copy1); + DarkenFilter(copy1); + CallFilter(subfilter, copy1); + static double alpha1 = 0.1, alpha2 = 1.0; + static int dir1 = 1, dir2 = 0; + AlphaMovementMaxMin(alpha1, dir1, 0.01, 1.0, 0.1); + AlphaMovementMaxMin(alpha2, dir2, 0.01, 1.0, 0.1); + AlphaBlendDouble(copy1, copy2, frame, alpha1, alpha2); + AddInvert(frame); +} + +void ac::ImageBlendSubFilterMedianBlend(cv::Mat &frame) { + if(blend_set == false || subfilter == -1 || ac::draw_strings[subfilter] == "ImageBlendSubFilterMedianBlend") + return; + DarkenFilter(frame); + DarkenFilter(frame); + BlendSubFilterAndImage(frame); + BlendWithSource(frame); + BlendWithSource(frame); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::FadeSubFilterXor(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "FadeSubFilterXor") + return; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + CallFilter(subfilter, copy2); + static double alpha1 = 1.1, alpha2 = 4.0; + static int dir1 = 1, dir2 = 0; + AlphaMovementMaxMin(alpha1, dir1, 0.01, 4.0, 1.1); + AlphaMovementMaxMin(alpha2, dir2, 0.05, 4.0, 1.1); + AlphaXorBlendDouble(copy1, copy2, frame, alpha1, alpha2); + AddInvert(frame); +} diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter16.cpp b/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter16.cpp new file mode 100755 index 0000000..9c90452 --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter16.cpp @@ -0,0 +1,1154 @@ +/* + * Software written by Jared Bruni https://github.com/lostjared + + This software is dedicated to all the people that experience mental illness. + + Website: http://lostsidedead.com + YouTube: http://youtube.com/LostSideDead + Instagram: http://instagram.com/jaredbruni + Twitter: http://twitter.com/jaredbruni + Facebook: http://facebook.com/LostSideDead0x + + You can use this program free of charge and redistrubute it online as long + as you do not charge anything for this program. This program is meant to be + 100% free. + + BSD 2-Clause License + + Copyright (c) 2019, Jared Bruni + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + */ + +#include "ac.h" + +void ac::BlurXorSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "BlurXorSubFilter") + return; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + for(int i = 0; i < 3; ++i) { + MedianBlur(copy1); + MedianBlur(copy2); + } + CallFilter(subfilter, copy1); + static double alpha1 = 2.0, alpha2 = 6.0; + static int dir1 = 0, dir2 = 1; + AlphaMovementMaxMin(alpha1, dir1, 0.01, 6.0, 2.0); + AlphaMovementMaxMin(alpha2, dir2, 0.1, 6.0, 2.0); + AlphaXorBlendDouble(copy1, copy2, frame, alpha1, alpha2); + AddInvert(frame); +} + + +void ac::ColorFlashIncrease(cv::Mat &frame) { + static unsigned int max_value = 2; + cv::Vec3b value(rand()%max_value, rand()%max_value, rand()%max_value); + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + MedianBlur(copy1); + MedianBlur(copy1); + MedianBlur(copy1); + DarkenFilter(copy1); + DarkenFilter(copy1); + for(int z = 0; z < copy2.rows; ++z) { + for(int i = 0; i < copy2.cols; ++i) { + cv::Vec3b &pixel = copy2.at(z, i); + cv::Vec3b pix = copy1.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = pixel[j]^value[j]^pix[j]; + } + } + } + static int dir = 1; + if(dir == 1) { + ++max_value; + if(max_value >= 255) + dir = 0; + } else { + --max_value; + if(max_value <= 1) + dir = 1; + } + static double alpha1 = 0.1, alpha2 = 1.0; + static int dir1 = 1, dir2 = 0; + AlphaMovementMaxMin(alpha1, dir1, 0.01, 1.0, 0.1); + AlphaMovementMaxMin(alpha2, dir2, 0.01, 1.0, 0.1); + AlphaBlendDouble(copy1, copy2, frame, alpha1, alpha2); + AddInvert(frame); +} + +void ac::ScaleFilter(cv::Mat &frame) { + static double amt = 0.1; + static int dir = 1; + PixelScaleAlpha(frame, amt); + AlphaMovementMaxMin(amt, dir, 0.01, 1.0, 0.1); +} + +void ac::NegativeDarkenXor(cv::Mat &frame) { + cv::Mat copy1 = frame.clone(); + static double alpha1 = 1.0; + static int dir = 1; + MedianBlur(copy1); + MedianBlur(copy1); + DarkenFilter(copy1); + DarkenFilter(copy1); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = copy1.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = pixel[j]^static_cast((-pix[j])*alpha1); + } + } + } + AlphaMovementMaxMin(alpha1, dir, 0.1, 6.0, 1.0); + AddInvert(frame); +} + +void ac::ImageXor_SubFilter(cv::Mat &frame) { + if(blend_set == false || subfilter == -1 || ac::draw_strings[subfilter] == "ImageXor_SubFilter") + return; + cv::Mat copy1 = frame.clone(), reimage; + cv::resize(blend_image, reimage, frame.size()); + Negate(copy1); + CallFilter(subfilter, copy1); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix1 = reimage.at(z, i); + cv::Vec3b pix2 = copy1.at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] = pix1[j]^pix2[j]^pixel[j]; + } + } + AddInvert(frame); +} + +void ac::NegateBlendSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "NegateBlendSubFilter") + return; + static double alpha1 = 1.0, alpha2 = 3.0; + static int dir1 = 1, dir2 = 0; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + Negate(copy2); + CallFilter(subfilter, copy2); + AlphaBlendDouble(copy1, copy2, frame, alpha1, alpha2); + AlphaMovementMaxMin(alpha1, dir1, 0.08, 4.0, 1.0); + AlphaMovementMaxMin(alpha2, dir2, 0.08, 4.0, 1.0); + AddInvert(frame); +} + +void ac::StrobeNegatePixel(cv::Mat &frame) { + static int index = 0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + pixel[index] = ~pixel[index]; + } + } + ++index; + if(index > 2) + index = 0; + AddInvert(frame); +} + +void ac::StrobeNegateInOut(cv::Mat &frame) { + static int dir = 1; + static int index = 0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + pixel[index] = ~pixel[index]; + } + } + if(dir == 1) { + ++index; + if(index > 2) { + dir = 0; + index = 2; + } + } else { + --index; + if(index < 0) { + dir = 1; + index = 0; + } + } + AddInvert(frame); +} + +void ac::ImageStrobeOnOff(cv::Mat &frame) { + if(blend_set == false) + return; + cv::Mat copy1 = frame.clone(), reimage; + cv::resize(blend_image, reimage, frame.size()); + static int index = 0; + if(index == 0) { + Negate(reimage); + index = 1; + } else { + Negate(copy1); + index = 0; + } + AlphaBlend(copy1, reimage, frame, 0.5); + AddInvert(frame); +} + +void ac::AlphaStrobeBlend(cv::Mat &frame) { + static double alpha = 1.0; + static int index = 0; + static int dir_v = 1; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = static_cast(pixel[j]*(alpha+1)); + } + pixel[index] = ~pixel[index]; + } + } + static int dir = 1; + if(dir == 1) { + ++index; + if(index > 2) { + dir = 0; + index = 2; + } + } else { + --index; + if(index < 0) { + dir = 1; + index = 0; + } + } + AlphaMovementMaxMin(alpha, dir_v, 0.1, 3.0, 1.0); + AddInvert(frame); + +} + +void ac::CannyRandomPixels(cv::Mat &frame) { + Canny(frame); + cv::Vec3b r(100+rand()%155, 100+rand()%155, 100+rand()%155); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + if(pixel[0] == 255 && pixel[1] == 255 && pixel[2] == 255) { + pixel = r; + } + } + } + AddInvert(frame); +} + +void ac::FrameImageFadeInOut(cv::Mat &frame) { + if(blend_set == false) + return; + static double alpha1 = 1.0; + static int dir1 = 1; + cv::Mat copy1 = frame.clone(), reimage; + cv::resize(blend_image, reimage, frame.size()); + AlphaMovementMaxMin(alpha1, dir1, 0.01, 3.0, 1.0); + AlphaBlendDouble(copy1, reimage, frame, alpha1, 0.5); + AddInvert(frame); +} + +void ac::FrameImageFadeInOutDouble(cv::Mat &frame) { + if(blend_set == false) + return; + cv::Mat copy1 = frame.clone(), reimage; + cv::resize(blend_image, reimage, frame.size()); + static double alpha1 = 1.0, alpha2 = 4.0; + static int dir1 = 1, dir2 = 0; + AlphaMovementMaxMin(alpha1, dir1, 0.05, 4.0, 1.0); + AlphaMovementMaxMin(alpha2, dir2, 0.01, 4.0, 1.0); + AlphaBlendDouble(copy1, reimage, frame, alpha1, alpha2); +} + +// todo: change every 1 second +void ac::ChangeEachSecond(cv::Mat &frame) { + static std::vector filter_array {"Self AlphaBlend","ScanAlphaSwitch", "Dual_SelfAlphaRainbow","BlendAlphaXor","SmoothTrailsSelfAlphaBlend","SelfAlphaRGB","XorAlpha","SelfAlphaScale", "SelfScaleAlpha","DarkSelfAlpha", "RGB Shift", "RGB Sep", "SlideRGB", "GradientRGB", "FrameBlendRGB", "MoveRGB", "LineRGB", "PixelRGB", "RGBFlash", "MirrorRGB", "RGBStatic1", "RGBStatic2", "SelfAlphaRGB", "CycleShiftRGB", "CycleShiftRandomRGB", "CycleShiftRandomRGB_XorBlend", "RGBVerticalXor", "RGBVerticalXorScale", "RGBHorizontalXor", "RGBHorizontalXorScale", "RGBMirror", "RGBTrails", "RGBTrailsDark", "RGBTrailsAlpha", "RGBTrailsNegativeAlpha", "MovementRGBTrails", "RGBTrailsXor", "ShadeRGB", "Self AlphaBlend", "Self Scale", "ReinterpSelfScale", "Dual_SelfAlphaRainbow", "Dual_SelfAlphaBlur","SelfXorScale", "SelfAlphaRGB", "GradientXorSelfScale", "SelfXorBlend", "SelfXorDoubleFlash", "SelfOrDoubleFlash", "SelfXorAverage", "SelfAlphaScale", "SelfScaleAlpha", "SelfAlphaScaleBlend", "SelfScaleXorIncrease", "DarkSelfAlpha", "ShuffleColorMap"}; + static int index = 0; + static unsigned int frame_counter = 0; + if(frame_counter == 0) { + std::sort(filter_array.begin(), filter_array.end()); + } + unsigned int frames_per_second = static_cast(ac::fps); + ++frame_counter; + if((frame_counter%frames_per_second)==0) { + ++index; + if(index > filter_array.size()) + index = 0; + } + CallFilter(filter_array[index], frame); + AddInvert(frame); +} + +void ac::ShuffleImage(cv::Mat &frame) { + static std::vector filter_array { "ImageXor", "ImageAlphaBlend", "ImageInter", "ImageX", "SmoothRandomImageBlend", "SmoothImageAlphaBlend", "BlendImageOnOff", "XorSelfAlphaImage", "ImageShiftUpLeft", "AlphaBlendImageXor", "BlendImageXor","BlendImageAround_Median","ImageBlendTransform","ImageXorAlpha","ImageAverageXor","DarkImageMedianBlend","MirrorAlphaBlendedImage","AlphaBlendXorImage","ImageXorFrame","ImageXorFunction","ImageXorAlphaBlend","ImageXorMirrorFilter","ImageSubtractMedianBlend","ImageDarkBlend","ImageAverageDark","ImageRemainderPixel","ParticleReleaseWithImage","ImageEnergy","ImageDistortion","SmoothExactImageXorAlpha","SmoothImageAlphaBlendMedian","ImageDarkenSmoothMedian","XorReverseImageSmooth","ImageSmoothMedianBlend","ImageAlphaXorMedianBlend","RotateImage","RotateBlendImage","RotateAlphaBlendImage","ImageXorScale","MatrixCollectionBlurImageXorAlpha", "BlurImageAlphaBlend", "MatrixCollectionSurroundingPixelsImage", "ImageTransparent", "ImageAlphaCollectionSmoothBlend", "ImageRandomColormap", "ImageRandomColormapAlphaBlend", "ImageRandomColormapAlphaScale", "ImageShuffle", "ImageFadeInOut", "ImageFadeBlackInOut", "ImageFadeFrameInOut", "ImageFadeDouble", "ImageStrobeOnOff", "FrameImageFadeInOut", "FrameImageFadeInOutDouble"}; + static int index = 0; + Shuffle(index, frame, filter_array); + AddInvert(frame); +} + +void ac::ChangeImageEachSecond(cv::Mat &frame) { + static std::vector filter_array { "ImageXor", "ImageAlphaBlend", "ImageInter", "ImageX", "SmoothRandomImageBlend", "SmoothImageAlphaBlend", "BlendImageOnOff", "XorSelfAlphaImage", "ImageShiftUpLeft", "AlphaBlendImageXor", "BlendImageXor","BlendImageAround_Median","ImageBlendTransform","ImageXorAlpha","ImageAverageXor","DarkImageMedianBlend","MirrorAlphaBlendedImage","AlphaBlendXorImage","ImageXorFrame","ImageXorFunction","ImageXorAlphaBlend","ImageXorMirrorFilter","ImageSubtractMedianBlend","ImageDarkBlend","ImageAverageDark","ImageRemainderPixel","ParticleReleaseWithImage","ImageEnergy","ImageDistortion","SmoothExactImageXorAlpha","SmoothImageAlphaBlendMedian","ImageDarkenSmoothMedian","XorReverseImageSmooth","ImageSmoothMedianBlend","ImageAlphaXorMedianBlend","RotateImage","RotateBlendImage","RotateAlphaBlendImage","ImageXorScale","MatrixCollectionBlurImageXorAlpha", "BlurImageAlphaBlend", "MatrixCollectionSurroundingPixelsImage", "ImageTransparent", "ImageAlphaCollectionSmoothBlend", "ImageRandomColormap", "ImageRandomColormapAlphaBlend", "ImageRandomColormapAlphaScale", "ImageShuffle", "ImageFadeInOut", "ImageFadeBlackInOut", "ImageFadeFrameInOut", "ImageFadeDouble", "ImageStrobeOnOff", "FrameImageFadeInOut", "FrameImageFadeInOutDouble"}; + static unsigned int counter = 0; + int fps_val = static_cast(ac::fps); + static int index = 0; + static auto rng = std::default_random_engine{}; + CallFilter(filter_array[index], frame); + ++counter; + if((counter%fps_val) == 0) { + ++index; + if(index > filter_array.size()-1) { + index = 0; + std::shuffle(filter_array.begin(), filter_array.end(),rng); + } + } + AddInvert(frame); +} + +void ac::ChangeImageFilterOnOff(cv::Mat &frame) { + if(blend_set == false) + return; + static int index = 0; + if(index == 0) { + index = 1; + ChangeImageEachSecond(frame); + } else { + index = 0; + ChangeEachSecond(frame); + } + AddInvert(frame); +} + +void ac::ChangeXorEachSecond(cv::Mat &frame) { + static auto rng = std::default_random_engine{}; + static std::vector filter_array {"XorMultiBlend", "XorSine", "TrailsFilterXor","XorAddMul", "SurroundPixelXor", "BlendAlphaXor", "SelfXorScale", "BitwiseXorScale", "XorTrails", "BitwiseXorStrobe", "RandomXorFlash", "SoftXor", "SelfXorBlend", "SelfXorDoubleFlash","XorBackwards", "MatrixXorAnd", "XorAlpha", "SelfXorAverage","AndOrXorStrobe", "AndOrXorStrobeScale","MedianBlurXor", "StaticXorBlend", "XorScale", "PixelReverseXor", "PixelXorBlend", "RainbowXorBlend", "StrobeXor", "SelfScaleXorIncrease","PixelByPixelXor", "CopyXorAlpha", "AveragePixelsXor","StrobeXorAndOr"}; + static unsigned int counter = 0; + + if(counter == 0) { + std::shuffle(filter_array.begin(), filter_array.end(),rng); + } + + int fps_val = static_cast(ac::fps); + static int index = 0; + CallFilter(filter_array[index], frame); + ++counter; + if((counter%fps_val) == 0) { + ++index; + if(index > filter_array.size()-1) { + index = 0; + std::shuffle(filter_array.begin(), filter_array.end(),rng); + } + } + AddInvert(frame); +} + +void ac::MorphXor(cv::Mat &frame) { + static MatrixCollection<32> collection; + ChangeXorEachSecond(frame); + Smooth(frame, &collection); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::MorphXorWithSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "MorphXorWithSubFilter") + return; + static MatrixCollection<32> collection; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + CallFilter(subfilter, copy1); + ChangeXorEachSecond(copy2); + AlphaBlend(copy1, copy2, frame, 0.5); + Smooth(frame, &collection); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::MirrorEachSecond(cv::Mat &frame) { + static auto rng = std::default_random_engine{}; + static std::vector filter_array {"MirrorBlend", "Sideways Mirror", "Mirror No Blend", "Mirror Average", "Mirror Average Mix", "Soft_Mirror", "InterMirror", "InterFullMirror", "MirrorRGB", "RGBMirror", "MirrorStrobe","MirrorXor", "MirrorXorAll", "MirrorXorScale", "EnergyMirror", "MirrorXorAlpha", "IntertwinedMirror", "BlurredMirror", "MirrorMedianBlend", "FlipMirror", "FlipMirrorAverage","ReverseMirrorX", "MirrorXorAll_Reverse", "MirrorRGBReverse", "MirrorRGBReverseBlend", "MirrorBitwiseXor", "BlurMirrorGamma", "EnergyMirrorDark", "AlphaBlendMirror", "TwistedMirror", "MirrorMedian","SmoothMirrorBlurFlip", "MirrorOrder", "BlurMirrorOrder", "MirrorOrderAlpha", "SoftFeedbackMirror", "MirrorAlphaBlend","MirrorBlendFrame", "MirrorBlendVertical", "MirrorVerticalAndHorizontal", "MirrorSidesMedian"}; + static unsigned int counter = 0; + if(counter == 0) { + std::shuffle(filter_array.begin(), filter_array.end(),rng); + } + int fps_val = static_cast(ac::fps); + static int index = 0; + CallFilter(filter_array[index], frame); + ++counter; + if((counter%fps_val) == 0) { + ++index; + if(index > filter_array.size()-1) { + index = 0; + std::shuffle(filter_array.begin(), filter_array.end(),rng); + } + } + AddInvert(frame); +} + +void ac::MirrorReverseSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "MirrorReverseSubFilter") + return; + cv::Mat copy1 = frame.clone(), copy2; + cv::flip(frame, copy2, 0); + CallFilter(subfilter, copy1); + MirrorEachSecond(copy2); + AlphaBlend(copy1, copy2, frame, 0.5); + AddInvert(frame); +} + +void ac::MirrorReverseSubFilterAlphaBlend(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "MirrorReverseSubFilter") + return; + static MatrixCollection<32> collection; + cv::Mat copy1 = frame.clone(), copy2; + cv::flip(frame, copy2, 0); + CallFilter(subfilter, copy1); + MirrorEachSecond(copy2); + static double alpha = 1.0; + static int dir = 1; + AlphaMovementMaxMin(alpha, dir, 0.05, 3.0, 1.0); + AlphaBlend(copy1, copy2, frame, alpha); + Smooth(frame, &collection); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::Mirror_Xor_Combined(cv::Mat &frame) { + DarkenFilter(frame); + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + static MatrixCollection<32> collection; + MirrorEachSecond(copy1); + ChangeXorEachSecond(copy2); + static double alpha = 1.0; + static int dir = 1; + AlphaMovementMaxMin(alpha, dir, 0.05, 3.0, 1.0); + AlphaBlend(copy1, copy2, frame, alpha); + Smooth(frame, &collection); + BlendWithSource(frame); + BlendWithSource(frame); + BlendWithSource(frame); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::MirrorFrameShuffle(cv::Mat &frame) { + static auto rng = std::default_random_engine{}; + static std::vector filter_array {"MirrorBlend", "Sideways Mirror", "Mirror No Blend", "Mirror Average", "Mirror Average Mix", "Soft_Mirror", "InterMirror", "InterFullMirror", "MirrorRGB", "RGBMirror", "MirrorStrobe","MirrorXor", "MirrorXorAll", "MirrorXorScale", "EnergyMirror", "MirrorXorAlpha", "IntertwinedMirror", "BlurredMirror", "MirrorMedianBlend", "FlipMirror", "FlipMirrorAverage","ReverseMirrorX", "MirrorXorAll_Reverse", "MirrorRGBReverse", "MirrorRGBReverseBlend", "MirrorBitwiseXor", "BlurMirrorGamma", "EnergyMirrorDark", "AlphaBlendMirror", "TwistedMirror", "MirrorMedian","SmoothMirrorBlurFlip", "MirrorOrder", "BlurMirrorOrder", "MirrorOrderAlpha", "SoftFeedbackMirror", "MirrorAlphaBlend","MirrorBlendFrame", "MirrorBlendVertical", "MirrorVerticalAndHorizontal", "MirrorSidesMedian"}; + static int init = 0; + if(init == 0) { + std::shuffle(filter_array.begin(), filter_array.end(), rng); + init = 1; + } static int index = 0; + CallFilter(filter_array[index], frame); + ++index; + if(index > filter_array.size()-1) { + index = 0; + std::shuffle(filter_array.begin(), filter_array.end(),rng); + } + AddInvert(frame); +} + +void ac::MirrorShuffleSmooth(cv::Mat &frame) { + static MatrixCollection<64> collection; + MirrorFrameShuffle(frame); + Smooth(frame, &collection); + AddInvert(frame); +} + +void ac::Mirror_Xor_Smooth(cv::Mat &frame) { + static MatrixCollection<16> collection; + static double alpha = 1.0; + static int dir = 1; + cv::Mat copy1 = frame.clone(); + cv::Mat copy2 = frame.clone(); + MirrorFrameShuffle(copy1); + XorFrameShuffle(copy2); + collection.shiftFrames(copy1); + collection.shiftFrames(copy2); + Smooth(frame, &collection, false); + AlphaMovementMaxMin(alpha, dir, 0.005, 4.0, 1.0); + AddInvert(frame); + +} + +void ac::XorFrameShuffle(cv::Mat &frame) { + static auto rng = std::default_random_engine{}; + static std::vector filter_array {"XorMultiBlend", "XorSine", "TrailsFilterXor","XorAddMul", "SurroundPixelXor", "BlendAlphaXor", "SelfXorScale", "BitwiseXorScale", "XorTrails", "SoftXor", "SelfXorBlend","XorBackwards", "MatrixXorAnd", "XorAlpha", "SelfXorAverage","AndOrXorStrobe", "AndOrXorStrobeScale","MedianBlurXor", "StaticXorBlend", "XorScale", "PixelReverseXor", "PixelXorBlend", "RainbowXorBlend", "StrobeXor", "SelfScaleXorIncrease","CopyXorAlpha","AveragePixelsXor","StrobeXorAndOr"}; + static unsigned int index = 0; + static int init = 0; + if(init == 0) { + std::shuffle(filter_array.begin(), filter_array.end(), rng); + init = 1; + } + CallFilter(filter_array[index], frame); + ++index; + if(index > filter_array.size()-1) { + index = 0; + std::shuffle(filter_array.begin(), filter_array.end(),rng); + } + AddInvert(frame); +} + +void ac::XorMirrorBlendFrame(cv::Mat &frame) { + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + XorFrameShuffle(copy1); + MirrorFrameShuffle(copy2); + AlphaBlend(copy1, copy2, frame, 0.5); + AddInvert(frame); +} + +void ac::ImageXorSmooth(cv::Mat &frame) { + if(blend_set == false) + return; + static MatrixCollection<32> collection1, collection2; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + ShuffleImage(copy1); + XorFrameShuffle(copy2); + Smooth(copy1, &collection1); + Smooth(copy2, &collection2); + AlphaBlend(copy1, copy2, frame, 0.5); + AddInvert(frame); +} + +void ac::SmoothSubFilter64(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "SmoothSubFilter64") + return; + static MatrixCollection<64> collection; + cv::Mat frame_copy = frame.clone(); + CallFilter(subfilter, frame_copy); + collection.shiftFrames(frame_copy); + Smooth(frame, &collection, false); + AddInvert(frame); +} + +void ac::SmoothMedian64(cv::Mat &frame) { + static MatrixCollection<64> collection; + Smooth(frame, &collection); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::SmoothMedian32_SubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "SmoothMedian32_SubFilter") + return; + static MatrixCollection<32> collection1, collection2; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + CallFilter(subfilter, copy1); + Smooth(copy1, &collection1); + Smooth(copy2, &collection2); + AlphaBlend(copy1, copy2, frame, 0.5); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::SmoothAlphaMedian_SubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "SmoothAlphaMedian_SubFilter") + return; + static MatrixCollection<32> collection1, collection2; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + CallFilter(subfilter, copy1); + Smooth(copy1, &collection1); + Smooth(copy2, &collection2); + static double alpha1 = 0.5, alpha2 = 3.0; + static int dir1 = 1, dir2 = 0; + AlphaBlendDouble(copy1, copy2, frame, alpha1, alpha2); + AlphaMovementMaxMin(alpha1, dir1, 0.01, 3.0, 0.5); + AlphaMovementMaxMin(alpha2, dir2, 0.01, 3.0, 0.5); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::SmoothImage_SubFilter(cv::Mat &frame) { + if(blend_set == false || subfilter == -1 || ac::draw_strings[subfilter] == "SmoothImage_SubFilter") + return; + static MatrixCollection<32> collection1, collection2; + cv::Mat copy1 = frame.clone(), reimage; + cv::resize(blend_image, reimage, frame.size()); + Smooth(copy1, &collection1); + CallFilter(subfilter, reimage); + Smooth(reimage, &collection2); + AlphaBlend(copy1, reimage, frame, 0.5); + AddInvert(frame); +} + +void ac::SmoothImageMedian_SubFilter(cv::Mat &frame) { + if(blend_set == false || subfilter == -1 || ac::draw_strings[subfilter] == "SmoothImageMedian_SubFilter") + return; + static MatrixCollection<8> collection1, collection2; + cv::Mat copy1 = frame.clone(), reimage; + cv::resize(frame, reimage, frame.size()); + CallFilter(subfilter, reimage); + SmoothRGB(reimage, &collection1); + CallFilter(subfilter, copy1); + Smooth(copy1, &collection2); + AlphaBlend(copy1, reimage, frame, 0.5); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::SmoothImageAndSubFilter(cv::Mat &frame) { + if(blend_set == false || subfilter == -1 || ac::draw_strings[subfilter] == "SmoothImageAndSubFilter") + return; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(), copy3, reimage; + cv::resize(blend_image, reimage, frame.size()); + static MatrixCollection<16> collection1, collection2, collection3; + CallFilter(subfilter, reimage); + CallFilter(subfilter, copy1); + Smooth(reimage, &collection1); + Smooth(copy1, &collection2); + Smooth(copy2, &collection3); + AlphaBlend(copy1, reimage, copy3, 0.5); + AlphaBlend(copy3, copy2, frame, 0.5); + AddInvert(frame); +} + +void ac::SmoothSubFilter90(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "SmoothSubFilter90") + return; + static MatrixCollection<90> collection; + collection.shiftFrames(frame); + CallFilter(subfilter, frame); + Smooth(frame, &collection); + AddInvert(frame); +} + +void ac::SmoothMedianImageSubFilter16(cv::Mat &frame) { + if(blend_set == false || subfilter == -1 || ac::draw_strings[subfilter] == "SmoothMedianImageSubFilter16") + return; + static MatrixCollection<16> collection1, collection2, collection3; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(), reimage, copy3; + cv::resize(blend_image, reimage, frame.size()); + CallFilter(subfilter, copy1); + CallFilter(subfilter, reimage); + Smooth(copy1, &collection1); + Smooth(reimage, &collection2); + AlphaBlend(copy1, reimage, copy3, 0.5); + CallFilter(subfilter, copy3); + Smooth(copy3, &collection3); + AlphaBlend(copy3,copy2,frame, 0.5); + AddInvert(frame); +} + +void ac::ImageNegate(cv::Mat &frame) { + if(blend_set == false) + return; + cv::Mat reimage; + cv::resize(blend_image, reimage, frame.size()); + Negate(reimage); + frame = reimage.clone(); + AddInvert(frame); +} + +void ac::ImageNegateAlphaBlend(cv::Mat &frame) { + if(blend_set == false) + return; + cv::Mat copy1 = frame.clone(), reimage; + cv::resize(blend_image, reimage, frame.size()); + Negate(reimage); + static double alpha1 = 3.0, alpha2 = 0.1; + static int dir1 = 0, dir2 = 1; + AlphaBlendDouble(copy1, reimage, frame, alpha1, alpha2); + AlphaMovementMaxMin(alpha1, dir1, 0.01, 3.0, 0.1); + AlphaMovementMaxMin(alpha2, dir2, 0.05, 3.0, 0.1); + AddInvert(frame); +} + +void ac::ImageNegateAlphaBlendSubFilter(cv::Mat &frame) { + if(blend_set == false || subfilter == -1 || ac::draw_strings[subfilter] == "ImageNegateAlphaBlendSubFilter") + return; + static MatrixCollection<16> collection1, collection2; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(), reimage; + cv::resize(blend_image, reimage, frame.size()); + CallFilter(subfilter, reimage); + Negate(reimage); + Smooth(reimage, &collection1); + Smooth(copy1, &collection2); + AlphaBlend(copy1, reimage, frame, 0.5); + AddInvert(frame); +} + +void ac::FrameNegateAlphaBlendImage(cv::Mat &frame) { + if(blend_set == false) + return; + cv::Mat copy1 = frame.clone(), reimage; + cv::resize(blend_image, reimage, frame.size()); + Negate(copy1); + static double alpha1 = 3.0, alpha2 = 0.1; + static int dir1 = 0, dir2 = 1; + AlphaBlendDouble(copy1, reimage, frame, alpha1, alpha2); + AlphaMovementMaxMin(alpha1, dir1, 0.01, 3.0, 0.1); + AlphaMovementMaxMin(alpha2, dir2, 0.05, 3.0, 0.1); + AddInvert(frame); +} + +void ac::DarkTrailsEffect(cv::Mat &frame) { + pushSubFilter(filter_map["Rainbow Blend"]); + TrailsSubFilter(frame); + popSubFilter(); + Negate(frame); + GammaDarken5(frame); + AddInvert(frame); +} + +void ac::DarkNegate(cv::Mat &frame) { + Negate(frame); + GammaDarken5(frame); + AddInvert(frame); +} + +void ac::ChannelSortMedianBlend(cv::Mat &frame) { + static MatrixCollection<16> collection1, collection2; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + ChannelSort(copy1); + Smooth(copy1, &collection1); + Smooth(copy2, &collection2); + AlphaBlend(copy1, copy2, frame, 0.5); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::MatrixCollectionMirrorDirection(cv::Mat &frame) { + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(), copy3; + MirrorFrameShuffle(copy1); + int r_dir = -1+rand()%2; + cv::flip(copy1, copy3, r_dir); + static MatrixCollection<64> collection; + collection.shiftFrames(copy2); + Smooth(copy3, &collection); + AlphaBlend(copy2, copy3, frame, 0.3); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::StrobeRandomChannel(cv::Mat &frame) { + int res = rand()%3; + static double alpha = 1.0; + static int dir = 1; + AlphaMovementMaxMin(alpha, dir, 0.1, 6.0, 1.0); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + pixel[res] = static_cast(pixel[res]*alpha); + } + } + AddInvert(frame); +} + +void ac::SplitFramesSort(cv::Mat &frame) { + static MatrixCollection<8> collection; + collection.shiftFrames(frame); + std::vector v1, v2, v3; + MirrorXorAll(frame); + rainbowBlend(collection.frames[2]); + cv::split(frame, v1); + cv::split(collection.frames[1], v2); + cv::split(collection.frames[2], v3); + cv::Mat channels[3]; + cv::Mat output; + cv::sort(v1[0], channels[0],cv::SORT_ASCENDING); + cv::sort(v2[1], channels[1],cv::SORT_ASCENDING); + cv::sort(v3[2], channels[2],cv::SORT_ASCENDING); + cv::merge(channels, 3, output); + frame = output.clone(); + AddInvert(frame); +} + +void ac::SplitFrameSortSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "SplitFrameSortSubFilter") + return; + static MatrixCollection<8> collection; + collection.shiftFrames(frame); + std::vector v1, v2, v3; + CallFilter(subfilter, frame); + cv::split(frame, v1); + cv::split(collection.frames[1], v2); + cv::split(collection.frames[2], v3); + cv::Mat channels[3]; + cv::Mat output; + cv::sort(v1[0], channels[0],cv::SORT_ASCENDING); + cv::sort(v2[1], channels[1],cv::SORT_ASCENDING); + cv::sort(v3[2], channels[2],cv::SORT_ASCENDING); + cv::merge(channels, 3, output); + frame = output.clone(); + AddInvert(frame); +} + +void ac::MedianBlend64(cv::Mat &frame) { + static MatrixCollection<64> collection; + int r = 3+rand()%7; + for(int i = 0; i < r; ++i) + MedianBlur(frame); + collection.shiftFrames(frame); + MatrixBlend(frame, &collection); + AddInvert(frame); +} + +void ac::SplitFrameFilter(cv::Mat &frame) { + static MatrixCollection<8> collection; + collection.shiftFrames(frame); + std::vector v1, v2, v3; + ColorExpand(frame); + rainbowBlend(collection.frames[1]); + RainbowXorBlend(collection.frames[2]); + cv::split(frame, v1); + cv::split(collection.frames[1], v2); + cv::split(collection.frames[2], v3); + cv::Mat channels[3]; + cv::Mat output; + cv::sort(v1[0], channels[0],cv::SORT_ASCENDING); + cv::sort(v2[1], channels[1],cv::SORT_ASCENDING); + cv::sort(v3[2], channels[2],cv::SORT_ASCENDING); + cv::merge(channels, 3, output); + frame = output.clone(); + AddInvert(frame); +} + +void ac::SplitFrameBlend(cv::Mat &frame) { + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + std::vector v1, v2, v3; + ColorXorScale(frame); + ColorExpand(copy1); + rainbowBlend(copy2); + cv::Mat channels[3]; + cv::extractChannel(frame, channels[0], 0); + cv::extractChannel(copy1, channels[1], 1); + cv::extractChannel(copy2, channels[2], 2); + cv::merge(channels, 3, frame); + AddInvert(frame); +} + +void ac::SplitFrameBlendSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "SplitFrameBlendSubFilter") + return; + cv::Mat frames[3]; + int r = rand()%3; + frames[0] = frame.clone(); + frames[1] = frame.clone(); + frames[2] = frame.clone(); + CallFilter(subfilter, frames[r]); + cv::Mat channels[3]; + cv::Mat output; + cv::extractChannel(frames[0], channels[0], 0); + cv::extractChannel(frames[1], channels[1], 1); + cv::extractChannel(frames[2], channels[2], 2); + cv::merge(channels, 3, frame); + AddInvert(frame); +} + +void ac::SplitFrameCollection(cv::Mat &frame) { + static MatrixCollection<8> collection; + collection.shiftFrames(frame); + cv::Mat frames[3]; + frames[0] = frame.clone(); + frames[1] = collection.frames[6].clone(); + frames[2] = collection.frames[7].clone(); + static int dir = 1; + if(dir == 1) { + RainbowXorBlend(frames[0]); + MedianBlend(frames[1]); + ColorXorScale(frames[2]); + dir = 0; + } else { + dir = 1; + ColorXorScale(frames[0]); + MedianBlend(frames[1]); + RainbowXorBlend(frames[2]); + } + cv::Mat channels[3]; + cv::Mat output; + cv::extractChannel(frames[0], channels[0], 0); + cv::extractChannel(frames[1], channels[1], 1); + cv::extractChannel(frames[2], channels[2], 2); + cv::merge(channels, 3, frame); + AddInvert(frame); +} + +void ac::SplitFrameMirror(cv::Mat &frame) { + cv::Mat frames[3]; + frames[0] = frame.clone(); + frames[1] = frame.clone(); + frames[2] = frame.clone(); + MirrorXorAll(frames[0]); + FlipBlendWH(frames[1]); + rainbowBlend(frames[2]); + cv::Mat channels[3]; + cv::Mat output; + static int dir = 1; + if(dir == 1) { + dir = 0; + cv::extractChannel(frames[0], channels[0], 0); + cv::extractChannel(frames[1], channels[1], 1); + cv::extractChannel(frames[2], channels[2], 2); + } else { + dir = 1; + cv::extractChannel(frames[0], channels[2], 0); + cv::extractChannel(frames[1], channels[1], 1); + cv::extractChannel(frames[2], channels[0], 2); + } + cv::merge(channels, 3, frame); + AddInvert(frame); +} + +void ac::RandomChannels(cv::Mat &frame) { + static auto rng = std::default_random_engine{}; + static std::vector selection ({"Self AlphaBlend", "Blend #3", "RandTriBlend", "Rainbow Blend", "Rand Blend", "New Blend", "MirrorBlend", "Mirror No Blend", "Blend_Angle", "XorMultiBlend", "BlendedScanLines", "FrameBlend", "FrameBlendRGB", "PrevFrameBlend", "HorizontalBlend", "VerticalBlend", "OppositeBlend", "BlendSwitch", "IncreaseBlendHorizontal", "BlendIncrease", "TrailsBlend", "BlendThree", "BlendTrails", "GridFilter8xBlend", "WeakBlend", "SmoothTrailsSelfAlphaBlend", "SmoothTrailsRainbowBlend", "MedianBlend", "RandomAlphaBlend", "RandomTwoFilterAlphaBlend", "AlphaBlendPosition", "BlendRowAlpha", "BlendRow", "BlendRowByVar", "BlendRowByDirection", "BlendAlphaXor", "AlphaBlendRandom", "ChannelSortAlphaBlend", "StrobeBlend", "GaussianBlend", "SelfXorBlend", "BlendRowCurvedSqrt", "CycleShiftRandomRGB_XorBlend", "CycleShiftRandomAlphaBlend", "MedianBlendAnimation", "ParticleBlend", "BlendInAndOut", "BlendScaleInAndOut", "RandomXorBlend", "InitBlend", "LagBlend", "RandomMirrorBlend", "RandomMirrorAlphaBlend", "RandBlend", "StaticXorBlend", "Bitwise_XOR_Blend", "Bitwise_OR_Blend", "Bitwise_AND_Blend", "SilverBlend", "PixelXorBlend", "RainbowXorBlend", "FadeBlend", "SelfAlphaScaleBlend", "ReverseFrameBlend", "ReverseFrameBlendSwitch", "RandomBlendFilter", "DoubleRandomBlendFilter", "FlipBlendW", "FlipBlendWH", "FlipBlendH", "FlipBlendAll", "Blend_RedGreenBlue", "XorBlend_RedGreenBlue", "BlendIncrease_RedGreenBlue", "Blend_RedReenBlue_Dark", "DarkModBlend", "MirrorMedianBlend", "DarkenBlend", "ChannelSort_NoBlend_Descending", "ChannelSort_NoBlend_Ascending", "BlendBurred", "BlendCombinedValues", "AlphaBlendWithSource", "RGBMedianBlend", "MirrorRGBReverseBlend", "MedianBlend16", "BGRBlend", "RGBBlend", "MedianBlendDark", "AlphaBlendMirror", "SelfScaleSortBlend", "FlashMedianBlend", "FlipAlphaBlend", "SmoothCollectionAlphaBlend", "SmoothTrailsBlend", "ShuffleAlphaMedianBlend", "AverageLinesBlend", "AverageVerticalLinesBlend", "LinesMedianBlend", "MedianBlendSoft", "ParticleReleaseAlphaBlend", "MirrorAlphaBlend", "MatrixCollectionBlend", "SmoothMedianBlend", "CosSinMedianBlend", "Filter8_Blend", "RandomAlphaBlendFilter", "MirrorBlendFrame", "MirrorBlendVertical", "BlendFor360", "MatrixCollectionSmoothAlphaBlend", "MedianBlendSelfBlend", "Bitwise_XOR_BlendFrame", "GaussianBlendEx", "SimpleMatrixBlend", "AlphaStrobeBlend", "XorMirrorBlendFrame", "ChannelSortMedianBlend", "MedianBlend64", "SplitFrameBlend"}); + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(), copy3 = frame.clone(); + static int index = 0; + if(index == 0) { + std::shuffle(selection.begin(), selection.end(), rng); + } + if(index+3 < selection.size()) { + CallFilter(selection[index], copy1); + CallFilter(selection[index+1], copy2); + CallFilter(selection[index+2], copy3); + } + index += 3; + if(index > selection.size()) + index = 0; + cv::Mat channels[3]; + cv::Mat output; + cv::extractChannel(copy1, channels[0], 0); + cv::extractChannel(copy2, channels[1], 1); + cv::extractChannel(copy3, channels[2], 2); + cv::merge(channels, 3, frame); + AddInvert(frame); +} + +void ac::SmoothRandomChannels(cv::Mat &frame) { + static MatrixCollection<16> collection1, collection2, collection3; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(), copy3 = frame.clone(); + randomFilter(copy1); + randomFilter(copy2); + randomFilter(copy3); + Smooth(copy1, &collection1); + Smooth(copy2, &collection2); + Smooth(copy3, &collection3); + cv::Mat channels[3]; + cv::Mat output; + cv::extractChannel(copy1, channels[0], 0); + cv::extractChannel(copy2, channels[1], 1); + cv::extractChannel(copy3, channels[2], 2); + cv::merge(channels, 3, frame); + AddInvert(frame); +} + +void ac::SmoothChannelSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "SmoothChannelSubFilter") + return; + static MatrixCollection<8> collection; + static int index = 0; + cv::Mat copy1 = frame.clone(); + CallFilter(subfilter, copy1); + collection.shiftFrames(copy1); + cv::Mat copies[3]; + copies[0] = collection.frames[1].clone(); + copies[1] = collection.frames[3].clone(); + copies[2] = collection.frames[6].clone(); + copies[index] = copy1.clone(); + ++index; + if(index > 2) + index = 0; + cv::Mat chan[3]; + cv::Mat output; + cv::extractChannel(copies[0], chan[0], 0); + cv::extractChannel(copies[1], chan[1], 1); + cv::extractChannel(copies[2], chan[2], 2); + cv::merge(chan, 3, frame); + AddInvert(frame); +} + +void ac::IncreaseRGB(cv::Mat &frame) { + static int index = 0; + static int max = 0; + static int speed = 5; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + pixel[index] += max; + } + } + if(max >= 255) { + ++index; + if(index > 2) + index = 0; + max = 0; + } else { + max += speed; + } + AddInvert(frame); +} + +void ac::IncreaseColor(cv::Mat &frame) { + static int index = 0; + static int max[3] = {0,50,100}; + static int speed = 5; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = pixel; + for(int j = 0; j < 3; ++j) { + pixel[j] += max[j]; + } + pixel[index] = pix[index]; + } + } + ++index; + if(index > 2) + index = 0; + for(int j = 0; j < 3; ++j) { + if(max[j] >= 255) { + max[j] = 0; + } else { + max[j] += speed; + } + } + AddInvert(frame); +} + +void ac::SaturateBlend(cv::Mat &frame) { + cv::Mat copy1 = frame.clone(); + cv::Mat copy2 = frame.clone(); + IncreaseColor(copy1); + rainbowBlend(copy2); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix[2]; + pix[0] = copy1.at(z, i); + pix[1] = copy2.at(z, i); + for(int j = 1; j < 3; ++j) { + pixel[j] = cv::saturate_cast(pixel[j]+pix[0][j]+pix[1][j]); + } + } + } + AddInvert(frame); +} + +void ac::SaturateBlendSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "SaturateBlendSubFilter") + return; + static double alpha = 1.0; + static int dir = 1; + cv::Mat copy1 = frame.clone(); + cv::Mat copy2 = frame.clone(); + IncreaseColor(copy1); + CallFilter(subfilter, copy2); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix[2]; + pix[0] = copy1.at(z, i); + pix[1] = copy2.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] ^= cv::saturate_cast((pixel[j]*alpha)+(pix[0][j]*alpha)+(pix[1][j]*alpha)); + } + } + } + AlphaMovementMaxMin(alpha, dir, 0.01, 2.5, 1.0); + AddInvert(frame); +} + +// average + +void ac::MaxRGB(cv::Mat &frame) { + static int index = 0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + pixel[index] = 255; + } + } + ++index; + if(index > 2) + index = 0; + AddInvert(frame); +} + +void ac::XorDifferenceFilter(cv::Mat &frame) { + static MatrixCollection<8> collection; + collection.shiftFrames(frame); + static int index = 0; + + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b copy_pix[8]; + for(int q = 0; q < collection.size(); ++q) { + copy_pix[q] = collection.frames[q].at(z, i); + } + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b copy_pixel = pixel; + for(int j = 0; j < 3; ++j) { + pixel[j] = copy_pix[0][j] ^ copy_pix[1][j] ^ copy_pix[2][j] ^ copy_pix[3][j] ^ copy_pix[4][j] ^ copy_pix[5][j] ^ copy_pix[6][j] ^ copy_pix[7][j] ^ pixel[j]; + } + cv::Vec3b lw(100, 100, 100); + if(colorBounds(pixel,copy_pixel,lw, lw)) { + //pixel = cv::Vec3b(0,0,0); + } else { + switch(index) { + case 0: + pixel = cv::Vec3b(0,0,255); + break; + case 1: + pixel = cv::Vec3b(0,255,0); + break; + case 2: + pixel = cv::Vec3b(255,0,0); + break; + } + } + } + } + ++index; + if(index > 2) index = 0; + AddInvert(frame); +} + +void ac::AlphaBlendChannelSort(cv::Mat &frame) { + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + SplitFrameFilter(copy2); + MedianBlend(copy2); + AlphaBlend(copy1, copy2, frame, 0.5); + AddInvert(frame); +} + + +void ac::ColorTrailsFilter(cv::Mat &frame) { + static MatrixCollection<8> collection; + SmoothRGB(frame, &collection); + AddInvert(frame); +} + + +void ac::ColorTrailsSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "ColorTrailsSubFilter") + return; + static MatrixCollection<8> collection; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + SmoothRGB(copy1, &collection); + MedianBlend(copy1); + CallFilter(subfilter, copy2); + AlphaBlend(copy1, copy2, frame, 0.5); + AddInvert(frame); +} diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter17.cpp b/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter17.cpp new file mode 100755 index 0000000..ab7ebb4 --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter17.cpp @@ -0,0 +1,157 @@ +/* + * Software written by Jared Bruni https://github.com/lostjared + + This software is dedicated to all the people that experience mental illness. + + Website: http://lostsidedead.com + YouTube: http://youtube.com/LostSideDead + Instagram: http://instagram.com/jaredbruni + Twitter: http://twitter.com/jaredbruni + Facebook: http://facebook.com/LostSideDead0x + + You can use this program free of charge and redistrubute it online as long + as you do not charge anything for this program. This program is meant to be + 100% free. + + BSD 2-Clause License + + Copyright (c) 2019, Jared Bruni + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + */ + +#include "ac.h" + +void ac::DarkNegateRainbowMedian(cv::Mat &frame) { + static MatrixCollection<8> collection1; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(); + DarkNegate(copy1); + SmoothRGB(copy1, &collection1); + rainbowBlend(copy2); + AlphaBlend(copy1, copy2, frame, 0.5); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::IncreaseQuick(cv::Mat &frame) { + static double speed = 1.0; + static double pixel_color[] = {0.1*(rand()%10), (0.1*(rand()%10)), (0.1*(rand()%10))}; + static int dir = 1, speed_dir = 1; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] += pixel[j]*pixel_color[j]; + } + } + } + for(int j = 0; j < 3; ++j) { + if(dir == 1) { + pixel_color[j] += speed; + if(pixel_color[j] >= 5) { + dir = 0; + } + } else { + pixel_color[j] -= speed; + if(pixel_color[j] <= 1.0) { + dir = 1; + } + } + } + if(speed_dir == 1) { + speed += 0.1; + if(speed > 2.0) { + speed_dir = 0; + for(int j = 0; j < 3; ++j) { + pixel_color[j] = 3.0; + } + } + } else { + speed -= 0.1; + if(speed <= 1.0) { + speed_dir = 1; + for(int j = 0; j < 3; ++j) { + pixel_color[j] = 1.0; + } + } + } +} + + +void ac::IncreaseRandomIndex(cv::Mat &frame) { + static int index = rand()%2, speed = 10; + static int colors[3] = {0,75,150}; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + pixel[index] += colors[index]; + } + } + for(int j = 0; j < 3; ++j ){ + colors[j] += speed; + if(colors[j] >= 255) { + colors[j] = 0; + ++index; + if(index > 2) + index = rand()%2; + } + } + AddInvert(frame); +} + +void ac::ImageChannelSubFilter(cv::Mat &frame) { + if(blend_set == false || subfilter == -1 || draw_strings[subfilter] == "ImageChannelSubFilter") + return; + cv::Mat copy1 = frame.clone(), copy2 = frame.clone(), reimage; + CallFilter(subfilter, copy1); + cv::resize(blend_image, reimage, frame.size()); + CallFilter(subfilter, reimage); + cv::Mat chan[3], output; + static int index = 0; + static int values[3] = {0,1,2}; + switch(index) { + case 0: + values[0] = 0; + values[1] = 1; + values[2] = 2; + break; + case 1: + values[0] = 1; + values[1] = 2; + values[2] = 0; + break; + case 2: + values[0] = 2; + values[1] = 0; + values[2] = 1; + break; + } + ++index; + if(index > 2) index = 0; + cv::extractChannel(copy1, chan[values[0]], 0); + cv::extractChannel(reimage, chan[values[1]],1); + cv::extractChannel(copy2, chan[values[2]], 2); + cv::merge(chan, 3, output); + AlphaBlend(output, copy2, frame, 0.5); +} diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter2.cpp b/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter2.cpp new file mode 100755 index 0000000..0327d65 --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter2.cpp @@ -0,0 +1,911 @@ +/* + * Software written by Jared Bruni https://github.com/lostjared + + This software is dedicated to all the people that experience mental illness. + + Website: http://lostsidedead.com + YouTube: http://youtube.com/LostSideDead + Instagram: http://instagram.com/jaredbruni + Twitter: http://twitter.com/jaredbruni + Facebook: http://facebook.com/LostSideDead0x + + You can use this program free of charge and redistrubute it online as long + as you do not charge anything for this program. This program is meant to be + 100% free. + + BSD 2-Clause License + + Copyright (c) 2019, Jared Bruni + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + */ + +#include "ac.h" + +// glitchSort +// takes cv::Mat reference +void ac::glitchSort(cv::Mat &frame) { + static double pos = 1.0f; // static pos set to 1.0 + int w = frame.cols;// frame width + int h = frame.rows;// frame height + static std::vector v;// static vector of int + v.reserve(w);// reserve at least w bytes + for(int z = 0; z < h; ++z) {// top to bottom + for(int i = 0; i < w; ++i) { // left to right + // grab current pixel value reference + cv::Vec3b &value = frame.at(z, i); + // temporary int variable + unsigned int vv = 0; + // pointer to unsigned char * of vv variable + unsigned char *cv = (unsigned char*)&vv; + // set RGB values + cv[0] = value[0]; + cv[1] = value[1]; + cv[2] = value[2]; + cv[3] = 0; + v.push_back(vv);// push back into vector + } + std::sort(v.begin(), v.end());// sort the row of pixels + for(int i = 0; i < w; ++i) {// left to right + // pointer to integer stored at index i + unsigned char *value = (unsigned char*)&v[i]; + // grab current pixel reference as cv::Vec3b + cv::Vec3b &pixel = frame.at(z, i); + // alphablend pixel with values from v at index i + pixel[0] = static_cast(pixel[0] + (pos)*value[0]); + pixel[1] = static_cast(pixel[1] + (pos)*value[1]); + pixel[2] = static_cast(pixel[2] + (pos)*value[2]); + // swap the colors + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); // if isNegative invert pixel + + } + v.erase(v.begin(), v.end());// erase pixel data + } + static double pos_max = 7.0f;// pos_max = 7.0 + static int direction = 1; + procPos(direction, pos, pos_max); +} + +// takes cv::Mat reference +void ac::pixelSort(cv::Mat &frame) { + int w = frame.cols;// frame width + int h = frame.rows;// frame height + static std::vector v;// static vector of int + v.reserve(w);// reserve w bytes + for(int z = 0; z < h; ++z) { // top to bottom + for(int i = 0; i < w; ++i) { // left to right + //int value = frame.at(z, i); + // grab pixel reference + cv::Vec3b &value = frame.at(z, i); + unsigned int vv = 0; + // unsigned char * of vv + unsigned char *cv = (unsigned char*)&vv; + // set RGB values + cv[0] = value[0]; + cv[1] = value[1]; + cv[2] = value[2]; + cv[3] = 0; + // push back into vector v + v.push_back(vv); + } + // sort vector v + std::sort(v.begin(), v.end()); + for(int i = 0; i < w; ++i) {// left to right + // unsigned char pointer of vector v at index i + unsigned char *value = (unsigned char*)&v[i]; + // get pixel reference + cv::Vec3b &pixel = frame.at(z, i); + // add to pixel without scaling + pixel[0] += value[0]; + pixel[1] += value[1]; + pixel[2] += value[2]; + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// invert pixel + } + v.erase(v.begin(), v.end()); + } +} +// preform a random filter +void ac::randomFilter(cv::Mat &frame) { + switch(rand()%5) { + case 0: + ShuffleAlpha(frame); + break; + case 1: + ShuffleRGB(frame); + break; + case 2: + ShuffleSelf(frame); + break; + case 3: + ShuffleMedian(frame); + break; + case 4: + ShuffleColorMap(frame); + break; + } +} + +void ac::randomFlash(cv::Mat &frame) { + int w = frame.cols;// frame width + int h = frame.rows;// frame height + static double pos = 1.0;// pos index + // a random red,green,blue value + int random_r = rand()%255, random_g = rand()%255, random_b = rand()%255; + // top to bottom + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) {// left to right + // get pixel reference + cv::Vec3b &pixel = frame.at(z, i); + // calculate RGB values + pixel[0] += static_cast(pos*random_r); + pixel[1] += static_cast(pos*random_g); + pixel[2] += static_cast(pos*random_b); + // swap colors + swapColors(frame, z, i); + // if isNegative true invert pixel + if(isNegative) invert(frame, z, i); + } + } + static double pos_max = 7.0f; + static int direction = 1; + procPos(direction, pos, pos_max); +} + + + +// alpha flame filters +// a collection of filters +void ac::alphaFlame(cv::Mat &frame) { + static double pos = 1.0f;// pos set to 1 + double count = 1.0f;// count set to 1 + static int i = 0, z = 0;// i,z variables + width = frame.cols;// frame width + height = frame.rows;// frame height + for(z = 0; z < frame.cols; ++z) { + for(i = 0; i < frame.rows; ++i) { + // grab pixel reference as cv::Vec3b + cv::Vec3b &buffer = frame.at(i, z); + // call change pixel function + changePixel(frame, z, i, buffer, pos, &count); + } + } + // static direction set to 1 + static int direction = 1; + if(direction == 1) {// if direction is equal to 1 + pos += 0.1f;// pos plus equal 0.1 + if(pos > 512) {// pos greater than 512 + pos = 512;// pos equal 512 + direction = 0;// direction equals 0 + } + } + else { + pos -= 0.1f; // pos minus equal 0.1 + if(pos < 1) {// if pos less than 1 + pos = 1;// pos equal 1 + direction = 1;// direction set back to 1 + } + } + resetAlpha(direction, pos); +} + +// Resize X variable +int AC_GetFX(int oldw,int x, int nw) { + float xp = (float)x * (float)oldw / (float)nw; + return (int)xp; +} +// Resize Y Variable +int AC_GetFZ(int oldh, int y, int nh) { + float yp = (float)y * (float)oldh / (float)nh; + return (int)yp; +} + + +// preform GaussianBlur +void ac::GaussianBlur(cv::Mat &frame) { + cv::Mat out; + cv::GaussianBlur(frame, out, cv::Size(5, 5), 0, 0); + frame = out.clone(); +} +// preform MedianBlur +void ac::MedianBlur(cv::Mat &frame) { + cv::Mat out; + cv::medianBlur(frame, out, 5); + frame = out.clone(); +} +// Increase / Decrease GaussianBlur +// takes cv::Mat reference +void ac::BlurDistortion(cv::Mat &frame) { + cv::Mat out;// output + static int index = 1, direction = 1; + cv::GaussianBlur(frame, out, cv::Size(index, index), 0, 0);// output + if(direction == 1) {// if direction equals 1 + if(index >= 51) direction = 0;// if greater than 51 set to zero go + // opposite direction + else index += 2;// increase + } else { + if(index <= 1) direction = 1;// go opposite direction + else index -= 2;// decrease + } + frame = out.clone();// frame equals out +} + +// Draw gradient diamonds that grow and shrink and blend with source image +// takes cv::Mat reference +void ac::DiamondPattern(cv::Mat &frame) { + static double pos = 1.0;// set pos to 1.0 + int w = frame.cols;// frame width + int h = frame.rows;// frame height + for(int z = 0; z < h; ++z) {// from top to bottom + for(int i = 0; i < w; ++i) {// from left to right + cv::Vec3b &buffer = frame.at(z, i);// get current pixel + // calculate the colors of the gradient diamonds + if((i%2) == 0) {// if i % 2 equals 0 + if((z%2) == 0) {// if z % 2 equals 0 + // set pixel component values + buffer[0] = static_cast(1-pos*buffer[0]); + buffer[2] = static_cast((i+z)*pos); + } else { + // set pixel coomponent values + buffer[0] = static_cast(pos*buffer[0]-z); + buffer[2] = static_cast((i-z)*pos); + } + } else { + if((z%2) == 0) {// if z % 2 equals 0 + // set pixel component values + buffer[0] = static_cast(pos*buffer[0]-i); + buffer[2] = static_cast((i-z)*pos); + } else { + // set pixel component values + buffer[0] = static_cast(pos*buffer[0]-z); + buffer[2] = static_cast((i+z)*pos); + } + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel + } + } + // static direction starts off with 1 + static double pos_max = 7.0f;// pos maximum + static int direction = 1; + procPos(direction, pos, pos_max); +} +// Mirror blend +// blend current pixel in loop with current pixel +// on opposite side of image (width-x), (height-y) +// then increase / decrease the pixel colors +// takes cv::Mat reference +void ac::MirrorBlend(cv::Mat &frame) { + static double pos = 1.0; // pos set to 1.0 + int w = frame.cols;// frame width + int h = frame.rows;// frame height + cv::Mat orig;// unaltered image + orig = frame.clone();// clone to orig + for(int z = 2; z < h-3; ++z) { // from top to bottom + for(int i = 2; i < w-3; ++i) {// from left to right + cv::Vec3b &buffer = frame.at(z, i); // get pixel at i,z + cv::Vec3b &pix1 = orig.at((h-z), (w-i));// get pixel at w-i, h-z + // set pixel rgb components + buffer[0] += static_cast(pix1[0]*pos); + buffer[1] += static_cast(pix1[1]*pos); + buffer[2] += static_cast(pix1[2]*pos); + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i); // invert if isNegative true + } + } + // static direction variable + static int direction = 1; + double inc_double = (alpha_increase != 0) ? alpha_increase : 0.1; + + static double pos_max = 2.0f; // position maximum + if(direction == 1) {// if direction is equal to 1 + pos += inc_double;// pos plus equal 0.1 + if(pos > pos_max) {// pos greater than pos max + pos = pos_max;// pos = pos max + direction = 0;// direction equals 0 + pos_max += 1.0f;// pos max pluse qual 1.0 + } + } else if(direction == 0) {// if direction equals zero + pos -= inc_double;// pos plus equal 0.1 + if(pos <= 1.0) {// pos less than 1.0 + if(pos_max > 2.0f) pos_max = 1.0f;// pos max greater than 2, pos_max set to 1 + direction = 1;// direction set back to 1 + } + } + resetAlpha(direction, pos); +} + +// Pulse color in and out +// takes cv::Mat reference +void ac::Pulse(cv::Mat &frame) { + static double pos = 1.0; // index + int w = frame.cols;// width variable + int h = frame.rows;// height variable + for(int z = 0; z < h; ++z) { // from top to bottom + for(int i = 0; i < w; ++i) { // from left to right + // current pixel reference cv::Vec3b + cv::Vec3b &buffer = frame.at(z, i); + // pixel rgb components plus equal multiplied by pos + buffer[0] += static_cast(buffer[0]*pos); + buffer[1] += static_cast(buffer[1]*pos); + buffer[2] += static_cast(buffer[2]*pos); + // swap colors + swapColors(frame, z, i); + // if negative variable true invert pixel + if(isNegative) invert(frame, z, i); + } + } + static int direction = 1; // current direction + static double pos_max = 3.0f; // maximum + if(direction == 1) { // direction equals 1 + pos += 0.1; // pos plus equal 0.1 + if(pos > pos_max) {// pos greater than pos max + pos = pos_max;// pos equals pox max + direction = 0; // direction is zero + pos_max += 1.0f; // pos max plus equal 1.0 + } + } else if(direction == 0) { // direction is 0 + pos -= 0.1; // pos minus equal 0.1 + if(pos <= 1.0) { // less thane equal 1 + // reset pos max + if(pos_max > 3.0f) pos_max = 1.0f; + direction = 1; // direction set to 1 + } + } + resetAlpha(direction, pos); +} + +// Sideways Mirror function +// takes reference cv::Mat (an image) +void ac::SidewaysMirror(cv::Mat &frame) { + static double pos = 1.0; + int w = frame.cols;// frame image width + int h = frame.rows;// frame image height + cv::Mat orig;// unaltered image matrix + orig = frame.clone();// clone frame to orig + for(int z = 2; z < h-3; ++z) {// loop from top to bottom + for(int i = 2; i < w-3; ++i) {// loop each row from left + // to right + // current pixel + cv::Vec3b &buffer = frame.at(z, i); + // h minus y, width minus x positioned pixel + cv::Vec3b &pix1 = orig.at((h-z), (w-i)); + // y and width minus x pixel + cv::Vec3b &pix2 = orig.at(z, (w-i)); + // current pixel compponents equal + // pix1[0] plus pix2[0] multiplied by kernel + buffer[0] += static_cast((pix1[0]+pix2[0])*pos); + // do the same for each component + buffer[1] += static_cast((pix1[1]+pix2[1])*pos); + buffer[2] += static_cast((pix1[2]+pix2[2])*pos); + // swap colors + swapColors(frame, z, i); + // if negative flag set invert frame + if(isNegative) invert(frame, z, i); + } + } + // max size + static double pos_max = 4.0f; + static int direction = 1; + procPos(direction, pos, pos_max); +} + +// Mirror function without blending +void ac::MirrorNoBlend(cv::Mat &frame) { + int w = frame.cols; // width of frame + int h = frame.rows; // height of frame + cv::Mat orig;// original image unaltered + orig = frame.clone(); // clone the frame to orig + for(int z = 2; z < h-3; ++z) { // loop through the height + for(int i = 2; i < w-3; ++i) {// go across each row + cv::Vec3b &buffer = frame.at(z, i);// current pixel + // opposite of current pixel + cv::Vec3b &pix1 = orig.at((h-z), (w-i)); + // opposite width, same height + cv::Vec3b &pix2 = orig.at(z, (w-i)); + // opposite height, same width + cv::Vec3b &pix3 = orig.at((h-z), i); + // current pixel components equal + // add each pixel value together + buffer[0] = (pix1[0]+pix2[0]+pix3[0]); + buffer[1] = (pix1[1]+pix2[1]+pix3[1]); + buffer[2] = (pix1[2]+pix2[2]+pix3[2]); + // swap RGB positions + swapColors(frame, z, i); + // if the negative switch is on, invert + if(isNegative) invert(frame, z, i); + } + } +} +// Sort the Fuzz +void ac::SortFuzz(cv::Mat &frame) { + int r = rand()%255; // random number betwen 0-254 + int w = frame.cols;// frame width + int h = frame.rows;// frame height + static std::vector v;// vector for row of bytes info + v.reserve(w);// reserve at least width bytes + for(int z = 0; z < h; ++z) { // loop: top to bottom + for(int i = 0; i < w; ++i) { // loop: left ro right + cv::Vec3b &value = frame.at(z, i); // current pixel + unsigned int vv = 0; // integer + unsigned char *cv = (unsigned char*)&vv; // pointer to unsigned char* + // set each byte + cv[0] = value[0]; + cv[1] = value[1]; + cv[2] = value[2]; + cv[3] = 0; + v.push_back(vv); // push back + } + std::sort(v.begin(), v.end());// sort greater + for(int i = 0; i < w; ++i) { // left to right + unsigned char *value = (unsigned char*)&v[i]; + cv::Vec3b &pixel = frame.at(z, i);// pixel at i,z + // pixel values plus equal value plus r + pixel[0] += static_cast(value[0]+r); + pixel[1] += static_cast(value[1]+r); + pixel[2] += static_cast(value[2]+r); + // swap colors + swapColors(frame, z, i); + // if negative variable set invert pixel + if(isNegative) invert(frame, z, i); + + } + v.erase(v.begin(), v.end()); // erase row + // repeat + } +} +// Fuzz filter +// takes cv::Mat reference +void ac::Fuzz(cv::Mat &frame) { + int w = frame.cols;// width of frame + int h = frame.rows;// height of frame + static int amount = 5; // num pixel distortion + for(int z = 0; z < h; ++z) {// loop top to bottom + for(int i = 0; i < w; ++i) { // loop from left ro gith + if((rand()%amount)==1) {// if random is true + cv::Vec3b &pixel = frame.at(z, i);// grab pixel + pixel[0] += rand()%255;// add random numbers + pixel[1] += rand()%255; + pixel[2] += rand()%255; + } + // swap colors + swapColors(frame, z, i); + // if negative invert pixel + if(isNegative) invert(frame, z, i); + } + } + // direction equals 1 to start + static int direction = 1; + if(direction == 1) {// if direction equals 1 + ++amount; // increase amount + if(amount >= 10) direction = 0; // greater than ten lower to zero + } else { + --amount;// decrease amount + if(amount <= 5) direction = 1;// less than five direction equals 1 + } +} + +// Double vision +// takes cv::Mat by refrence +void ac::DoubleVision(cv::Mat &frame) { + static double pos = 1.0; // index + int w = frame.cols;// frame width + int h = frame.rows;// frame height + cv::Mat orig = frame.clone(); // clone frame to orig + for(int z = 3; z < h-3; ++z) {// top to bottom + for(int i = 3; i < w-3; ++i) { // left to right + // current pixel + cv::Vec3b &buffer = frame.at(z, i); + cv::Vec3b &g = orig.at((h-z), i); // pixel at h-y, x + cv::Vec3b &b = orig.at(z, (w-i)); // pixel at y, w-x + // this is what gives the diamond image + if((i%2) == 0) {// if modulus i by two returns zero + if((z%2) == 0) {// modulus z by two returns zero + buffer[2] += static_cast((i+z)*pos);// buffer[2] plus equals (i plus z) multiplied by pos + } else { + buffer[2] += static_cast((i-z)*pos); // buffer[2] plus equals (i minus z) mulitplied by pos + } + } else { + if((z%2) == 0) {// modulus z by two equals zero + buffer[2] += static_cast((i-z)*pos); // buffer[2] plus equals (i minus z) multiplied by pos + } else { + buffer[2] += static_cast((i+z)*pos); // buffer[2] plus equals (i plus z) multiplied by pos + } + } + // this is what adds the rgb from other positions + buffer[0] += g[0]; + buffer[1] += b[1]; + // swap colors + swapColors(frame, z, i); + // if negative variable set invert pixel + if(isNegative) invert(frame, z, i); + } + } + // static int direction + // pos max + static double pos_max = 7.0f; + static int direction = 1; + procPos(direction, pos, pos_max); +} +// RGB Shift +// takes cv::Mat reference +void ac::RGBShift(cv::Mat &frame) { + int w = frame.cols; // frame width + int h = frame.rows;// frame height + cv::Mat orig = frame.clone();// clone frame to orig + static int shift = 0;// shift equals 0 + for(int z = 3; z < h-3; ++z) {// top to bottom + for(int i = 3; i < w-3; ++i) {// left to right + // grab pixel values + cv::Vec3b &buffer = frame.at(z, i); + cv::Vec3b &g = orig.at((h-z), i); + cv::Vec3b &b = orig.at(z, (w-i)); + cv::Vec3b &r = orig.at((h-z), (w-i)); + // switch shift, each state preforms addition on different + // pixel component values + switch(shift) { + case 0: + buffer[0] += r[0]; + buffer[1] += g[1]; + buffer[2] += b[2]; + case 1: + buffer[0] += g[0]; + buffer[1] += b[1]; + buffer[2] += r[2]; + break; + case 2: + buffer[0] += b[0]; + buffer[1] += r[1]; + buffer[2] += g[2]; + break; + } + swapColors(frame, z, i);// swap the colors + if(isNegative) invert(frame, z, i);// invert current pixel + } + } + ++shift;// increase shift + if(shift > 2) shift = 0;// shift greater than two reset shift +} +// RGB Seperation +// takes cv::Mat +void ac::RGBSep(cv::Mat &frame) { + int w = frame.cols;// frame width + int h = frame.rows;// frame height + cv::Mat orig = frame.clone();// orig is clone of frame + for(int z = 3; z < h-3; ++z) {// top to bottom + for(int i = 3; i < w-3; ++i) {// left to right + // grab pixel values + cv::Vec3b &buffer = frame.at(z, i); + cv::Vec3b &g = orig.at((h-z), i); + cv::Vec3b &b = orig.at(z, (w-i)); + // set pixel values + buffer[0] += g[0]; + buffer[2] += b[2]; + swapColors(frame, z, i); // swap colors + if(isNegative) invert(frame, z, i); // invert pixel + } + } +} +// Gradient Rainbow +// takes cv::Mat reference +void ac::GradientRainbow(cv::Mat &frame) { + int w = frame.cols;// frame width + int h = frame.rows;// frame height + // start color double + double start_color = (1+(rand()%255))* 0.5; + + for(int z = 0; z < h; ++z) { // top to bottom + for(int i = 0; i < w; ++i) {// left to right + // reference to current pixel + cv::Vec3b &pixel = frame.at(z, i); + // color RGB variables + int color_R = static_cast(start_color * 4), color_G = static_cast(start_color * 6), color_B = static_cast(start_color * 8); + // add to pixel color + pixel[0] += static_cast(color_R); + pixel[1] += static_cast(color_G); + pixel[2] += static_cast(color_B); + // swap colors + swapColors(frame, z, i); + // if isNegative true invert pixel + if(isNegative) invert(frame, z, i); + } + start_color += 0.1;// increase start_color + } +} +// Flash +// takes cv::Mat +void ac::GradientRainbowFlash(cv::Mat &frame) { + int w = frame.cols;// frame width + int h = frame.rows;// frame height + static double pos = 0.1; + static int shift = 0; + // start color double + double start_color = (1+(rand()%255)) * pos; + for(int z = 0; z < h; ++z) { // top to bottom + for(int i = 0; i < w; ++i) {// left to right + // reference to current pixel + cv::Vec3b &pixel = frame.at(z, i); + // color RGB variables + int color_R = static_cast(start_color * 4), color_G = static_cast(start_color * 6), color_B = static_cast(start_color * 8); + // add to pixel colors + pixel[2] += static_cast(color_R); + pixel[1] += static_cast(color_G); + pixel[0] += static_cast(color_B); + // flash + if(shift == 0) { + pixel[2] = ~pixel[2]; + pixel[1] = ~pixel[1]; + pixel[0] = ~pixel[0]; + } + + // swap colors + swapColors(frame, z, i); + // if isNegative true invert pixel + if(isNegative) invert(frame, z, i); + } + start_color += 0.050;// increase start_color + } + shift = !shift; + // static int direction + static int direction = 1; + // pos max + // if direction equals 1 + if(direction == 1) { + pos += 0.05; // pos plus equal 0.05 + if(pos > 1.0) { // if pos > pos max + pos = 1.0; + direction = 0;// direction equals 0 + } + } else if(direction == 0) {// direction equals 1 + pos -= 0.05;// pos -= 0.05 + if(pos <= 0.1) {// if pos <= 1.0 + // set to 1.0 + direction = 1;// set direction back to 1 + pos = 0.1; + } + } + resetAlpha(direction, pos); +} +// Reverse Frame +// takes cv::Mat reference +void ac::Reverse(cv::Mat &frame) { + cv::Mat output;//output matrix + cv::flip(frame, output, 1); // flip image + frame = output.clone(); // set frame to output +} +// Scanlines - Draws scanlines like a CRT. +void ac::Scanlines(cv::Mat &frame) { + int w = frame.cols;// width + int h = frame.rows;// height + for(int z = 0; z < h; z += 2) {// top to bottom step by 2 + for(int i = 0; i < w; ++i) {// left to right + cv::Vec3b &pix = frame.at(z, i);// current pixel + pix[0] = pix[1] = pix[2] = 0;// set to zero + } + } +} +// Random Pixels +void ac::TVStatic(cv::Mat &frame) { + int w = frame.cols;// frame width + int h = frame.rows;// frame height + static int dir = 0; + for(int z = dir; z < h; z += 2) {// top to bottom step by 2 pixels + for(int i = 0; i < w; ++i) {// left to right + cv::Vec3b &pix = frame.at(z, i);// current pixel + if(rand()%2>0) { + pix[0] = pix[1] = pix[2] = 0; + } else { + pix[0] = pix[1] = pix[2] = 255; + } + } + } + ++dir; + if(dir >= 2) dir = 0; +} +// Mirror Average +// takes cv::Mat reference +void ac::MirrorAverage(cv::Mat &frame) { + int w = frame.cols;// frame width + int h = frame.rows;// frame height + cv::Mat orig = frame.clone(); // clone original frame (make a copy) + static double pos = 1.0f; // current index + for(int z = 1; z < h-1; ++z) { // top to bottom + for(int i = 1; i < w-1; ++i) {// left to right + // refernce to current pixel located at i,z + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b mir_pix[3]; // array of Vec3b variables + mir_pix[0] = orig.at((h-z), (w-i)); // pixel at w-i, h-z + mir_pix[1] = orig.at((h-z), i); // pixel at i, h-z + mir_pix[2] = orig.at(z,(w-i)); // pixel at w-i, z + // take each component from mir_pix and find the average + // with the same index from each variable in the mir_pix array + // then multiply it by the position index (pos) then add it + // to current pixel + pixel[0] += static_cast(((mir_pix[0][0]+mir_pix[1][0]+mir_pix[2][0])/3)*pos); + pixel[1] += static_cast(((mir_pix[0][1]+mir_pix[1][1]+mir_pix[2][1])/3)*pos); + pixel[2] += static_cast(((mir_pix[0][2]+mir_pix[1][2]+mir_pix[2][2])/3)*pos); + + // swap colors + swapColors(frame, z, i); + // if isNegative true invert pixel + if(isNegative) invert(frame, z, i); + } + } + // move up and down the color scale + + static double pos_max = 7.0; + static int direction = 1; + procPos(direction, pos, pos_max); +} +// Mirror Average Mix +// Takes cv::Mat matrix +void ac::MirrorAverageMix(cv::Mat &frame) { + int w = frame.cols;// frame width + int h = frame.rows;// frame height + cv::Mat orig = frame.clone(); // clone original frame + static double pos = 1.0; // position index floating point + for(int z = 1; z < h-1; ++z) { // loop from top to bottom + for(int i = 1; i < w-1; ++i) { // loop from left to right + cv::Vec3b &pixel = frame.at(z, i); // current pixel at i,z + cv::Vec3b mir_pix[3]; // array of 3 cv::Vec3b vectors + mir_pix[0] = orig.at((h-z), (w-i)); // pixel at w-i, h-z + mir_pix[1] = orig.at((h-z), i); // pixel at i, h-z + mir_pix[2] = orig.at(z,(w-i)); // pixel at w-i, z + // take each pixel and average together mulitply by pos + // and add its value to different components in + // pixel reference vector + pixel[0] += static_cast(((mir_pix[0][0]+mir_pix[0][1]+mir_pix[0][2])/3)*pos); + pixel[1] += static_cast(((mir_pix[1][0]+mir_pix[1][1]+mir_pix[1][2])/3)*pos); + pixel[2] += static_cast(((mir_pix[2][0]+mir_pix[2][1]+mir_pix[2][2])/3)*pos); + // swap colors + swapColors(frame, z, i); + // if isNegative true invert pixel + if(isNegative) invert(frame, z, i); + } + } + // pos max + static double pos_max = 7.0; + static int direction = 1; + procPos(direction, pos, pos_max); +} +// Mean takes cv::Mat reference +void ac::Mean(cv::Mat &frame) { + static double pos = 1.0; // position index floating point + int w = frame.cols;// frame width + int h = frame.rows;// frame height + cv::Scalar s = cv::mean(frame); + for(int z = 0; z < h; ++z) { // from top to bottom + for(int i = 0; i < w; ++i) {// from left to right + cv::Vec3b &pixel = frame.at(z, i); // pixel at (i,z) + // add to pixel values + pixel[0] += static_cast(pos*s[0]); + pixel[1] += static_cast(pos*s[1]); + pixel[2] += static_cast(pos*s[2]); + swapColors(frame, z, i); + // if isNegative true invert pixel + if(isNegative) invert(frame, z, i); + } + } + // position movement + static double pos_max = 7.0; + static int direction = 1; + procPos(direction, pos, pos_max); +} + +// Laplacian - takes cv::Mat reference +void ac::Laplacian(cv::Mat &frame) { + cv::Mat out; + cv::Laplacian(frame, out, CV_8U); + frame = out.clone(); + AddInvert(frame); +} + +// XOR - takes cv::Mat reference +void ac::Bitwise_XOR(cv::Mat &frame) { + static cv::Mat initial;// set initial frame + if(reset_filter == true || frames_released == true || initial.empty() || (initial.size() != frame.size())) { + initial = frame.clone(); // did frame resize? if so set the new frame value + reset_filter = false; + } + cv::Mat start = frame.clone(); // clone frame (make a copy) + cv::Mat output = frame.clone();// output variable + cv::bitwise_xor(frame, initial, output); // OpenCV function bitwise_and + initial = start.clone();// set initial to start + frame = output.clone(); // set frame to output + AddInvert(frame); +} + +// And takes cv::Mat reference +void ac::Bitwise_AND(cv::Mat &frame) { + static cv::Mat initial;// set initial frame + if(reset_filter == true || frames_released == true || initial.empty() || (initial.size() != frame.size())) { + initial = frame.clone(); // did frame resize? if so set the new frame value + reset_filter = false; + } + cv::Mat start = frame.clone(); // clone frame (make a copy) + cv::Mat output = frame.clone();// output variable + cv::bitwise_and(frame, initial, output); // OpenCV function bitwise_and + initial = start.clone();// set initial to start + frame = output.clone(); // set frame to output + AddInvert(frame); +} +// takes cv::Mat reference +void ac::Bitwise_OR(cv::Mat &frame) { + static cv::Mat initial;// set initial frame + if(reset_filter == true || frames_released == true || initial.empty() || (initial.size() != frame.size())) { + initial = frame.clone(); // did frame resize? if so set the new frame value + reset_filter = false; + } + cv::Mat start = frame.clone(); // clone frame (make a copy) + cv::Mat output = frame.clone();// output variable + cv::bitwise_or(frame, initial, output); // OpenCV function bitwise_and + initial = start.clone();// set initial to start + frame = output.clone(); // set frame to output + AddInvert(frame); +} +// takes cv::Mat reference +// Equalize image +void ac::Equalize(cv::Mat &frame) { + cv::Mat output[3]; // array of cv::Mat + std::vector v; // vector to hold cv::Mat values + cv::split(frame, v);// split b,g,r values + cv::equalizeHist(v[0], output[0]);// equalize + cv::equalizeHist(v[1], output[1]); + cv::equalizeHist(v[2], output[2]); + cv::merge(output,3,frame);// merge back to create final output + AddInvert(frame); +} + +// Channel sort - takes cv::Mat reference +void ac::ChannelSort(cv::Mat &frame) { + static double pos = 1.0; // color scale + std::vector v; // to hold the Matrix for split + cv::split(frame, v);// split the channels into seperate matrices + cv::Mat channels[3]; // output channels + cv::Mat output; // for merge + cv::sort(v[0], channels[0],cv::SORT_ASCENDING); // sort each matrix + cv::sort(v[1], channels[1],cv::SORT_ASCENDING); + cv::sort(v[2], channels[2],cv::SORT_ASCENDING); + cv::merge(channels, 3, output); // combine the matrices + for(int z = 0; z < frame.rows; ++z) { // top to bottom + for(int i = 0; i < frame.cols; ++i) { // left to right + cv::Vec3b &pixel = frame.at(z, i); // get reference to pixel + cv::Vec3b &ch_pixel = output.at(z, i); // get reference to pixel + // add and multiply components to channels + pixel[0] += static_cast(ch_pixel[0]*pos); + pixel[1] += static_cast(ch_pixel[1]*pos); + pixel[2] += static_cast(ch_pixel[2]*pos); + // swap colors + swapColors(frame, z, i); + // if isNegative true invert pixel + if(isNegative) invert(frame, z, i); + } + } + // pos max + static double pos_max = 7.0; + static int direction = 1; + procPos(direction, pos, pos_max); +} + diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter3.cpp b/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter3.cpp new file mode 100755 index 0000000..40ce80a --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter3.cpp @@ -0,0 +1,1882 @@ +/* + * Software written by Jared Bruni https://github.com/lostjared + + This software is dedicated to all the people that experience mental illness. + + Website: http://lostsidedead.com + YouTube: http://youtube.com/LostSideDead + Instagram: http://instagram.com/jaredbruni + Twitter: http://twitter.com/jaredbruni + Facebook: http://facebook.com/LostSideDead0x + + You can use this program free of charge and redistrubute it online as long + as you do not charge anything for this program. This program is meant to be + 100% free. + + BSD 2-Clause License + + Copyright (c) 2019, Jared Bruni + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + */ + +#include "ac.h" + +// takes cv::Mat reference +void ac::Reverse_XOR(cv::Mat &frame) { + static cv::Mat initial = frame; + if(initial.cols != frame.cols || initial.rows != frame.rows) { + initial = frame; + } + static double pos = 1.0; + cv::Mat start = frame.clone(); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b &in_pixel = initial.at(z, i); + pixel[0] ^= in_pixel[2]; + pixel[1] ^= in_pixel[1]; + pixel[2] ^= in_pixel[0]; + // swap colors + swapColors(frame, z, i); + // if isNegative true invert pixel + if(isNegative) invert(frame, z, i); + } + } + initial = start; + static double pos_max = 7.0; + static int direction = 1; + procPos(direction, pos, pos_max); +} + +// takes cv::Mat reference +void ac::CombinePixels(cv::Mat &frame) { + static double pos = 1.0, pos_max = 7.0; + static int direction = 1; + cv::Scalar s(1.0, 100.0, 200.0); + for(int z = 2; z < frame.rows-2; ++z) { + for(int i = 2; i < frame.cols-2; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pixels[4]; + pixels[0] = frame.at(z, i+1); + pixels[1] = frame.at(z+1, i); + pixels[2] = frame.at(z+1, i+1); + pixel[0] ^= (pixels[0][0]+pixels[1][0]+pixels[2][0]); + pixel[1] ^= (pixels[0][1]+pixels[1][1]+pixels[2][1]); + pixel[2] ^= (pixels[0][2]+pixels[1][2]+pixels[2][2]); + pixel[0] *= static_cast(pos); + pixel[1] *= static_cast(pos); + pixel[2] *= static_cast(pos); + // swap colors + swapColors(frame, z, i); + // if isNegative true invert pixel + if(isNegative) invert(frame, z, i); + } + } + procPos(direction, pos, pos_max); +} +// Canny takes cv::Mat reference +void ac::Canny(cv::Mat &frame) { + cv::Mat out; + static double x = 100, y = 100; + cv::Canny(frame, out, x, y); + cv::Mat converted; + cv::cvtColor(out, converted, cv::COLOR_GRAY2BGR); + frame = converted.clone(); + AddInvert(frame); +} + +// Flip takes cv::Mat reference +// flip the iamge every other frame +void ac::FlipTrip(cv::Mat &frame) { + static int _flip = 0;// index variable + cv::Mat output;// output matrix + switch(_flip){ + case 0: + cv::flip(frame, output, 1); // flip matrix + frame = output.clone();// frame equals output + _flip++;// increase index + break; + case 1: + // do nothing + _flip = 0; // index equals zero + break; + } +} + +// Loop tiled boxes +void ac::Boxes(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + static int pixel_size = 8; // size of each tile + for(int z = 0; z < h; z += pixel_size) { // from top to bottom + for(int i = 0; i < w; i += pixel_size) { // from left to right + unsigned char rgb[3]; // 3 bytes + rgb[0] = rand()%255; // set to random number + rgb[1] = rand()%255; + rgb[2] = rand()%255; + for(int y = z; y < static_cast(z+pixel_size); ++y) { // tile top to bottom + for(int x = i; x < static_cast(i+pixel_size); ++x) {// tile left to right + if(x < w && y < h) { // is x,y on screen? + // reference to pixel + cv::Vec3b &pixel = frame.at(y, x); + pixel[0] += rgb[0]; // add each component + pixel[1] += rgb[1]; + pixel[2] += rgb[2]; + } + } + } + } + } + static int direction = 1; // current direction, grow versus shrink + if(direction == 1) { + ++pixel_size;// grow by 1 + // if greater than 1/6 of frame size set to zero + if(static_cast(pixel_size) > (w/6)) direction = 0; + } else if(direction == 0) {// direction equals zero shrink + --pixel_size;// shrink + if(pixel_size < 24) direction = 1; + } +} +// Loop tiled box fade +void ac::BoxesFade(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + static cv::Vec3b color(rand()%255, rand()%255, rand()%255); // random color + static int sw = 0; // with component to increase + static int pixel_size = 8; // size of each tile + for(int z = 0; z < h; z += pixel_size) { // from top to bottom + ++sw;// increase + if(sw > 2) sw = 0;//greater than 2 reset + for(int i = 0; i < w; i += pixel_size) { // from left to right + for(int y = z; y < z+pixel_size; ++y) { // tile top to bottom + for(int x = i; x < i+pixel_size; ++x) {// tile left to right + if(x < w && y < h) { // is x,y on screen? + // reference to pixel + switch(sw) { + case 0: // increase B + ++color[0]; + break; + case 1:// increase G + ++color[1]; + break; + case 2:// increase R + ++color[2]; + break; + } + if(color[0] >= 254) color[0] = rand()%255; // reset if over + if(color[1] >= 254) color[1] = rand()%255; + if(color[2] >= 254) color[2] = rand()%255; + + cv::Vec3b &pixel = frame.at(y, x); + pixel[0] += color[0]; // add each component + pixel[1] += color[1]; + pixel[2] += color[2]; + } + } + } + } + } + static int direction = 1; // current direction, grow versus shrink + if(direction == 1) { + ++pixel_size;// grow by 1 + // if greater than 1/6 of frame size set to zero + if(pixel_size > (w/6)) direction = 0; + } else if(direction == 0) {// direction equals zero shrink + --pixel_size;// shrink + if(pixel_size < 24) direction = 1; + } +} + + +void ac::FlashBlack(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + static cv::Vec3b black(0, 0, 0); + static bool flash = false; + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + if(flash == true) + pixel = black; + + } + } + flash = !flash; +} + +void ac::SlideRGB(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + static int offset_x = 0; + int color[2] = { rand()%3, rand()%3 }; + for(int z = 3; z < h-3; ++z) { + for(int i = 3; i < w-3; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + if(offset_x+i < (w-1)) { + cv::Vec3b off_pix = frame.at(z, offset_x+i); + pixel[color[0]] += static_cast(off_pix[color[0]]); + cv::Vec3b off_red = frame.at(z, (w-(offset_x+i))); + pixel[color[1]] += static_cast(off_red[color[1]]); + } + } + } + static int direction = 1; + if(direction == 1) { + ++offset_x; + if(offset_x > 5) { + direction = 0; + } + } else { + --offset_x; + if(offset_x <= 1) { + direction = 1; + } + } +} +// Blend from Side to Side +void ac::Side2Side(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + static double pos = 1.0, pos_max = 3.0; + for(int z = 0; z < h; ++z) { + cv::Scalar total; + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + total[0] += (pixel[0]/2); + total[1] += (pixel[1]/2); + total[2] += (pixel[2]/2); + pixel[0] = static_cast(pixel[0] + (total[0]*pos)*0.01); + pixel[1] = static_cast(pixel[1] + (total[1]*pos)*0.01); + pixel[2] = static_cast(pixel[2] + (total[2]*pos)*0.01); + + // swap colors + swapColors(frame, z, i); + // if isNegative true invert pixel + if(isNegative) invert(frame, z, i); + } + } + static int direction = 1; + procPos(direction, pos, pos_max); +} +// Blend from Top To Bottom +void ac::Top2Bottom(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + static double pos = 1.0, pos_max = 5.0; + for(int i = 0; i < w; ++i) { + cv::Scalar total; + for(int z = 0; z < h; ++z) { + cv::Vec3b &pixel = frame.at(z, i); + total[0] += (pixel[0]/2); + total[1] += (pixel[1]/2); + total[2] += (pixel[2]/2); + pixel[0] = static_cast(pixel[0] + (total[0]*pos)*0.01); + pixel[1] = static_cast(pixel[1] + (total[1]*pos)*0.01); + pixel[2] = static_cast(pixel[2] + (total[2]*pos)*0.01); + // swap colors + swapColors(frame, z, i); + // if isNegative true invert pixel + if(isNegative) invert(frame, z, i); + } + } + static int direction = 1; + procPos(direction, pos, pos_max); +} + +void ac::StrobeRedGreenBlue(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + static unsigned color = 0; + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + switch(color) { + case 0: // B + pixel[1] = pixel[2] = 0; + break; + case 1:// G + pixel[0] = pixel[2] = 0; + break; + case 2:// R + pixel[0] = pixel[1] = 0; + } + // swap colors + swapColors(frame, z, i); + // if isNegative true invert pixel + if(isNegative) invert(frame, z, i); + } + } + ++color; + if(color > 2) color = 0; +} + +void ac::Blend_Angle(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + static double pos = 1.0, pos_max = 5.0; + for(int z = 0; z < h; ++z) { + cv::Scalar total; + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + total[0] += pixel[0] * 0.01; + total[1] += pixel[1] * 0.01; + total[2] += pixel[2] * 0.01; + + pixel[0] = static_cast(pixel[0] + (total[0]) * (pos*0.1)); + pixel[1] = static_cast(pixel[1] + (total[1]) * (pos*0.1)); + pixel[2] = static_cast(pixel[2] + (total[2]) * (pos*0.1)); + + // swap colors + swapColors(frame, z, i); + // if isNegative true invert pixel + if(isNegative) invert(frame, z, i); + } + } + + static int direction = 1; + procPos(direction, pos,pos_max); +} + +void ac::Outward(cv::Mat &frame) { + int w = frame.cols;// frame width + int h = frame.rows;// frame height + static double start_pos = 1, pos = 1.0, pos_max = 5.0; + + static cv::Scalar offset(5, 50, 100); + + pos = start_pos; + + for(int y = h/2; y > 0; --y) { + for(int x = 0; x < w; ++x) { + cv::Vec3b &pixel = frame.at(y, x); + pixel[0] += static_cast((pos*offset[0])); + pixel[1] += static_cast((pos*offset[1])); + pixel[2] += static_cast((pos*offset[2])); + // swap colors + swapColors(frame, y, x); + // if isNegative true invert pixel + if(isNegative) invert(frame, y, x); + + } + pos += 0.005; + } + + pos = start_pos; + + for(int y = h/2+1; y < h; ++y) { + for(int x = 0; x < w; ++x) { + cv::Vec3b &pixel = frame.at(y, x); + pixel[0] += static_cast((pos*offset[0])); + pixel[1] += static_cast((pos*offset[1])); + pixel[2] += static_cast((pos*offset[2])); + // swap colors + swapColors(frame, y, x); + // if isNegative true invert pixel + if(isNegative) invert(frame, y, x); + } + pos += 0.005; + } + + offset[0] += 12; + offset[1] += 6; + offset[2] += 3; + + for(int i = 0; i < 3; ++i) if(offset[i] > 200) offset[i] = 0; + + static int direction = 1; + procPos(direction, start_pos, pos_max); +} + +void ac::OutwardSquare(cv::Mat &frame) { + int w = frame.cols;// frame width + int h = frame.rows;// frame height + int wx = w/2; + static double start_pos = 1, pos = 1.0, pos_max = 5.0; + static cv::Scalar offset(5, 50, 100); + pos = start_pos; + + for(int y = h/2; y > 0; --y) { + for(int x = 0; x < wx; ++x) { + cv::Vec3b &pixel = frame.at(y, x); + pixel[0] += static_cast((pos*offset[0])); + pixel[1] += static_cast((pos*offset[1])); + pixel[2] += static_cast((pos*offset[2])); + // swap colors + swapColors(frame, y, x); + // if isNegative true invert pixel + if(isNegative) invert(frame, y, x); + } + pos += 0.005; + } + //pos = start_pos; + for(int y = h/2; y > 0; --y) { + for(int x = w-1; x > wx-1; --x) { + cv::Vec3b &pixel = frame.at(y, x); + pixel[0] += static_cast((pos*offset[0])); + pixel[1] += static_cast((pos*offset[1])); + pixel[2] += static_cast((pos*offset[2])); + // swap colors + swapColors(frame, y, x); + // if isNegative true invert pixel + if(isNegative) invert(frame, y, x); + } + pos += 0.005; + } + + pos = start_pos; + for(int y = h/2+1; y < h; ++y) { + for(int x = 0; x < wx; ++x) { + cv::Vec3b &pixel = frame.at(y, x); + pixel[0] += static_cast((pos*offset[0])); + pixel[1] += static_cast((pos*offset[1])); + pixel[2] += static_cast((pos*offset[2])); + // swap colors + swapColors(frame, y, x); + // if isNegative true invert pixel + if(isNegative) invert(frame, y, x); + } + pos += 0.005; + } + //pos = start_pos; + for(int y = h/2+1; y < h; ++y) { + for(int x = w-1; x > wx-1; --x) { + cv::Vec3b &pixel = frame.at(y, x); + pixel[0] += static_cast((pos*offset[0])); + pixel[1] += static_cast((pos*offset[1])); + pixel[2] += static_cast((pos*offset[2])); + // swap colors + swapColors(frame, y, x); + // if isNegative true invert pixel + if(isNegative) invert(frame, y, x); + } + pos += 0.005; + } + offset[0] += 12; + offset[1] += 6; + offset[2] += 3; + for(int i = 0; i < 3; ++i) if(offset[i] > 200) offset[i] = 0; + static int direction = 1; + procPos(direction, start_pos, pos_max); +} + +void ac::ShiftPixels(cv::Mat &frame) { + static int offset = 1; + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + for(int z = 0; z < h; ++z) { + int start = 0; + for(int i = offset; i < w && start < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b &source = frame.at(z, start); + pixel[0] += source[0]; + pixel[1] += source[1]; + pixel[2] += source[2]; + ++start; + // swap colors + swapColors(frame, z, i); + // if isNegative true invert pixel + if(isNegative) invert(frame, z, i); + } + for(int i = 0; i < offset-1 && start < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b &source = frame.at(z, start); + pixel[0] += source[0]; + pixel[1] += source[1]; + pixel[2] += source[2]; + ++start; + // swap colors + swapColors(frame, z, i); + // if isNegative true invert pixel + if(isNegative) invert(frame, z, i); + } + } + static int direction = 1; + static int max_up = (w/16); + if(direction == 1) { + ++offset; + if(offset > max_up) { + direction = 0; + max_up += 4; + if(max_up > (w/4)) { + max_up = (w/16); + } + } + } else if(direction == 0) { + --offset; + if(offset < 2) direction = 1; + } +} + +void ac::ShiftPixelsDown(cv::Mat &frame) { + static int offset = 1; + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + static double pos = 1.0, pos_max = 7.0; + for(int i = 0; i < w; ++i) { + int start = 0; + for(int z = offset; z < h && start < h; ++z) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b &source = frame.at(z, start); + pixel[0] += static_cast(source[0]*pos); + pixel[1] += static_cast(source[1]*pos); + pixel[2] += static_cast(source[2]*pos); + ++start; + // swap colors + swapColors(frame, z, i); + // if isNegative true invert pixel + if(isNegative) invert(frame, z, i); + } + for(int z = 0; z < offset-1 && start < h; ++z) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b &source = frame.at(z, start); + pixel[0] += static_cast(source[0]*pos); + pixel[1] += static_cast(source[1]*pos); + pixel[2] += static_cast( source[2]*pos); + ++start; + // swap colors + swapColors(frame, z, i); + // if isNegative true invert pixel + if(isNegative) invert(frame, z, i); + } + } + static int direction = 1; + static int max_up = (h/8); + if(direction == 1) { + ++offset; + if(offset > max_up) { + direction = 0; + max_up += 4; + if(max_up > (h/2)) { + max_up = (h/8); + } + } + } else if(direction == 0) { + --offset; + if(offset < 2) direction = 1; + } + static int dir = 1; + procPos(dir, pos, pos_max); + +} + +void ac::XorMultiBlend(cv::Mat &frame) { + int w = frame.cols;// frame width + int h = frame.rows;// frame height + static double pos = 1.0, pos_max = 3.0; + cv::Scalar s(pos, -pos, pos); + for(int y = h-1; y > 0; --y) { + for(int x = w-1; x > 0; --x) { + cv::Vec3b &pixel = frame.at(y, x); + pixel[0] = static_cast((pixel[0]^(int)s[0])*pos); + pixel[1] = static_cast((pixel[1]^(int)s[1])*pos); + pixel[2] = static_cast((pixel[2]^(int)s[2])*pos); + + swapColors(frame, y, x); + if(isNegative) invert(frame, y, x); + } + } + static int direction = 1; + procPos(direction, pos, pos_max, 4.0); +} + +void ac::BitwiseRotate(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + static int offset = 0; + static int direction = 1; + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + + if(direction == 1) { + pixel[0] = ror(pixel[0], offset); + pixel[1] = rol(pixel[1], offset); + pixel[2] = ror(pixel[2], offset); + } else { + pixel[0] = rol(pixel[0], offset); + pixel[1] = ror(pixel[1], offset); + pixel[2] = rol(pixel[2], offset); + } + + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } + if(direction == 1) { + offset++; + if(offset >= 7) { + direction = 0; + } + } else { + offset--; + if(offset <= 1) { + direction = 1; + } + } +} + +void ac::BitwiseRotateDiff(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + static int offset = 1; + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int q = 0; q < 3; ++q) + pixel[q] += static_cast((pixel[q]-ror(pixel[q], offset))); + + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } + ++offset; + if(offset > 7) offset = 1; +} + +void ac::HPPD(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + static double pos = 1.0, pos_max = 4.0; + for(int z = 0; z < h; ++z) { + cv::Scalar total; + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + total[0] += pixel[0]; + total[1] += pixel[1]; + total[2] += pixel[2]; + pixel[0] = static_cast(pixel[0]-total[0]*pos); + pixel[1] = static_cast(pixel[1]-total[1]*pos); + pixel[2] = static_cast(pixel[2]-total[2]*pos); + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } + + static int direction = 1; + procPos(direction, pos, pos_max); +} + +void ac::FuzzyLines(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + static double pos = 1.0, pos_max = 4.0; + cv::Scalar prev_pixel; + double value[3] = { 0 }; + + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b temp = pixel; + + value[0] += temp[0]+temp[1]+temp[2]; + value[1] -= temp[0]+temp[1]+temp[2]; + value[2] += temp[0]+temp[1]+temp[2]; + pixel[0] += static_cast((value[0]*pos)*0.001); + pixel[1] += static_cast((value[1]*pos)*0.001); + pixel[2] += static_cast((value[2]*pos)*0.001); + + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + prev_pixel[0] = pixel[0]; + prev_pixel[1] = pixel[1]; + prev_pixel[2] = pixel[2]; + } + } + + static int direction = 1; + procPos(direction, pos, pos_max); +} + +void ac::GradientLines(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + static int count = 0, index = 0; + + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + pixel[index] += static_cast(count); + ++count; + if(count >= 255) { + count = 0; + ++index; + if(index > 2) index = 0; + } + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } +} + +void ac::GradientSelf(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + static double pos = 1.0, pos_max = 7.0; + static int count = 0, index = 0; + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + pixel[index] = static_cast((pixel[index]*pos)+count); + ++count; + if(count >= 255) { + count = 0; + } + + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + ++index; + if(index > 2) index = 0; + } + static int direction = 1; + procPos(direction, pos, pos_max); +} + +void ac::GradientSelfVertical(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + static double pos = 1.0, pos_max = 7.0; + static int count = 0, index = 0; + for(int i = 0; i < w; ++i) { + for(int z = 0; z < h; ++z) { + cv::Vec3b &pixel = frame.at(z, i); + pixel[index] = static_cast((pixel[index]*pos)+count); + ++count; + if(count >= 255) { + count = 0; + } + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + ++index; + if(index > 2) index = 0; + } + static int direction = 1; + procPos(direction, pos, pos_max); +} + +void ac::GradientDown(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + static double pos = 1.0, pos_max = 7.0; + static int count = 0, index = 0; + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + pixel[index] = static_cast((pixel[index]*pos)+count); + ++index; + if(index > 2) index = 0; + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + ++count; + if(count >= 255) { + count = 0; + } + } + static int direction = 1; + procPos(direction, pos, pos_max); +} + +void ac::GraidentHorizontal(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + static double pos = 1.0, pos_max = 7.0; + static int count = 0, index = 0; + for(int i = 0; i < w; ++i) { + for(int z = 0; z < h; ++z) { + cv::Vec3b &pixel = frame.at(z, i); + pixel[index] = static_cast((pixel[index]*pos)+count); + ++index; + if(index > 2) index = 0; + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + ++count; + if(count >= 255) { + count = 0; + } + } + int direction = 1; + procPos(direction, pos, pos_max); +} + +void ac::GradientRGB(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + static int count = 0, index = 0; + static int direction = 1; + if(direction == 1) { + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + pixel[index] = pixel[index]*count; + ++count; + if(count >= 255) { + ++index; + if(index > 2) { + index = 0; + } + } + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } + } else { + for(int i = 0; i < w; ++i) { + for(int z = 0; z < h; ++z) { + cv::Vec3b &pixel = frame.at(z, i); + pixel[index] = pixel[index]*count; + ++count; + if(count >= 255) { + ++index; + if(index > 2) { + index = 0; + } + } + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } + } + if(direction == 1) direction = 0; else direction = 1; +} + + +void ac::Inter(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + static int start_x = 0; + for(int z = start_x; z < h; z += 2) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + pixel[0] = pixel[1] = pixel[2] = 0; + } + } + if(start_x == 0) start_x = 1; else start_x = 0; +} + + +void ac::UpDown(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + static double pos = 1.0, pos_max = 7.0; + double alpha = 1.0; + bool order = true; + + for(int i = 0; i < w; ++i) { + if(order == true) { + order = false; + for(int z = 0; z < h; ++z) { + cv::Vec3b &pixel = frame.at(z, i); + for(int q = 0; q < 3; ++q) + pixel[q] = static_cast(alpha+(pixel[q]*pos)); + + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + alpha += 0.1; + } else { + order = true; + for(int z = h-1; z > 1; --z) { + cv::Vec3b &pixel = frame.at(z, i); + for(int q = 0; q < 3; ++q) + pixel[q] =static_cast(alpha-(pixel[q]*pos)); + + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + + alpha += 0.1; + } + + } + + static int direction = 1; + procPos(direction, pos, pos_max); +} + +void ac::LeftRight(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + static double pos = 1.0, pos_max = 7.0; + double alpha = 1.0; + bool order = true; + for(int z = 0; z < h; ++z) { + if(order == true) { + order = false; + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int q = 0; q < 3; ++q) + pixel[q] = static_cast(alpha+(pixel[q]*pos)); + + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + alpha += 0.1; + } else { + order = true; + for(int i = w-1; i > 1; --i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int q = 0; q < 3; ++q) + pixel[q] = static_cast(alpha-(pixel[q]*pos)); + + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + + alpha += 0.1; + } + } + static int direction = 1; + procPos(direction, pos, pos_max); +} + +void ac::StrobeScan(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + static double pos = 1.0, pos_max = 7.0; + static int color_mode = 0; + int over = rand()%255; + static int cdirection = 1; + + for(int z = 0; z < h; ++z) { + switch(color_mode) { + case 0: { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + pixel[color_mode] = static_cast(over+(pixel[color_mode]*pos)); + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } + break; + case 1: { + for(int i = w-1; i > 1; --i) { + cv::Vec3b &pixel = frame.at(z, i); + pixel[color_mode] -= static_cast(over+(pixel[1]*pos)); + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + + } + } + break; + case 2: { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + pixel[color_mode] ^= static_cast(over+(pixel[color_mode]*pos)); + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + + } + } + break; + } + + if(cdirection == 1) { + ++color_mode; + if(color_mode > 2) { + cdirection = 0; + } + } else if(cdirection == 0) { + --color_mode; + if(color_mode < 0) { + cdirection = 1; + } + } + } + static int direction = 1; + procPos(direction, pos, pos_max); +} + +void ac::BlendedScanLines(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + static int cnt = 0; + for(int z = 0; z < h; ++z) { + int r = rand()%255; + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + pixel[cnt] += static_cast(r); + ++r; + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + ++cnt; + if(cnt > 2) { + cnt = 0; + } + } + } +} + +void ac::GradientStripes(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + static int offset = 0, count = 0; + int count_i = (rand()%0xFF)+(rand()%0xFFFFFF);//color offset + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + pixel[offset] += static_cast(count); + pixel[2-offset] -= static_cast(count_i); + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + ++count; + ++count_i; + } + ++offset; + if(offset > 2) + offset = 0; +} +// this one pixelates the image very heavily. +void ac::XorSine(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + static cv::Scalar val(rand()%10, rand()%10, rand()%10); + static double pos = 1.0, pos_max = 7.0; + for(int i = 0; i < w; ++i) { + for(int z = 0; z < h; ++z) { + cv::Vec3b &pixel = frame.at(z, i); + pixel[0] ^= static_cast(sin(pixel[0])*val[0]); + pixel[1] ^= static_cast(sin(pixel[1])*val[1]); + pixel[2] ^= static_cast(sin(pixel[2])*val[2]); + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } + static int direction = 1; + for(int q = 0; q < 3; ++q) { + if(direction == 1) + val[q] += pos; + else + val[q] -= pos; + } + procPos(direction, pos, pos_max); +} + + + +void ac::Circular(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + static double pos = 1.0, pos_max = 7.0; + static double deg = 0.0; + static double rad = 50; + + for(int i = 0; i < w; ++i) { + for(int z = 0; z < h; ++z) { + cv::Vec3b &pixel = frame.at(z, i); + int X_color = int(rad * cos(deg)); + int Y_color = int(rad * sin(deg)); + pixel[0] += static_cast(pos*X_color); + pixel[1] *= static_cast(pos); + pixel[2] += static_cast(pos*Y_color); + deg += 0.1; + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } + rad += 0.5; + if(rad > 100) rad = 50; + static int direction = 1; + procPos(direction, pos, pos_max); +} + + +void ac::WhitePixel(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + static int pixel_count = 0; + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + if(pixel_count == 4) { + cv::Vec3b &pixel = frame.at(z, i); + pixel[0] = pixel[1] = pixel[2] = 255; + pixel_count = rand()%2; + } else ++pixel_count; + + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + pixel_count = rand()%2; + } +} + +void ac::FrameBlend(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + static double pos = 1.0, pos_max = 7.0; + static cv::Mat stored_frame; + if((frame.rows != stored_frame.rows) || (frame.cols != stored_frame.cols)) { + stored_frame = frame.clone(); + } + cv::Mat start = frame.clone(); + // process frame + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b old_pixel = stored_frame.at(z, i); + pixel[0] += static_cast((old_pixel[0]^pixel[0])*pos); + pixel[1] += static_cast((old_pixel[1]&pixel[1])*pos); + pixel[2] += static_cast((old_pixel[2]|pixel[2])*pos); + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } + stored_frame = start.clone(); + static int direction = 1; + procPos(direction, pos, pos_max); +} + +void ac::FrameBlendRGB(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + static double pos = 1.0, pos_max = 7.0; + static cv::Mat stored_frame; + if(stored_frame.empty() || frame.size() != stored_frame.size()) { + stored_frame = frame.clone(); + } + cv::Mat start = frame.clone(); + static int swap = 0; + // process frame + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b old_pixel = stored_frame.at(z, i); + switch(swap) { + case 0: + pixel[0] += static_cast((old_pixel[0]^pixel[0])*pos); + pixel[1] += static_cast((old_pixel[1]&pixel[1])*pos); + pixel[2] += static_cast((old_pixel[2]|pixel[2])*pos); + break; + case 1: + pixel[0] += static_cast((old_pixel[0]&pixel[0])*pos); + pixel[1] += static_cast((old_pixel[1]|pixel[1])*pos); + pixel[2] += static_cast((old_pixel[2]^pixel[2])*pos); + break; + case 2: + pixel[0] += static_cast((old_pixel[0]|pixel[0])*pos); + pixel[1] += static_cast((old_pixel[1]^pixel[1])*pos); + pixel[2] += static_cast((old_pixel[2]&pixel[2])*pos); + break; + } + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } + ++swap; + if(swap > 2) swap = 0; + stored_frame = start.clone(); + static int direction = 1; + procPos(direction, pos, pos_max); +} + +void ac::TrailsFilter(cv::Mat &frame) { + static MatrixCollection<4> collection; + collection.shiftFrames(frame); + const int w = frame.cols;// frame width + const int h = frame.rows;// frame heigh + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Scalar s; + cv::Vec3b frame_pixels[8]; + frame_pixels[0] = collection.frames[1].at(z, i); + frame_pixels[1] = collection.frames[2].at(z, i); + frame_pixels[2] = collection.frames[3].at(z, i); + pixel[0] += (frame_pixels[0][0] + frame_pixels[1][0] + frame_pixels[2][0]); + pixel[1] += (frame_pixels[0][1] + frame_pixels[1][1] + frame_pixels[2][1]); + pixel[2] += (frame_pixels[0][2] + frame_pixels[1][2] + frame_pixels[2][2]); + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } +} + +void ac::TrailsFilterIntense(cv::Mat &frame) { + static MatrixCollection<8> collection; + collection.shiftFrames(frame); + const int w = frame.cols;// frame width + const int h = frame.rows;// frame heigh + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Scalar s; + cv::Vec3b frame_pixels[8]; + frame_pixels[0] = collection.frames[0].at(z, i); + frame_pixels[1] = collection.frames[1].at(z, i); + frame_pixels[2] = collection.frames[2].at(z, i); + frame_pixels[3] = collection.frames[3].at(z, i); + frame_pixels[4] = collection.frames[4].at(z, i); + frame_pixels[5] = collection.frames[5].at(z, i); + pixel[0] += (frame_pixels[0][0] + frame_pixels[1][0] + frame_pixels[2][0] + frame_pixels[3][0] + frame_pixels[4][0] + frame_pixels[5][0]); + pixel[1] += (frame_pixels[0][1] + frame_pixels[1][1] + frame_pixels[2][1] + frame_pixels[3][1] + frame_pixels[4][1] + frame_pixels[5][1]); + pixel[2] += (frame_pixels[0][2] + frame_pixels[1][2] + frame_pixels[2][2] + frame_pixels[3][2] + frame_pixels[4][2] + frame_pixels[5][2]); + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } +} + +void ac::TrailsFilterSelfAlpha(cv::Mat &frame) { + static MatrixCollection<8> collection; + static double pos = 1.0, pos_max = 7.0; + collection.shiftFrames(frame); + const int w = frame.cols;// frame width + const int h = frame.rows;// frame heigh + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Scalar s; + cv::Vec3b frame_pixels[8]; + frame_pixels[0] = collection.frames[1].at(z, i); + frame_pixels[1] = collection.frames[2].at(z, i); + frame_pixels[2] = collection.frames[3].at(z, i); + frame_pixels[3] = collection.frames[4].at(z, i); + frame_pixels[4] = collection.frames[5].at(z, i); + frame_pixels[5] = collection.frames[6].at(z, i); + pixel[0] += static_cast((frame_pixels[0][0] + frame_pixels[1][0] + frame_pixels[2][0] + frame_pixels[3][0] + frame_pixels[4][0] + frame_pixels[5][0])*pos); + pixel[1] += static_cast((frame_pixels[0][1] + frame_pixels[1][1] + frame_pixels[2][1] + frame_pixels[3][1] + frame_pixels[4][1] + frame_pixels[5][1])*pos); + pixel[2] += static_cast((frame_pixels[0][2] + frame_pixels[1][2] + frame_pixels[2][2] + frame_pixels[3][2] + frame_pixels[4][2] + frame_pixels[5][2])*pos); + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } + static int direction = 1; + procPos(direction, pos, pos_max); +} + +void ac::TrailsFilterXor(cv::Mat &frame) { + static MatrixCollection<12> collection; + static double pos = 1.0, pos_max = 7.0; + collection.shiftFrames(frame); + const int w = frame.cols;// frame width + const int h = frame.rows;// frame heigh + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Scalar s; + cv::Vec3b frame_pixels[12]; + frame_pixels[0] = collection.frames[1].at(z, i); + frame_pixels[1] = collection.frames[2].at(z, i); + frame_pixels[2] = collection.frames[3].at(z, i); + frame_pixels[3] = collection.frames[4].at(z, i); + frame_pixels[4] = collection.frames[5].at(z, i); + frame_pixels[5] = collection.frames[6].at(z, i); + pixel[0] ^= (frame_pixels[0][0] + frame_pixels[1][0] + frame_pixels[2][0] + frame_pixels[3][0] + frame_pixels[4][0] + frame_pixels[5][0]); + pixel[1] ^= (frame_pixels[0][1] + frame_pixels[1][1] + frame_pixels[2][1] + frame_pixels[3][1] + frame_pixels[4][1] + frame_pixels[5][1]); + pixel[2] ^= (frame_pixels[0][2] + frame_pixels[1][2] + frame_pixels[2][2] + frame_pixels[3][2] + frame_pixels[4][2] + frame_pixels[5][2]); + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } + static int direction = 1; + procPos(direction, pos, pos_max); +} + +void ac::ColorTrails(cv::Mat &frame) { + static MatrixCollection<8> collection; + collection.shiftFrames(frame); + const int w = frame.cols;// frame width + const int h = frame.rows;// frame heigh + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Scalar s; + cv::Vec3b frame_pixels[8]; + frame_pixels[0] = collection.frames[1].at(z, i); + frame_pixels[1] = collection.frames[2].at(z, i); + frame_pixels[2] = collection.frames[3].at(z, i); + frame_pixels[3] = collection.frames[4].at(z, i); + frame_pixels[4] = collection.frames[5].at(z, i); + frame_pixels[5] = collection.frames[6].at(z, i); + for(int q = 0; q < 6; ++q) { + if(frame_pixels[q][0] > pixel[0]) frame_pixels[q][0] = 0; + if(frame_pixels[q][1] < pixel[1]) frame_pixels[q][1] = 0; + if(frame_pixels[q][2] > pixel[2]) frame_pixels[q][2] = 0; + } + pixel[0] = (frame_pixels[0][0] + frame_pixels[1][0] + frame_pixels[2][0] + frame_pixels[3][0] + frame_pixels[4][0] + frame_pixels[5][0]); + pixel[1] = (frame_pixels[0][1] + frame_pixels[1][1] + frame_pixels[2][1] + frame_pixels[3][1] + frame_pixels[4][1] + frame_pixels[5][1]); + pixel[2] = (frame_pixels[0][2] + frame_pixels[1][2] + frame_pixels[2][2] + frame_pixels[3][2] + frame_pixels[4][2] + frame_pixels[5][2]); + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } +} + +void ac::MoveRed(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame heigh + static double pos = 1.0, pos_max = 7.0; + static int movement = 0; + cv::Mat frame_copy = frame.clone(); + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + if(i+movement < (w-1)) { + cv::Vec3b add = frame_copy.at(z, (i+movement)); + pixel[2] += static_cast((add[2]*pos)); + } else if((i-movement) > 1) { + cv::Vec3b add = frame_copy.at(z, (i-movement)); + pixel[2] += static_cast((add[2]*pos)); + } + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } + ++movement; + if(movement > (w-1)) movement = 0; + static int direction = 1; + procPos(direction, pos, pos_max); +} + +void ac::MoveRGB(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame heigh + static double pos = 1.0, pos_max = 7.0; + static int rgb = 0; + static int movement = 0; + cv::Mat frame_copy = frame.clone(); + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + if(i+movement < (w-1)) { + cv::Vec3b add = frame_copy.at(z, (i+movement)); + pixel[rgb] += static_cast((add[rgb]*pos)); + } else if((i-movement) > 1) { + cv::Vec3b add = frame_copy.at(z, (i-movement)); + pixel[rgb] += static_cast((add[rgb]*pos)); + } + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } + ++rgb; + if(rgb > 2) rgb = 0; + ++movement; + if(movement > (w-1)) movement = 0; + static int direction = 1; + procPos(direction, pos, pos_max); +} + +void ac::MoveRedGreenBlue(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame heigh + static double pos = 1.0, pos_max = 7.0; // position in transition, maximum value + static int movement[4] = {0, w, 0}; // movement variable array + static int stored_w = w; // stored_w in case the frame size changes + if(stored_w != w) { + movement[1] = w-1; // set movement[1] to width + stored_w = w; // stored_w set to new width + } + cv::Mat frame_copy = frame.clone(); // make a copy of the frame + for(int z = 0; z < h; ++z) { // loop from top to bottom + for(int i = 0; i < w; ++i) { // loop from left to right + cv::Vec3b &pixel = frame.at(z, i); // reference to current pixel + for(int q = 0; q <= 2; ++q) { // loop from 0 to 2 + int pos_x = i+movement[q];// pixel position + int pos_y = i-movement[q];// pixel position + if(pos_x < (w-1) && pos_x > 0) { // if within the screen + cv::Vec3b add = frame_copy.at(z, pos_x); // grab pixel + pixel[q] += static_cast((add[q]*pos)); // add to current index multiplied by position + } else if(pos_y > 0 && pos_y < (w-1)) {// if pos y within the screen + cv::Vec3b add = frame_copy.at(z, pos_y); // grab pixel + pixel[q] += static_cast((add[q]*pos));// add to current index multiplied by position + } + } + swapColors(frame, z, i);// swap colors for rgb sliders + if(isNegative) invert(frame, z, i); // if is negative + } + } + movement[0] += 4; // movement position increase by 4 + if(movement[0] > (w-1)) movement[0] = 0; + movement[1] -= 4;// movement position decrease by 4 + if(movement[1] < 1) movement[1] = w-1; // set to width -1 + movement[2] += 8;// movement position increase by 8 + if(movement[2] > (w-1)) movement[2] = 0;// if greater than widthset to zero + static int direction = 1;// direction of transition animation + procPos(direction, pos, pos_max);// proc the position by increasing/decreasing +} + +void ac::BlurSim(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame heigh + static double pos = 1.0, pos_max = 7.0; + + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b pixels[2][2]; + cv::Vec3b &pixel = frame.at(z, i); + bool grabbed = true; + for(int a = 0; a < 2; a++) { + for(int b = 0; b < 2; b++) { + if((a+i) < (w-1) && (b+z) < (h-1)) { + pixels[a][b] = frame.at(z+b, i+a); + } else { + grabbed = false; + break; + } + } + } + if(grabbed == false) continue; + unsigned char rgb[3] = {0}; + for(int q = 0; q < 3; ++q) + for(int a = 0; a < 2; ++a) { + for(int b = 0; b < 2; ++b) { + rgb[q] += pixels[a][b][q]; + } + } + pixel[0] ^= static_cast((rgb[0]/4)*pos); + pixel[1] ^= static_cast((rgb[1]/4)*pos); + pixel[2] ^= static_cast((rgb[2]/4)*pos); + swapColors(frame, z, i);// swap colors for rgb sliders + if(isNegative) invert(frame, z, i); // if is negative + } + } + static int direction = 1; + procPos(direction, pos, pos_max); +} + +void ac::Block(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame heigh + static int square = 2; + for(int z = 0; z < h; z += square) { + for(int i = 0; i < w; i += square) { + cv::Vec3b &pixel = frame.at(z, i); + for(int x = 0; x < square; ++x) { + for(int y = 0; y < square; ++y) { + if(y+z < h && i+x < w) { + cv::Vec3b &pix = frame.at(y+z, i+x); + pix = pixel; + } + } + } + swapColors(frame, z, i);// swap colors for rgb sliders + if(isNegative) invert(frame, z, i); // if is negative + } + } + static int direction = 1; + if(direction == 1) { + square += 2; + if(square >= 32) direction = 0; + } else { + square -= 2; + if(square <= 2) direction = 1; + } +} + +void ac::BlockXor(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame heigh + static double pos = 1.0, pos_max = 3.0; + static int square = 2; + for(int z = 0; z < h; z += square) { + for(int i = 0; i < w; i += square) { + cv::Vec3b &pixel = frame.at(z, i); + for(int x = 0; x < square; ++x) { + for(int y = 0; y < square; ++y) { + if(y+z < h && i+x < w) { + cv::Vec3b &pix = frame.at(y+z, i+x); + pix[0] ^= static_cast(pixel[0]*pos); + pix[1] ^= static_cast(pixel[1]*pos); + pix[2] ^= static_cast(pixel[2]*pos); + + } + } + } + swapColors(frame, z, i);// swap colors for rgb sliders + if(isNegative) invert(frame, z, i); // if is negative + + } + } + static int direction = 1; + if(direction == 1) { + square += 2; + if(square >= 8) direction = 0; + } else { + square -= 2; + if(square <= 2) direction = 1; + } + static int posDirection = 1; + procPos(posDirection, pos, pos_max); +} +// BlockScale +void ac::BlockScale(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame heigh + static double pos = 1.0, pos_max = 3.0; + static int square = 2; + for(int z = 0; z < h; z += square) { // loop from top to bottom + for(int i = 0; i < w; i += square) { // loop from left to right + cv::Vec3b &pixel = frame.at(z, i);// grab pixel value + for(int x = 0; x < square; ++x) {// draw square from left to right + for(int y = 0; y < square; ++y) {// draw square form top to bottom + if(y+z < h && i+x < w) {// within bounds? + cv::Vec3b &pix = frame.at(y+z, i+x); // grab pixel + pix[0] = static_cast(pixel[0]*pos); // calculate values + pix[1] = static_cast(pixel[1]*pos); + pix[2] = static_cast(pixel[2]*pos); + } + } + } + swapColors(frame, z, i);// swap colors for rgb sliders + if(isNegative) invert(frame, z, i); // if is negative + } + } + // move in/out direction + static int direction = 1; + if(direction == 1) { + square += 2; + if(square >= 8) direction = 0; + } else { + square -= 2; + if(square <= 2) direction = 1; + } + static int posDirection = 1; + procPos(posDirection, pos, pos_max); +} + +void ac::BlockStrobe(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame heigh + static int square = 2; + for(int z = 0; z < h; z += square) { + for(int i = 0; i < w; i += square) { + cv::Vec3b &pixel = frame.at(z, i); + for(int x = 0; x < square; ++x) { + for(int y = 0; y < square; ++y) { + if(y+z < h && i+x < w) { + cv::Vec3b &pix = frame.at(y+z, i+x); + pix[0] += static_cast(pixel[0]*(x*y)); + pix[1] += static_cast(pixel[1]*(x*y)); + pix[2] += static_cast(pixel[2]*(x*y)); + } + } + } + swapColors(frame, z, i);// swap colors for rgb sliders + if(isNegative) invert(frame, z, i); // if is negative + } + } + static int direction = 1; + if(direction == 1) { + square += 2; + if(square >= 8) direction = 0; + } else { + square -= 2; + if(square <= 2) direction = 1; + } +} + +// Prev Frame Blend +// store previous frame and manipulate with current frame +void ac::PrevFrameBlend(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + double pos = 1.0; + static int old_w = w; + static cv::Mat stored = frame.clone(), temp; + temp = frame.clone(); + if(old_w != w) { + stored = frame.clone(); + old_w = w; + } + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b old_pixel = stored.at(z, i); + pixel[0] = static_cast((pixel[0])+(1-old_pixel[0])*pos); + pixel[1] = static_cast((pixel[1])+(1-old_pixel[1])*pos); + pixel[2] = static_cast((pixel[2])+(1-old_pixel[2])*pos); + swapColors(frame, z, i);// swap colors for rgb sliders + if(isNegative) invert(frame, z, i); // if is negative + } + } + stored = temp; + static int direction = 1; + if(direction == 1) { + pos += 0.1; + if(pos > 7.0) direction = 0; + } else { + pos -= 0.1; + if(pos <= 1.0) direction = 1; + } + resetAlpha(direction, pos); + +} + +class WavePoints { +public: + WavePoints() : x1(0), x2(0), x1_dir(0), x2_dir(0),c_dir(0),color(0) {} + int x1,x2; + int x1_dir, x2_dir, c_dir; + double color; +}; + + +void ac::Wave(cv::Mat &frame) { + static int width = 0, height = 0; + // uses lazy allocation when frame is resized pointer is reallocated. + // last deallocation is done when program exits so no need to manually release + static std::unique_ptr points; + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + const int slice = (h/16); + + if(width != w || height != h) { + points.reset(new WavePoints[w]); + width = w; + height = h; + + for(int i = 0; i < w; ++i) { + points[i].x1 = rand()%slice; + points[i].x2 = h-rand()%slice; + points[i].color = rand()%13; + points[i].x1_dir = 0; + points[i].x2_dir = 0; + points[i].c_dir = 0; + } + } + for(int z = 0; z (z, i); + if(z >= points[i].x1 && z <= points[i].x2) { + pixel[0] += static_cast(pixel[0]*points[i].color); + pixel[1] += static_cast(pixel[1]*points[i].color); + pixel[2] += static_cast(pixel[2]*points[i].color); + } + swapColors(frame, z, i);// swap colors for rgb sliders + if(isNegative) invert(frame, z, i); // if is negative + } + } + for(int i = 0; i < w; ++i) { + // color direction + if(points[i].c_dir == 0) { + points[i].color += 0.1; + if(points[i].color >= 10) { + points[i].c_dir = 1; + } + } else if(points[i].c_dir == 1) { + points[i].color -= 0.1; + if(points[i].color <= 1) { + points[i].c_dir = 0; + } + } + + // x1 point direction/move down and up + if(points[i].x1_dir == 0) { + points[i].x1 ++; + if(points[i].x1 > slice) { + points[i].x1_dir = 1; + } + } else if(points[i].x1_dir == 1) { + points[i].x1--; + if(points[i].x1 < 1) { + points[i].x1_dir = 0; + } + } + + // x2 point up/down + if(points[i].x2_dir == 0) { + points[i].x2--; + if(points[i].x2 < (h-slice)) { + points[i].x2_dir = 1; + } + } else if(points[i].x2_dir == 1) { + points[i].x2++; + if(points[i].x2 > (h-4)) { + points[i].x2_dir = 0; + } + } + } +} + +void ac::HighWave(cv::Mat &frame) { + static int width = 0, height = 0; + static std::unique_ptr points; + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + const int slice = (h/8); + + if(width != w || height != h) { + points.reset(new WavePoints[w]); + width = w; + height = h; + + for(int i = 0; i < w; ++i) { + points[i].x1 = rand()%slice; + points[i].x2 = h-rand()%slice; + points[i].color = rand()%13; + points[i].x1_dir = 0; + points[i].x2_dir = 0; + points[i].c_dir = 0; + } + } + for(int z = 0; z (z, i); + pixel[0] -= static_cast(pixel[0]*points[i].color); + pixel[1] += static_cast(pixel[1]*points[i].color); + pixel[2] -= static_cast(pixel[2]*points[i].color); + swapColors(frame, z, i);// swap colors for rgb slides + if(isNegative) invert(frame, z, i); // if is negative + } + } + for(int i = 0; i < w; ++i) { + // color direction + if(points[i].c_dir == 0) { + points[i].color += 0.25; + if(points[i].color >= 10) { + points[i].c_dir = 1; + } + } else if(points[i].c_dir == 1) { + points[i].color -= 0.25; + if(points[i].color <= 1) { + points[i].c_dir = 0; + } + } + } +} + +void ac::VerticalSort(cv::Mat &frame) { + int w = frame.cols;// frame width + int h = frame.rows;// frame height + static std::vector v;// static vector of int + v.reserve(w);// reserve w bytes + for(int i = 0; i < w; ++i) { // top to bottom + for(int z = 0; z < h; ++z) { // left to right + //int value = frame.at(z, i); + // grab pixel reference + + swapColors(frame, z, i);// swap colors for rgb sliders + if(isNegative) invert(frame, z, i); // if is negative + + cv::Vec3b &value = frame.at(z, i); + unsigned int vv = 0; + // unsigned char * of vv + unsigned char *cv = (unsigned char*)&vv; + // set RGB values + cv[0] = value[0]; + cv[1] = value[1]; + cv[2] = value[2]; + cv[3] = 0; + // push back into vector v + v.push_back(vv); + } + // sort vector v + std::sort(v.begin(), v.end()); + for(int q = 0; q < h; ++q) {// left to right + // unsigned char pointer of vector v at index i + unsigned char *value = (unsigned char*)&v[q]; + // get pixel reference + cv::Vec3b &pixel = frame.at(q, i); + // add to pixel without scaling + pixel[0] = value[0]; + pixel[1] = value[1]; + pixel[2] = value[2]; + + } + v.erase(v.begin(), v.end()); + } +} + +void ac::VerticalChannelSort(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + std::vector pixels[3]; + for(int i = 0; i < w; ++i) { + for(int z = 0; z < h; ++z) { + + swapColors(frame, z, i);// swap colors for rgb sliders + if(isNegative) invert(frame, z, i); // if is negative + + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) + pixels[j].push_back(pixel[j]); + } + + for(int j = 0; j < 3; ++j) + std::sort(pixels[j].begin(), pixels[j].end()); + + for(int z = 0; z < h; ++z) { + cv::Vec3b &pixel = frame.at(z, i); + pixel[0] = pixels[0][z]; + pixel[1] = pixels[1][z]; + pixel[2] = pixels[2][z]; + } + for(int j = 0; j < 3; ++j) + if(!pixels[j].empty()) + pixels[j].erase(pixels[j].begin(), pixels[j].end()); + } + +} + +void ac::HorizontalBlend(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + static double alpha[3] = {1,8,16}; + for(int i = 0; i < w; ++i) { + for(int z = 0; z < h; ++z) { + cv::Vec3b &pixel = frame.at(z, i); + pixel[0] = static_cast(pixel[0] * alpha[0]); + pixel[1] = static_cast(pixel[1] * alpha[1]); + pixel[2] = static_cast(pixel[2] * alpha[2]); + + swapColors(frame, z, i);// swap colors for rgb sliders + if(isNegative) invert(frame, z, i); // if is negative + } + if((rand()%4)==0) { + for(int i = 0; i < 3; ++i) { + alpha[i] += 0.1; + if(alpha[i] > 25) alpha[i] = 1; + } + } + } +} + +void ac::VerticalBlend(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + static double alpha[3] = {1,8,16}; + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + pixel[0] = static_cast(pixel[0] * alpha[0]); + pixel[1] = static_cast(pixel[1] * alpha[1]); + pixel[2] = static_cast(pixel[2] * alpha[2]); + + swapColors(frame, z, i);// swap colors for rgb sliders + if(isNegative) invert(frame, z, i); // if is negative + } + if((rand()%4)==0) { + for(int i = 0; i < 3; ++i) { + alpha[i] += 0.1; + if(alpha[i] > 25) alpha[i] = 1; + } + } + } +} + diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter4.cpp b/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter4.cpp new file mode 100755 index 0000000..dc24e16 --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter4.cpp @@ -0,0 +1,1241 @@ +/* + * Software written by Jared Bruni https://github.com/lostjared + + This software is dedicated to all the people that experience mental illness. + + Website: http://lostsidedead.com + YouTube: http://youtube.com/LostSideDead + Instagram: http://instagram.com/jaredbruni + Twitter: http://twitter.com/jaredbruni + Facebook: http://facebook.com/LostSideDead0x + + You can use this program free of charge and redistrubute it online as long + as you do not charge anything for this program. This program is meant to be + 100% free. + + BSD 2-Clause License + + Copyright (c) 2019, Jared Bruni + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + */ + +#include "ac.h" +#include "fractal.h" + + +void ac::OppositeBlend(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + cv::Mat temp = frame.clone(); + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w-1; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b temp_pixel = temp.at(z, w-i-1); + pixel[0] = static_cast((pixel[0]+temp_pixel[0])); + pixel[1] = static_cast((pixel[1]+temp_pixel[1])); + pixel[2] = static_cast((pixel[2]+temp_pixel[2])); + swapColors(frame, z, i);// swap colors for rgb sliders + if(isNegative) invert(frame, z, i); // if is negative + } + } +} + +void ac::DiagonalLines(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + cv::Mat temp = frame.clone(); + static double pos = 1.0; + + for(int i = 0; i < w-1; ++i) { + for(int z = 0; z < h-1; ++z) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b temp_pixel = temp.at(h-z-1, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = static_cast((pixel[j]+temp_pixel[j])+pos); + ++pos; + if(pos > 100) pos = 0; + } + swapColors(frame, z, i);// swap colors for rgb sliders + if(isNegative) invert(frame, z, i); // if is negative + } + } +} + +void ac::HorizontalLines(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + static double pos[3] = {1.0, 16.0, 32.0}; + + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = static_cast(pixel[j] + pos[j]); + pos[j] += 0.1; + if(pos[j] > 100) + pos[j] = 0; + + } + swapColors(frame, z, i);// swap colors for rgb sliders + if(isNegative) invert(frame, z, i); // if is negative + } + } +} + +void ac::InvertedScanlines(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + + static int index = 0; + static double alpha = 1.0; + static double pos_max = 14.0; + + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + switch(index) { + case 0: { + for(int j = 0; j < 3; ++j) + pixel[j] = static_cast((~pixel[j])*alpha); + index++; + } + case 1: { + cv::Vec3b temp = pixel; + pixel[0] = static_cast(temp[2]*alpha); + pixel[1] = static_cast(temp[1]*alpha); + pixel[2] = static_cast(temp[0]*alpha); + index++; + } + break; + case 2: + index = 0; + break; + } + swapColors(frame, z, i);// swap colors for rgb sliders + if(isNegative) invert(frame, z, i); // if is negative + } + } + + static int direction = 1; + procPos(direction, alpha, pos_max); +} + +void ac::Soft_Mirror(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + static int index = 0; + cv::Mat temp = frame.clone(); + for(int z = 1; z < h-1; ++z) { + for(int i = 1; i < w-1; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + switch(index) { + case 0: + index++; + break; + case 1: { + cv::Vec3b pix = frame.at(h-z-1, w-i-1); + pixel[0] = pix[0]; + pixel[1] = pix[1]; + pixel[2] = pix[2]; + index = 0; + } + break; + } + swapColors(frame, z, i);// swap colors for rgb sliders + if(isNegative) invert(frame, z, i); // if is negative + } + } +} + +void ac::KanapaTrip(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + static int start_index = 0; + int index = start_index; + cv::Mat temp = frame.clone(); + for(int z = 1; z < h-1; ++z) { + for(int i = 1; i < w-1; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + switch(index) { + case 0: + index++; + break; + case 1: { + cv::Vec3b pix = frame.at(h-z-1, w-i-1); + pixel[0] = pix[0]; + pixel[1] = pix[1]; + pixel[2] = pix[2]; + index = 0; + } + break; + } + swapColors(frame, z, i);// swap colors for rgb sliders + if(isNegative) invert(frame, z, i); // if is negative + } + } + if(start_index == 0) + start_index = 1; + else + start_index = 0; +} + +void ac::ColorMorphing(cv::Mat &frame) { + KanapaTrip(frame); + SidewaysMirror(frame); +} + + +void ac::ScanSwitch(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + static int start_index = 0; + int index = start_index; + for(int z = 3; z < h-3; ++z) { + for(int i = 3; i < w-3; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + switch(index) { + case 0: + index++; + break; + case 1: { + pixel[0] = ~pixel[0]; + pixel[1] = ~pixel[1]; + pixel[2] = ~pixel[2]; + index = 0; + } + break; + } + swapColors(frame, z, i);// swap colors for rgb sliders + if(isNegative) invert(frame, z, i); // if is negative + } + } + if(start_index == 0) + start_index = 1; + else + start_index = 0; +} + + +void ac::ScanAlphaSwitch(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + static int start_index = 0; + static double alpha = 1.0, alpha_max = 10.0; + int index = start_index; + for(int z = 3; z < h-3; ++z) { + for(int i = 3; i < w-3; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + switch(index) { + case 0: + index++; + pixel[0] = ~pixel[0]; + pixel[1] = ~pixel[1]; + pixel[2] = ~pixel[2]; + break; + case 1: { + pixel[0] += static_cast(pixel[0]*alpha); + pixel[1] += static_cast(pixel[1]*alpha); + pixel[2] += static_cast(pixel[2]*alpha); + index = 0; + } + break; + } + swapColors(frame, z, i);// swap colors for rgb sliders + if(isNegative) invert(frame, z, i); // if is negative + } + } + if(start_index == 0) + start_index = 1; + else + start_index = 0; + + static int direction = 1; + procPos(direction, alpha, alpha_max); +} + +void ac::NegativeStrobe(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + static int flash = 1; + if(flash == 1) { + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + pixel[0] = ~pixel[0]; + pixel[1] = ~pixel[1]; + pixel[2] = ~pixel[2]; + } + } + } + if(flash == 1) { + flash = 0; + } else { + flash = 1; + } +} + +void ac::XorAddMul(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame heigh + static double blend = 1.0, blend_max = 13.0; + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + int b = static_cast(blend); + pixel[0] += static_cast(pixel[0]^b); + pixel[1] += static_cast(pixel[1]+b); + pixel[2] += static_cast(pixel[2]*b); + swapColors(frame, z, i);// swap colors for rgb sliders + if(isNegative) invert(frame, z, i); // if is negative + } + } + static int direction = 1; + procPos(direction, blend, blend_max); + //if(blend > 255) blend = 1.0; +} + + +void ac::BlendSwitch(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame heigh + static int pos = 0; + static unsigned char blend_pixel = 0; + for(int i = 0; i < w; ++i) { + for(int z = 0; z < h; ++z) { + cv::Vec3b &pixel = frame.at(z, i); + pixel[pos] *= blend_pixel++; + swapColors(frame, z, i);// swap colors for rgb sliders + if(isNegative) invert(frame, z, i); // if is negative + } + pos++; + if(pos > 2) pos = 0; + } +} + +// set all color components other than red to zero +void ac::AllRed(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame heigh + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + pixel[0] = pixel[1] = 0; + } + } +} +// set all color components other than green to zero +void ac::AllGreen(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame heigh + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + pixel[0] = pixel[2] = 0; + } + } +} +// set all color components other than blue to zero +void ac::AllBlue(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame heigh + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + pixel[2] = pixel[1] = 0; + } + } +} +// set colors to zero based on counter +// increment counter after each nested loop +void ac::LineRGB(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame heigh + static int counter = 0; + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + switch(counter) { + case 0: + pixel[0] = pixel[1] = 0; + break; + case 1: + pixel[0] = pixel[2] = 0; + break; + case 2: + pixel[2] = pixel[1] = 0; + break; + } + swapColors(frame, z, i);// swap colors for rgb sliders + if(isNegative) invert(frame, z, i); // if is negative + } + ++counter; + if(counter > 2) counter = 0; + } +} +// set colors to zero based on counter +// increment counter each iteration of nested loop +void ac::PixelRGB(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame heigh + static int counter = 0; + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + switch(counter) { + case 0: + pixel[0] = pixel[1] = 0; + break; + case 1: + pixel[0] = pixel[2] = 0; + break; + case 2: + pixel[2] = pixel[1] = 0; + break; + } + swapColors(frame, z, i);// swap colors for rgb sliders + if(isNegative) invert(frame, z, i); // if is negative + ++counter; + if(counter > 2) counter = 0; + } + } +} + +// Boxed RGB +void ac::BoxedRGB(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame heigh + static int row_counter = 0; // row counter + + for(int z = 0; z < h; ++z) { // from top to bottom + for(int i = 0; i < w; ++i) { // from left to right + cv::Vec3b &pixel = frame.at(z, i); // pixel + switch(row_counter) {// row counter iterate between red,green,and blue + case 0: + pixel[0] = pixel[1] = 0; // red + break; + case 1: + pixel[0] = pixel[2] = 0; // green + break; + case 2: + pixel[2] = pixel[1] = 0; // blue + break; + } + swapColors(frame, z, i);// swap colors for rgb sliders + if(isNegative) invert(frame, z, i); // if is negative + } + // if z is evenly divideable by 32 + if((z%32) == 0) { + ++row_counter;// increment row counter + if(row_counter > 3) row_counter = 0; + } + } +} + +// joke filter +// color the image with red/green bars switching color each frame +void ac::KruegerSweater(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame heigh + static int row_counter = 0;// row counter + static int rg = 0;// row counter start variable + row_counter = rg; // set row counter to start + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + // set the colors other than red or green to zero based on row counter + switch(row_counter) { + case 0: + pixel[0] = pixel[1] = 0; // red + break; + case 1: + pixel[0] = pixel[2] = 0; // green + break; + } + swapColors(frame, z, i);// swap colors for rgb sliders + if(isNegative) invert(frame, z, i); // if is negative + } + if((z%32) == 0) { + ++row_counter; // increment row counter + if(row_counter >= 2) { // if greater than or equal 2 + row_counter = 0; // set to row_counter to zero + } + } + } + rg = (rg == 0) ? 1 : 0; // swap back and forth rg between zero and one. +} + +void ac::RGBFlash(cv::Mat &frame) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame heigh + static int counter = 0; // counter for setting the pixel + static int start = 0; // start position + for(int z = start; z < h; z += 2) { // top to bottom, skipping 1 each time + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + // set pixel a certain color based on the counter + switch(counter) { + case 0: + pixel[2] = 255;// set red + break; + case 1: + pixel[1] = 255; // set green + break; + case 2: + pixel[0] = 255;// set blue + break; + } + swapColors(frame, z, i);// swap colors for rgb sliders + if(isNegative) invert(frame, z, i); // if is negative + } + } + ++counter;// increment counter + if(counter > 2) counter = 0; // if greater than 2 reset to zero + start = (start == 0) ? 1 : 0; // swap start back and forth between 0 and 1 +} + +void ac::IncreaseBlendHorizontal(cv::Mat &frame) { + ac::orig_frame = frame.clone(); + const int w = frame.cols; + const int h = frame.rows; + for(int i = 0; i < w; ++i) { + cv::Vec3b pix; + for(int z = 0; z < h; ++z) { + cv::Vec3b &pixel = frame.at(z, i); + pix[0] += pixel[0]/2; + pix[1] += pixel[1]/4; + pix[2] += pixel[2]/6; + pixel[0] += pixel[0] * (pix[0]/32); + pixel[1] += pixel[1] * (pix[1]/32); + pixel[2] += pixel[2] * (pix[2]/32); + swapColors(frame, z, i);// swap colors for rgb sliders + if(isNegative) invert(frame, z, i); // if is negative + } + } + ac::pass2_alpha = 0.75; + Pass2Blend(frame); +} +// blend increase +void ac::BlendIncrease(cv::Mat &frame) { + static int blend_r = rand()%255, blend_g = rand()%255, blend_b = rand()%255; + static bool cblend_r = true, cblend_g = true, cblend_b = true; + static int increase_value_r = 2, increase_value_g = 2, increase_value_b = 2; + const int w = frame.cols; + const int h = frame.rows; + if(blend_r > 255) { + blend_r = rand()%255; + if(cblend_r == true) { + blend_r = -blend_r; + cblend_r = false; + } else { + cblend_r = true; + } + } + if(blend_g > 255) { + blend_g = rand()%255; + if(cblend_g == true) { + blend_g = -blend_g; + cblend_g = false; + } else { + cblend_g = true; + } + } + if(blend_b > 255) { + blend_b = rand()%255; + if(cblend_b == true) { + blend_b = -blend_b; + cblend_b = false; + } else { + cblend_b = true; + } + } + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + pixel[2] += static_cast(blend_r); + pixel[1] += static_cast(blend_g); + pixel[0] += static_cast(blend_b); + swapColors(frame, z, i);// swap colors for rgb sliders + if(isNegative) invert(frame, z, i); // if is negative + } + } + blend_r += increase_value_r; + blend_g += increase_value_g; + blend_b += increase_value_b; + increase_value_r += rand()%5; + increase_value_g += rand()%5; + increase_value_b += rand()%5; + if(increase_value_r > 20) { + increase_value_r = 2; + } + if(increase_value_g > 20) { + increase_value_g = 2; + } + if(increase_value_b > 20) { + increase_value_b = 2; + } +} + +void ac::GradientReverse(cv::Mat &frame) { + const int w = frame.cols; + const int h = frame.rows; + static bool direction = true; + static double alpha = 1.0, alpha_max = 8; + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + if(direction == true) + pixel[j] += static_cast(i*alpha); + else + pixel[j] -= static_cast(i*alpha); + } + ac::swapColors(frame, z, i); + if(isNegative) ac::invert(frame, z, i); + } + direction = (direction == true) ? false : true; + } + static int direction_ = 1; + procPos(direction_, alpha, alpha_max); +} + +void ac::GradientReverseBox(cv::Mat &frame) { + const int w = frame.cols; + const int h = frame.rows; + static bool direction = true; + static double alpha = 1.0, alpha_max = 8; + for(int i = 0; i < w; ++i) { + for(int z = 0; z < h; ++z) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + if(direction == true) + pixel[j] += static_cast((i*alpha)); + else + pixel[j] -= static_cast((z*alpha)); + } + ac::swapColors(frame, z, i); + if(isNegative) ac::invert(frame, z, i); + } + direction = (direction == true) ? false : true; + } + static int direction_ = 1; + procPos(direction_, alpha, alpha_max); +} + +void ac::GradientReverseVertical(cv::Mat &frame) { + const int w = frame.cols; + const int h = frame.rows; + static bool direction = true; + static double alpha = 1.0, alpha_max = 8; + for(int i = 0; i < w; ++i) { + for(int z = 0; z < h; ++z) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + if(direction == true) + pixel[j] += static_cast((z*alpha)); + else + pixel[j] -= static_cast((z*alpha)); + } + ac::swapColors(frame, z, i); + if(isNegative) ac::invert(frame, z, i); + } + direction = (direction == true) ? false : true; + } + static int direction_ = 1; + procPos(direction_, alpha, alpha_max); +} + +void ac::GradientNewFilter(cv::Mat &frame) { + const int w = frame.cols; + const int h = frame.rows; + static int index = 0; + static double alpha = 1.0, alpha_max = 9; + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + switch(index) { + case 0: + pixel[j] = static_cast((pixel[j] ^ (int)(alpha*z))); + break; + case 1: + pixel[j] = static_cast((pixel[j] & (int)(alpha*i))); + break; + case 2: + pixel[j] = static_cast((pixel[j] ^ (int)alpha)); + break; + } + } + ac::swapColors(frame, z, i); + if(isNegative) ac::invert(frame, z, i); + ++index; + if(index > 2) index = 0; + } + } + static int direction_ = 1; + procPos(direction_, alpha, alpha_max); +} + +void ac::ReinterpretDouble(cv::Mat &frame) { + const int w = frame.cols; + const int h = frame.rows; + static double alpha = 1.0, alpha_max = 8; + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + unsigned char *value = reinterpret_cast(&alpha); + for(int j = 0; j < 3; ++j) + pixel[j] = cv::saturate_cast(pixel[j] ^ value[j]); + + ac::swapColors(frame, z, i); + if(isNegative) ac::invert(frame, z, i); + } + } + static int direction_ = 1; + procPos(direction_, alpha, alpha_max); +} + + +void ac::ReinterpSelfScale(cv::Mat &frame) { + const int w = frame.cols; + const int h = frame.rows; + static int index = 0; + static double alpha = 1.0, alpha_max = 8; + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + unsigned char *value = reinterpret_cast(&alpha); + switch(index) { + case 0: { + pixel[0] = static_cast(pixel[0]*alpha)^value[0]; + pixel[1] = static_cast(pixel[1]*alpha); + pixel[2] = static_cast(pixel[2]*alpha); + } + break; + case 1: { + pixel[0] = static_cast(pixel[0]*alpha); + pixel[1] = static_cast(pixel[0]*alpha)^value[1]; + pixel[2] = static_cast(pixel[2]*alpha); + } + break; + case 2: { + pixel[0] = static_cast(pixel[0]*alpha); + pixel[1] = static_cast(pixel[1]*alpha); + pixel[2] = static_cast(pixel[2]*alpha)^value[2]; + } + break; + } + ac::swapColors(frame, z, i); + if(isNegative) ac::invert(frame, z, i); + } + ++index; + if(index > 2) index = 0; + } + static int direction_ = 1; + procPos(direction_, alpha, alpha_max); +} + +void ac::AverageLines(cv::Mat &frame) { + const int w = frame.cols; + const int h = frame.rows; + unsigned char average[3]; + static double alpha = 1.0, alpha_max = 11; + for(int z = 0; z < h; ++z) { + cv::Scalar s(1,1,1); + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + s[0] += pixel[0]; + s[1] += pixel[1]; + s[2] += pixel[2]; + pixel[0] = static_cast((pixel[0]^average[0])*alpha); + pixel[1] = static_cast((pixel[1]^average[1])*alpha); + pixel[2] = static_cast((pixel[2]^average[2])*alpha); + ac::swapColors(frame, z, i); + if(isNegative) ac::invert(frame, z, i); + } + average[0] = cv::saturate_cast((s[0]/w)); + average[1] = cv::saturate_cast((s[1]/w)); + average[2] = cv::saturate_cast((s[2]/w)); + } + int direction = 1; + procPos(direction, alpha, alpha_max); +} + + + +void ac::ColorRange(cv::Mat &frame) { + const int w = frame.cols; + const int h = frame.rows; + static double alpha = 1.0, alpha_max = 6; + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] = static_cast((pixel[j]+colors[j])*alpha); + } + } + static int direction[3] = {1, 0, 1}; + for(int j = 0; j < 3; ++j) { + if(direction[j] == 1) { + colors[j] ++; + if(colors[j] >= 255) { + direction[j] = 0; + colors[j] = 255; + } + } else if(direction[j] == 0) { + colors[j] --; + if(colors[j] <= 0) { + direction[j] = 1; + colors[j] = 0; + } + } + } + + static int _direction = 1; + procPos(_direction, alpha, alpha_max); +} + + +void ac::TrailsInter(cv::Mat &frame) { + static MatrixCollection<8> collection; + collection.shiftFrames(frame); + static int counter = 0; + const int w = frame.cols;// frame width + const int h = frame.rows;// frame heigh + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + pixel = collection.frames[counter+1].at(z, i); + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + ++counter; + if(counter > 5) counter = 0; + } +} + +void ac::TrailsBlend(cv::Mat &frame) { + static MatrixCollection<8> collection; + cv::Mat new_frame = frame.clone(); + ac::SelfAlphaBlend(new_frame); + collection.shiftFrames(new_frame); + static int counter = 0; + const int w = frame.cols;// frame width + const int h = frame.rows;// frame heigh + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + pixel = collection.frames[counter].at(z, i); + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + ++counter; + if(counter >= 5) counter = 0; + } +} + +void ac::TrailsNegate(cv::Mat &frame) { + static MatrixCollection<8> collection; + static int index = 0; + cv::Mat new_frame = frame.clone(); + if(index == 0) { + ac::Negate(new_frame); + index = 1; + } else { + index = 0; + } + collection.shiftFrames(new_frame); + static int counter = 0; + const int w = frame.cols;// frame width + const int h = frame.rows;// frame heigh + for(int z = 0; z < h-1; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + pixel = collection.frames[counter].at(z, i); + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + ++counter; + if(counter >= 5) counter = 0; + } +} + +void ac::InterReverse(cv::Mat &frame) { + const int w = frame.cols; + const int h = frame.rows; + bool get_value = true; + static bool value_start = true; + get_value = value_start; + cv::Mat frame_copy = frame.clone(); + for(int z = 2; z < h-2; ++z) { + for(int i = 2; i < w-2; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + if(get_value == true) { + cv::Vec3b value; + value = frame_copy.at(h-z-1, i); + pixel = value; + } + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + get_value = (get_value == true) ? false : true; + } + value_start = (value_start == true) ? false : true; +} + +void ac::InterMirror(cv::Mat &frame) { + const int w = frame.cols; + const int h = frame.rows; + bool get_value = true; + static bool value_start = true; + get_value = value_start; + cv::Mat frame_copy = frame.clone(); + for(int z = 2; z < h-2; ++z) { + for(int i = 2; i < w-2; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + if(get_value == true) { + cv::Vec3b value; + value = frame_copy.at(h-z-1, i); + cv::Vec3b value2; + value2 = frame_copy.at(z, w-i-1); + cv::Vec3b value3; + value3 = frame_copy.at(h-z-1, w-i-1); + pixel[0] = static_cast(value[0]+value2[0]+value3[0]); + pixel[1] = static_cast(value[1]+value2[1]+value3[1]); + pixel[2] = static_cast(value[2]+value2[2]+value3[2]); + } + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + get_value = (get_value == true) ? false : true; + } + value_start = (value_start == true) ? false : true; +} + +void ac::InterFullMirror(cv::Mat &frame) { + const int w = frame.cols; + const int h = frame.rows; + int index = 0; + cv::Mat frame_copy = frame.clone(); + for(int z = 2; z < h-2; ++z) { + for(int i = 2; i < w-2; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + switch(index) { + case 0: + continue; + case 1: + pixel = frame_copy.at(h-z-1, i); + break; + case 2: + pixel = frame_copy.at(z, w-i-1); + break; + case 3: + pixel = frame_copy.at(h-z-1, w-i-1); + break; + } + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + ++index; + if(index > 3) index = 0; + } +} + +void ac::MirrorRGB(cv::Mat &frame) { + const int w = frame.cols; + const int h = frame.rows; + cv::Mat frame_copy = frame.clone(); + for(int z = 2; z < h-2; ++z) { + for(int i = 2; i < w-2; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b frame_pixels[4] = {frame_copy.at(h-z-1, i), frame_copy.at(z, w-i-1), frame_copy.at(h-z-1, w-i-1)}; + for(int j = 0; j < 3; ++j) { + pixel[j] += static_cast(frame_pixels[j][j]); + } + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } +} + +void ac::RGBStatic1(cv::Mat &frame) { + const int w = frame.cols; + const int h = frame.rows; + static double pos = 0.25; + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b add(rand()%255, rand()%255, rand()%255); + for(int j = 0; j < 3; ++j) + pixel[j] += static_cast(add[j] * pos); + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } + static int direction = 1; + static double direction_max = 0.4; + if(direction == 1) { + pos += 0.005; + if(pos > direction_max) { + direction = 0; + direction_max += 0.05; + if(direction_max >= 0.8) { + direction_max = 0.5; + } + } + } else if(direction == 0) { + pos -= 0.005; + if(pos <= 0.25) + direction = 1; + } +} + +void ac::RGBStatic2(cv::Mat &frame) { + const int w = frame.cols; + const int h = frame.rows; + static double pos = 0.05; + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b add(rand()%255, rand()%255, rand()%255); + for(int j = 0; j < 3; ++j) + pixel[j] += static_cast(add[j] * pos); + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } + static int direction = 1; + static double direction_max = 0.4; + if(direction == 1) { + pos += 0.005; + if(pos > direction_max) { + direction = 0; + direction_max += 0.05; + if(direction_max >= 0.9) { + direction_max = 0.4; + } + } + } else if(direction == 0) { + pos -= 0.05; + if(pos <= 0.05) + direction = 1; + } + +} + +void ac::VectorIncrease(cv::Mat &frame) { + const int w = frame.cols; + const int h = frame.rows; + static double pos = 0.25; + static cv::Vec3b value(rand()%255, rand()%255, rand()%255); + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] = static_cast((pixel[j]*value[j]) * pos); + + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } + for(int j = 0; j < 3; ++j) + value[j] += rand()%8; +} + +void ac::LineByLineReverse(cv::Mat &frame) { + const int w = frame.cols; + const int h = frame.rows; + bool rev = false; + cv::Mat frame_copy = frame.clone(); + for(int z = 0; z < h; ++z) { + for(int i = 2; i < w-2; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + if(rev == true) + break; + else + pixel = frame_copy.at(z, (w-i-1)); + + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + rev = (rev == true) ? false : true; + } +} + +void ac::RandomIntertwine(cv::Mat &frame) { + cv::Mat frame1 = frame.clone(), frame2 = frame.clone(); + randomFilter(frame1); + randomFilter(frame2); + const int w = frame.cols; + const int h = frame.rows; + bool rev = false; + for(int z = 0; z < h; ++z) { + for(int i = 2; i < w-2; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + if(rev == true) + pixel = frame1.at(z, i); + else + pixel = frame2.at(z, (w-i-1)); + + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + rev = (rev == true) ? false : true; + } +} + +void ac::RandomFour(cv::Mat &frame) { + cv::Mat frames[4]; + frames[0] = frame; + for(int j = 1; j < 4; ++j) { + frames[j] = frame.clone(); + randomFilter(frames[j]); + } + const int w = frame.cols, h = frame.rows; + static int row = 0; + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + if(row == 0) break; + else { + pixel = frames[row].at(z, i); + } + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + ++row; + if(row > 3) row = 0; + } +} + +void ac::BlendThree(cv::Mat &frame) { + static double pos = 1.0, pos_max = 8.0; + cv::Mat frames[3]; + frames[0] = frame; + for(int j = 1; j < 3; ++j) { + frames[j] = frame.clone(); + randomFilter(frames[j]); + } + const int w = frame.cols, h = frame.rows; + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b values[4]; + for(int j = 0; j < 3; ++j) + values[j] = frames[j].at(z, i); + + pixel[0] = values[0][0] + values[1][0] + values[2][0]; + pixel[1] = values[0][1] + values[1][1] + values[2][1]; + pixel[2] = values[0][2] + values[1][2] + values[2][2]; + + for(int j = 0; j < 3; ++j) { + pixel[j] /= 3; + pixel[j] *= static_cast(pos); + } + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } + + static int direction = 1; + procPos(direction, pos, pos_max); +} + +void ac::AcidTrails(cv::Mat &frame) { + const int w = frame.cols, h = frame.rows; + cv::Mat frame_copies[3]; + + for(int j = 0; j < 3; ++j) + frame_copies[j] = frame.clone(); + + ac::SelfScale(frame_copies[0]); + ac::TrailsInter(frame_copies[0]); + ac::Type(frame_copies[1]); + ac::Outward(frame_copies[2]); + + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b copy1 = frame_copies[0].at(z, i); + cv::Vec3b copy2 = frame_copies[1].at(z, i); + cv::Vec3b copy3 = frame_copies[2].at(z, i); + cv::Vec3b value; + for(int j = 0; j < 3; ++j) { + pixel[j] = static_cast(((copy1[j] ^ copy2[j]) + copy3[j])); + } + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } +} + +void ac::RandomTwo(cv::Mat &frame) { + cv::Mat frames[2]; + frames[0] = frame.clone(); + frames[1] = frame.clone(); + randomFilter(frames[0]); + randomFilter(frames[1]); + static int index = 0; + int w = frame.cols, h = frame.rows; + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + pixel = frames[index].at(z, i); + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + ++index; + if(index > 1) index = 0; + } +} + +void ac::HorizontalTrailsInter(cv::Mat &frame) { + static MatrixCollection<8> collection; + collection.shiftFrames(frame); + static int counter = 0; + const int w = frame.cols;// frame width + const int h = frame.rows;// frame heigh + for(int i = 0; i < w; ++i) { + for(int z = 0; z < h; ++z) { + cv::Vec3b &pixel = frame.at(z, i); + pixel = collection.frames[counter].at(z, i); + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + ++counter; + if(counter >= 3) counter = 0; + } +} + +void ac::Trails(cv::Mat &frame) { + TrailsInter(frame); + HorizontalTrailsInter(frame); +} + +void ac::BlendTrails(cv::Mat &frame) { + Negate(frame); + rainbowBlend(frame); + Trails(frame); +} + diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter5.cpp b/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter5.cpp new file mode 100755 index 0000000..7936f7c --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter5.cpp @@ -0,0 +1,1275 @@ +/* + * Software written by Jared Bruni https://github.com/lostjared + + This software is dedicated to all the people that experience mental illness. + + Website: http://lostsidedead.com + YouTube: http://youtube.com/LostSideDead + Instagram: http://instagram.com/jaredbruni + Twitter: http://twitter.com/jaredbruni + Facebook: http://facebook.com/LostSideDead0x + + You can use this program free of charge and redistrubute it online as long + as you do not charge anything for this program. This program is meant to be + 100% free. + + BSD 2-Clause License + + Copyright (c) 2019, Jared Bruni + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + */ + + +#include"ac.h" + +void ac::RandomFilteredSquare(cv::Mat &frame) { + static std::unique_ptr boxes; + int num_boxes = static_cast(frame.cols/0.5); + if(boxes == 0 || (frame.cols != Box::frame_width)) { + boxes.reset(new Box[num_boxes]); + Box::frame_width = frame.cols; + Box::frame_height = frame.rows; + for(int i = 0; i < num_boxes; ++i) + boxes.get()[i].initBox(frame.cols, frame.rows); + } + + for(int i = 0; i < num_boxes; ++i) { + boxes.get()[i].sizeBox(); + boxes.get()[i].drawBox(frame); + } +} + +void ac::RandomQuads(cv::Mat &frame) { + static MatrixCollection<8> collection; + collection.shiftFrames(frame); + for(int j = 0; j < 4; ++j) { + int frame_index = 0; + do { + frame_index = rand()%28; + } while(frame_index == 13 || frame_index == 14); + CallFilter(frame_index, collection.frames[j]); + } + cv::Size quarter(frame.cols/2, frame.rows/2); + ac::copyMat(collection.frames[0],0, 0, frame, ac::Rect(0, 0, quarter)); + ac::copyMat(collection.frames[1],frame.cols/2, 0, frame, ac::Rect(frame.cols/2,0, quarter)); + ac::copyMat(collection.frames[2],frame.cols/2, frame.rows/2, frame, ac::Rect(frame.cols/2, frame.rows/2, quarter)); + ac::copyMat(collection.frames[3],0, frame.rows/2, frame, ac::Rect(0,frame.rows/2, quarter)); +} + +void ac::QuadCosSinMultiply(cv::Mat &frame) { + cv::Mat frame_copy = frame.clone(); + cv::Size quarter(frame.cols/2, frame.rows/2); + DrawFunction procFunc = getFilter(ac::draw_strings[15]); + procFunc(frame_copy); + procFunc(frame_copy); + ac::copyMat(frame_copy,0, 0, frame, ac::Rect(0, 0, quarter)); + procFunc(frame_copy); + ac::copyMat(frame_copy,frame.cols/2, 0, frame, ac::Rect(frame.cols/2,0, quarter)); + procFunc(frame_copy); + ac::copyMat(frame_copy,frame.cols/2, frame.rows/2, frame, ac::Rect(frame.cols/2, frame.rows/2, quarter)); + procFunc(frame_copy); + ac::copyMat(frame_copy,0, frame.rows/2, frame, ac::Rect(0,frame.rows/2, quarter)); +} + +void ac::QuadRandomFilter(cv::Mat &frame) { + + if(testSize(frame) == false) + return; + + cv::Mat frame_copy = frame.clone(); + cv::Size quarter(frame.cols/2, frame.rows/2); + int base_index = 0, index = 0; + DrawFunction baseFilter = getRandomFilter(base_index); + baseFilter(frame_copy); + DrawFunction procFunc = getRandomFilter(index); + procFunc(frame_copy); + ac::copyMat(frame_copy,0, 0, frame, ac::Rect(0, 0, quarter)); + procFunc(frame_copy); + ac::copyMat(frame_copy,frame.cols/2, 0, frame, ac::Rect(frame.cols/2,0, quarter)); + procFunc(frame_copy); + ac::copyMat(frame_copy,frame.cols/2, frame.rows/2, frame, ac::Rect(frame.cols/2, frame.rows/2, quarter)); + procFunc(frame_copy); + ac::copyMat(frame_copy,0, frame.rows/2, frame,ac::Rect(0,frame.rows/2, quarter)); +} + +void ac::RollRandom(cv::Mat &frame) { + + if(testSize(frame) == false) + return; + + SquareVertical_Roll(frame); + int index = 0; + DrawFunction rand_func = getRandomFilter(index); + rand_func(frame); +} + +void ac::AverageRandom(cv::Mat &frame) { + static double alpha = 1.0, alpha_max = 8.0; + cv::Mat frame_copy = frame.clone(), frame_copy2 = frame.clone(); + int index = 0; + DrawFunction func = getRandomFilter(index); + func(frame_copy); + func(frame_copy2); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix1 = frame_copy.at(z, i); + cv::Vec3b pix2 = frame_copy2.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = static_cast(pixel[j] + pix1[j] + pix2[j]); + pixel[j] /= static_cast(1.5); + pixel[j] = static_cast(pixel[j] * (1+alpha)); + } + } + } + static int direction = 1; + procPos(direction, alpha, alpha_max); +} + +void ac::HorizontalStripes(cv::Mat &frame) { + if(frame.empty() || frame.rows < 25 || frame.cols < 25) + return; + static cv::Scalar value(1.0, 1.0, 1.0); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + double rval = rand()%10; + double val = rval * 0.001; + value[j] += val; + if(value[j] > 255) value[j] = 0; + pixel[j] = pixel[j] ^ static_cast(value[j]); + } + } + } + MedianBlur(frame); + Bitwise_XOR(frame); +} + +void ac::DiamondStrobe(cv::Mat &frame) { + static double pos = 1.0;// set pos to 1.0 + int w = frame.cols;// frame width + int h = frame.rows;// frame height + static int index1 = 0, index2 = 2; + + ++index1; + if(index1 > 2) index1 = 0; + ++index2; + if(index2 > 2) index2 = 0; + + for(int z = 0; z < h; ++z) {// from top to bottom + for(int i = 0; i < w; ++i) {// from left to right + cv::Vec3b &buffer = frame.at(z, i);// get current pixel + // calculate the colors of the gradient diamonds + if((i%2) == 0) {// if i % 2 equals 0 + if((z%2) == 0) {// if z % 2 equals 0 + // set pixel component values + buffer[index1] = static_cast(1-pos*buffer[0]); + buffer[index2] = static_cast((i+z)*pos); + } else { + // set pixel coomponent values + buffer[index1] = static_cast(pos*buffer[0]-z); + buffer[index2] = static_cast((i-z)*pos); + } + } else { + if((z%2) == 0) {// if z % 2 equals 0 + // set pixel component values + buffer[index1] = static_cast(pos*buffer[0]-i); + buffer[index2] = static_cast((i-z)*pos); + } else { + // set pixel component values + buffer[index1] = static_cast(pos*buffer[0]-z); + buffer[index2] = static_cast((i+z)*pos); + } + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel + } + } + // static direction starts off with 1 + static double pos_max = 7.0f;// pos maximum + static int direction = 1; + procPos(direction, pos, pos_max); +} + +void ac::SmoothTrails(cv::Mat &frame) { + static MatrixCollection<8> collection; + Smooth(frame, &collection); +} + + +void ac::Dual_SelfAlphaRainbow(cv::Mat &frame) { + static double alpha1 = 2.0, alpha2 = 10.0, pos_max = 10.0; + static bool switch_on = true; + rainbowBlend(frame); + for(int z = 0; z < frame.rows-1; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + if(switch_on == true) { + for(int j = 0; j < 3; ++j) + pixel[j] = static_cast(pixel[j]*alpha1); + } else { + for(int j = 0; j < 3; ++j) + pixel[j] = static_cast(pixel[j]*alpha2); + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel + } + switch_on = !switch_on; + } + static int direction[2] = { 1, 0 }; + procPos(direction[0], alpha1, pos_max); + procPos(direction[1], alpha2, pos_max); +} + +void ac::Dual_SelfAlphaBlur(cv::Mat &frame) { + Dual_SelfAlphaRainbow(frame); + MedianBlur(frame); + MedianBlur(frame); + Bitwise_XOR(frame); +} + +void ac::SurroundPixelXor(cv::Mat &frame) { + static double alpha = 1.0, alpha_max = 4.0; + for(int z = 0; z < frame.rows-3; ++z) { + for(int i = 0; i < frame.cols-3; ++i) { + cv::Vec3b pix[3]; + cv::Vec3b &pixel = frame.at(z, i); + pix[0] = frame.at(z+1, i); + pix[1] = frame.at(z, i+1); + pix[2] = frame.at(z+1, i+1); + cv::Scalar value; + value[0] = pix[0][0]+pix[1][0]+pix[2][0]; + value[1] = pix[0][1]+pix[1][1]+pix[2][1]; + value[3] = pix[0][2]+pix[1][2]+pix[2][2]; + for(int j = 0; j < 3; ++j) { + int val = static_cast(value[j]); + pixel[j] = static_cast((val^pixel[j])*alpha); + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel + } + } + static int direction = 1; + procPos(direction, alpha, alpha_max); +} + +void ac::Darken(cv::Mat &frame) { + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + pixel[0] /= 6; + pixel[1] /= 6; + pixel[2] /= 6; + } + } +} + +void ac::WeakBlend(cv::Mat &frame) { + static int index = 0; + static cv::Scalar value((rand()%5)+1,(rand()%5)+1,(rand()%5)+1); + for(int i = 0; i < frame.cols; ++i) { + for(int z = 0; z < frame.rows; ++z) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + int val = static_cast(pixel[j]+(pixel[j]*value[index])); + val /= 2; + pixel[j] = static_cast(val); + } + index ++; + if(index > 2) + index = 0; + + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel + } + } + for(int j = 0; j < 3; ++j) { + value[j] += 1+((rand()%5) * 0.5); + if(value[j] > 10) { + value[j] = rand()%10; + } + } +} + +void ac::AverageVertical(cv::Mat &frame) { + static double alpha = 1.0, alpha_max = 8.0; + std::unique_ptr values(new cv::Scalar[frame.rows]); + for(int i = 0; i < frame.cols; ++i) { + for(int z = 0; z < frame.rows; ++z) { + cv::Vec3b pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) + values.get()[z][j] += pixel[j]; + } + } + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Scalar val = values.get()[z]; + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + val[j] /= frame.rows; + pixel[j] += static_cast(val[j]*alpha); + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel + } + } + static int direction = 1; + procPos(direction, alpha, alpha_max); +} + + +void ac::RandomCollectionAverage(cv::Mat &frame) { + + if(testSize(frame) == false) + return; + + static MatrixCollection<8> collection; + int index = 0; + DrawFunction randF = getRandomFilter(index); + randF(frame); + Smooth(frame, &collection); +} + +void ac::RandomCollectionAverageMax(cv::Mat &frame) { + + if(testSize(frame) == false) + return; + + static MatrixCollection<16> collection; + int index = 0; + DrawFunction randF = getRandomFilter(index); + randF(frame); + Smooth(frame, &collection); +} + +void ac::SmoothTrailsSelfAlphaBlend(cv::Mat &frame) { + static MatrixCollection<8> collection; + MedianBlur(frame); + SelfAlphaBlend(frame); + Smooth(frame, &collection); +} + +void ac::SmoothTrailsRainbowBlend(cv::Mat &frame) { + static MatrixCollection<8> collection; + MedianBlur(frame); + rainbowBlend(frame); + Smooth(frame, &collection); +} + +void ac::MedianBlend(cv::Mat &frame) { + static MatrixCollection<8> collection; + int r = 3+rand()%7; + for(int i = 0; i < r; ++i) + MedianBlur(frame); + + collection.shiftFrames(frame); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Scalar value; + for(int j = 0; j < collection.size(); ++j) { + cv::Vec3b pixel = collection.frames[j].at(z, i); + for(int q = 0; q < 3; ++q) { + value[q] += pixel[q]; + } + } + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + int val = 1+static_cast(value[j]); + pixel[j] = static_cast(pixel[j] ^ val); + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } +} + + + + +void ac::RandomAlphaBlend(cv::Mat &frame) { + static MatrixCollection<8> collection; + double alpha = 1.0, alpha_max = 6.0; + int index = 0; + + if(testSize(frame) == false) + return; + + DrawFunction randFunc = getRandomFilter(index); + cv::Mat temp = frame.clone(), rand_frame = frame.clone(); + randFunc(rand_frame); + collection.shiftFrames(rand_frame); + AlphaBlend(temp,rand_frame, frame, alpha); + Smooth(frame, &collection); + static int direction = 1; + procPos(direction, alpha, alpha_max); +} + +void ac::RandomTwoFilterAlphaBlend(cv::Mat &frame) { + /* + static double alpha = 1.0, alpha_max = 5.0; + static MatrixCollection<8> collection; + cv::Mat one, two, output; + one = frame.clone(); + two = frame.clone(); + int index = 0; + DrawFunction randFunc1 = getRandomFilter(index); + DrawFunction randFunc2 = getRandomFilter(index); + randFunc1(one); + randFunc2(two); + AlphaBlend(one, two, output, alpha); + collection.shiftFrames(output); + Smooth(frame, &collection); + static int direction = 1; + procPos(direction, alpha, alpha_max); + */ +} + +void ac::PixelatedSquare(cv::Mat &frame) { + static MatrixCollection<8> collection; + static double alpha = 1.0, alpha_max = 3.0; + cv::Mat filter_1 = frame.clone(); + cv::Mat frame_copy; + SurroundPixelXor(filter_1); + GridFilter16x(filter_1); + + AlphaBlend(filter_1,frame,frame_copy,alpha); + collection.shiftFrames(frame_copy); + Smooth(frame, &collection); + static int direction = 1; + procPos(direction, alpha, alpha_max); +} + +void ac::AlphaBlendPosition(cv::Mat &frame) { + static double alpha = 1.0, alpha_max = 4.0; + int pos_x = 0; + for(int z = 0; z < frame.rows; ++z) { + cv::Vec3b pix = frame.at(z, pos_x); + ++pos_x; + if(pos_x > frame.cols-1) pos_x = 0; + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] = static_cast((pixel[j]*(alpha+1))+(pix[j]*alpha)); + + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel + } + } + static int direction = 1; + procPos(direction, alpha, alpha_max); +} + +void ac::BlendRowAlpha(cv::Mat &frame) { + static int row = 0; + static double alpha = 1.0, alpha_max = 4.0; + for(int i = 0; i < frame.cols; ++i) { + row++; + if(row > frame.cols) row = 0; + for(int z = 0; z < frame.rows; ++z) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = static_cast((pixel[j] ^ row)*alpha); + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel + } + } + static int direction = 1; + procPos(direction, alpha, alpha_max); +} + +void ac::BlendRow(cv::Mat &frame) { + static int row = 0; + for(int i = 0; i < frame.cols; ++i) { + row++; + if(row > frame.cols) row = 0; + for(int z = 0; z < frame.rows; ++z) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = static_cast(pixel[j] ^ row); + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel + } + } +} + +void ac::BlendRowByVar(cv::Mat &frame) { + static int row = 0; + for(int i = 0; i < frame.cols; ++i) { + row++; + if(row > frame.cols) row = 0; + for(int z = 0; z < frame.rows; ++z) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = static_cast((pixel[j]+(z-i)) ^ row); + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel + } + } +} + +void ac::BlendRowByDirection(cv::Mat &frame) { + static int row = 0; + static int direction = 1; + for(int i = 0; i < frame.cols; ++i) { + if(direction == 1) { + ++row; + if(row > frame.cols) + direction = 0; + } else if(direction == 0) { + --row; + if(row <= 0) { + direction = 1; + } + } + for(int z = 0; z < frame.rows; ++z) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + if(direction == 1) + pixel[j] = static_cast((pixel[j]+i+z) & row); + else if(direction == 0) + pixel[j] = static_cast((pixel[j]^row)); + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } +} + +void ac::BlendAlphaXor(cv::Mat &frame) { + static int r = 3; + static int direction = 1; + static double alpha = 1.0, alpha_max = 10.0; + for(int i = 0; i < frame.cols; ++i) { + for(int z = 0; z < frame.rows; ++z) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + unsigned char val = static_cast(r*alpha); + pixel[j] += cv::saturate_cast(pixel[j]^val); + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } + if(direction == 1) { + ++r; + if(r >= 255) + direction = 0; + } else if(direction == 0) { + --r; + if(r <= 3) + direction = 1; + } + static int dir = 1; + procPos(dir, alpha, alpha_max); +} + +void ac::SelfXorScale(cv::Mat &frame) { + static double alpha = 1.0, alpha_max = 8.0; + static int value = 1; + for(int i = 0; i < frame.cols; ++i) { + for(int z = 0; z < frame.rows; ++z) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = static_cast((pixel[j]^value)*alpha); + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } + static int direction = 1; + if(direction == 1) { + ++value; + if(value > 254) + direction = 0; + } else if(direction == 0) { + --value; + if(value <= 1) + direction = 1; + } + static int dir = 1; + procPos(dir, alpha, alpha_max); +} + +void ac::BitwiseXorScale(cv::Mat &frame) { + static cv::Mat frame1 = frame.clone(); + cv::Mat temp = frame.clone(); + + if(frame1.size()!=frame.size()) + frame1 = temp.clone(); + + static double alpha = 1.0, alpha_max = 2.0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = frame1.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] += static_cast((pixel[j]^pix[j])*alpha); + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } + frame1 = temp; + static int direction = 1; + procPos(direction, alpha, alpha_max); +} + +void ac::XorTrails(cv::Mat &frame) { + static MatrixCollection<8> collection; + collection.shiftFrames(frame); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b value; + for(int j = 0; j < collection.size(); ++j) { + cv::Vec3b frame_val = collection.frames[j].at(z, i); + for(int q = 0; q < 3; ++q) { + value[q] ^= frame_val[q]; + } + } + for(int j = 0; j < 3; ++j) + pixel[j] = pixel[j]^value[j]; + + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } +} + +void ac::RainbowTrails(cv::Mat &frame) { + static MatrixCollection<8> collection; + collection.shiftFrames(frame); + for(int i = 0; i < frame.cols; ++i) { + for(int z = 0; z < frame.rows; ++z) { + cv::Vec3b value; + cv::Vec3b &pixel = frame.at(z, i);; + for(int j = 1; j < collection.size(); ++j) { + cv::Vec3b frame_val = collection.frames[j].at(z, i); + for(int q = 0; q < 3; ++q) { + value[q] += frame_val[q]; + } + } + for(int j = 0; j < 3; ++j) { + pixel[j] = pixel[j]^value[j]; + } + } + } +} +void ac::NegativeTrails(cv::Mat &frame) { + static MatrixCollection<8> collection; + static double alpha = 1.0, alpha_max = 8.0; + collection.shiftFrames(frame); + for(int i = 0; i < frame.cols; ++i) { + for(int z = 0; z < frame.rows; ++z) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b value; + for(int j = 0; j < collection.size(); ++j) { + cv::Vec3b frame_val = collection.frames[j].at(z, i); + for(int q = 0; q < 3; ++q) { + pixel[q] ^= pixel[q]+frame_val[q]; + } + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max); +} + +void ac::IntenseTrails(cv::Mat &frame) { + static MatrixCollection<8> collection; + collection.shiftFrames(frame); + static double alpha = 1.0, alpha_max = 8.0; + for(int i = 0; i < frame.cols; ++i) { + for(int z = 0; z < frame.rows; ++z) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b value = pixel; + for(int j = 0; j < collection.size(); ++j) { + cv::Vec3b frame_val = collection.frames[j].at(z, i); + for(int q =0; q < 3; ++q) { + value[q] += static_cast(frame_val[q]*alpha); + + } + } + for(int j = 0; j < 3; ++j) + pixel[j] ^= value[j]; + + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max); +} + +void ac::SelfAlphaRGB(cv::Mat &frame) { + static double alpha = 1.0, alpha_max = 3.0; + static int index = 0; + for(int i = 0; i < frame.cols-2; ++i) { + for(int z = 0; z < frame.rows-2; ++z) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix[4]; + pix[0] = frame.at(z+1, i+1); + pix[1] = frame.at(z+1, i); + pix[2] = frame.at(z, i+1); + pix[3] = pixel; + switch(index) { + case 0: + pixel[0] = static_cast(pix[0][0]*alpha); + pixel[1] = static_cast((pix[0][1]+pix[1][1])*alpha); + pixel[2] = static_cast((pix[0][2]+pix[1][2]+pix[2][2])*alpha); + break; + case 1: + pixel[2] = static_cast(pix[0][0]*alpha); + pixel[1] = static_cast((pix[0][1]+pix[1][1])*alpha); + pixel[0] = static_cast((pix[0][2]+pix[1][2]+pix[2][2])*alpha); + break; + case 2: + pixel[1] = static_cast(pix[0][0]*alpha); + pixel[0] = static_cast((pix[0][1]+pix[1][1])*alpha); + pixel[2] = static_cast((pix[0][2]+pix[1][2]+pix[2][2])*alpha); + break; + case 3: + pixel[0] = pixel[0]^static_cast(pix[0][0]*alpha); + pixel[1] = pixel[1]^static_cast((pix[0][1]+pix[1][1])*alpha); + pixel[2] = pixel[2]^static_cast((pix[0][2]+pix[1][2]+pix[2][2])*alpha); + break; + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max); + + ++index; + if(index > 3) index = 0; +} + + +void ac::BitwiseXorStrobe(cv::Mat &frame) { + static int index = 0; + static double alpha1 = 1.0, alpha2 = 10.0, alpha3 = 5.0,alpha_max = 3.0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + switch(index) { + case 0: + pixel[0] += cv::saturate_cast(pixel[0] * alpha1); + pixel[1] += cv::saturate_cast(pixel[1] * alpha2); + pixel[2] += cv::saturate_cast(pixel[2] * alpha3); + break; + case 1: + pixel[2] += cv::saturate_cast(pixel[0] * alpha1); + pixel[0] += cv::saturate_cast(pixel[1] * alpha2); + pixel[1] += cv::saturate_cast(pixel[2] * alpha3); + break; + case 2: + pixel[1] += cv::saturate_cast(pixel[0] * alpha1); + pixel[2] += cv::saturate_cast(pixel[1] * alpha2); + pixel[0] += cv::saturate_cast(pixel[2] * alpha3); + break; + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } + static int dir1 = 1, dir2 = 0, dir3 = 1; + procPos(dir1, alpha1, alpha_max); + procPos(dir2, alpha2, alpha_max); + procPos(dir3, alpha3, alpha_max); + + ++index; + if(index > 2) index = 0; + Bitwise_XOR(frame); +} + + +void ac::AlphaBlendRandom(cv::Mat &frame) { + + if(testSize(frame) == false) + return; + + static double val = 0.30; + static int val_dir = 1; + int index = 0; + DrawFunction func[2]; + func[0] = getRandomFilter(index); + func[1] = getRandomFilter(index); + cv::Mat copy[4]; + copy[0] = frame.clone(); + copy[1] = frame.clone(); + copy[2] = frame.clone(); + func[0](copy[0]); + func[1](copy[1]); + AlphaBlend(copy[0], copy[1], copy[3], 0.5); + AlphaBlend(copy[2], copy[3], frame, val); + if(val_dir == 1) { + val += 0.05; + if(val >= 1.0) + val_dir = 0; + } else { + val -= 0.05; + if(val <= 0.30) + val_dir = 1; + } +} + +void ac::ChannelSortAlphaBlend(cv::Mat &frame) { + static double alpha = 1.0, alpha_max = 3.0; + static int index = 0; + std::vector v; // to hold the Matrix for split + cv::split(frame, v);// split the channels into seperate matrices + cv::Mat channels[3]; // output channels + cv::Mat output; // for merge + cv::sort(v[0], channels[0],cv::SORT_ASCENDING); // sort each matrix + cv::sort(v[1], channels[1],cv::SORT_ASCENDING); + cv::sort(v[2], channels[2],cv::SORT_ASCENDING); + cv::sort(v[index], channels[index], cv::SORT_DESCENDING); + cv::merge(channels, 3, output); + ++index; + if(index > 2) index = 0; + cv::Mat copy = frame.clone(); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pixadd = output.at(z, i); + for(int j = 0; j < 3; ++j) { + //pixel += pixadd; + pixel[j] = static_cast((pixel[j] * (1+alpha)) + (pixadd[j] * alpha)); + } + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 10, 0.01); +} + +void ac::XorChannelSort(cv::Mat &frame) { + std::vector v; // to hold the Matrix for split + cv::split(frame, v);// split the channels into seperate matrices + cv::Mat channels[3]; // output channels + cv::Mat output; // for merge + cv::sort(v[0], channels[0],(((rand()%2) == 0) ? cv::SORT_ASCENDING : cv::SORT_DESCENDING)); // sort each matrix + cv::sort(v[1], channels[1],(((rand()%2) == 0) ? cv::SORT_ASCENDING : cv::SORT_DESCENDING)); // sort each matrix + cv::sort(v[2], channels[2],(((rand()%2) == 0) ? cv::SORT_ASCENDING : cv::SORT_DESCENDING)); // sort each matrix + cv::merge(channels, 3, output); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b sorted = output.at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] = pixel[j] ^ sorted[j]; + + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } +} + +void ac::GradientColors(cv::Mat &frame) { + static int index = 0; + static unsigned char val = 0; + int inc = (frame.rows/255)+1; + for(int i = 0; i < frame.cols; ++i) { + val = 1; + for(int z = 0; z < frame.rows; ++z) { + cv::Vec3b &pixel = frame.at(z, i); + pixel[index] = val; + if((z%inc) == 0) + ++val; + + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } + ++index; + if(index > 2) + index = 0; +} + +void ac::GradientColorsVertical(cv::Mat &frame) { + static int index = 0; + static unsigned char val = 0; + int inc = (frame.cols/255)+1; + for(int z = 0; z < frame.rows; ++z) { + val = 1; + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + pixel[index] = val; + + if((i%inc) == 0) + ++val; + + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } + ++index; + if(index > 2) + index = 0; +} + +void ac::Bitwise_XOR_Average(cv::Mat &frame) { + static double alpha = 1.0, alpha_max = 8.0; + for(int z = 0; z < frame.rows; ++z) { + cv::Scalar sval; + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + sval[j] += pixel[j]; + } + } + + for(int j = 0; j < 3; ++j) + sval[j] /= frame.cols; + + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] = static_cast((pixel[j] * (1+alpha)) + (static_cast(sval[j])*alpha)); + + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 0.01); + Bitwise_XOR(frame); +} + +void ac::NotEqual(cv::Mat &frame) { + + static MatrixCollection<2> collection; + collection.shiftFrames(frame); + static double alpha = 1.0, alpha_max = 3.0; + + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + bool same_value = true; + cv::Vec3b value; + for(int j = 0; j < collection.size(); ++j) { + value = collection.frames[j].at(z, i); + if(value != pixel) { + same_value = false; + break; + } + } + if(same_value == false) { + for(int j = 0; j < 3; ++j) { + pixel[j] = static_cast((pixel[j] * (1+alpha)) + (value[j] * alpha)); + } + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 0.10); +} + +void ac::GradientXorSelfScale(cv::Mat &frame) { + static double alpha = 1.0, alpha_max = 3.0; + for(int z = 0; z < frame.rows-1; ++z) { + for(int i = 0; i < frame.cols-1; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = frame.at(z+1, i+1); + for(int j = 0; j < 3; ++j) { + pixel[j] = static_cast((pixel[j] * (1+alpha))) ^ pix[j]; + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 10, 0.03); +} + +void ac::SmoothSourcePixel(cv::Mat &frame) { + static MatrixCollection<8> collection; + static double alpha = 1.0, alpha_max = 3.0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + int total = pixel[0]+pixel[1]+pixel[2]/3; + for(int j = 0; j < 3; ++j) { + pixel[j] = static_cast(((pixel[j] ^ total) * static_cast(alpha))); + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 15, 0.1); + collection.shiftFrames(frame); + Smooth(frame, &collection); +} + +void ac::StrobeBlend(cv::Mat &frame) { + int value1 = ((frame.cols/2)/255)+1; + int num = 1, num2 = 1; + static double alpha = 1.0, alpha_max = 8.0; + static int index1 = 0, index2 = 2; + static int frame_num = 0; + + ++frame_num; + if(frame_num > 1) frame_num = 0; + + for(int z = 0; z < frame.rows; ++z) { + num = 1; + num2 = 1; + for(int i = 0; i < frame.cols/2; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + if((i%value1)==0) + num++; + if(frame_num == 0) { + for(int j = 0; j < 3; ++j) { + pixel[j] = pixel[j] ^ static_cast(num); + } + } else { + for(int j = 0; j < 3; ++j) { + pixel[j] = pixel[j] ^ static_cast(num/(alpha+1)); + } + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + //pixel[index1]= 255; + } + for(int i = frame.cols/2; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + if((i%value1)==0) + num2++; + if(frame_num == 0) { + for(int j = 0; j < 3; ++j) { + pixel[j] = pixel[j] ^ static_cast(num2); + } + } else { + for(int j = 0; j < 3; ++j) { + pixel[j] = pixel[j] ^ static_cast(num2/(alpha+1)); + } + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + //pixel[index2] = 0; + } + } + if(++index1 > 2) index1 = 0; + if(--index2 < 0) index2 = 2; + static int dir = 1; + procPos(dir, alpha, alpha_max, 15, 0.03); +} + +void ac::FrameBars(cv::Mat &frame) { + int diff_i = (frame.cols/255)+1; + int diff_z = (frame.rows/255)+1; + unsigned char val[2] = {0,0}; + static double alpha = 1.0, alpha_max = 8.0; + static MatrixCollection<4> collection; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] += static_cast(val[0]*alpha) + static_cast(val[1]*alpha); + + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + + if((i%diff_i) == 0) { + val[0]++; + } + } + if((z%diff_z) == 0) { + val[1]++; + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max); + collection.shiftFrames(frame); + Smooth(frame, &collection); +} + +void ac::Sort_Vertical_Horizontal(cv::Mat &frame) { + cv::Mat value = frame.clone(); + VerticalChannelSort(value); + ChannelSort(value); + Add(frame, value, false); + +} + +void ac::Sort_Vertical_Horizontal_Bitwise_XOR(cv::Mat &frame) { + cv::Mat value = frame.clone(); + VerticalChannelSort(value); + ChannelSort(value); + static bool sub = false; + if(sub == false) + Add(frame, value, false); + else + Sub(frame, value, false); + sub = (sub == true) ? false : true; + Bitwise_XOR(frame); +} + + +void ac::Scalar_Average_Multiply(cv::Mat &frame) { + cv::Mat copy = frame.clone(); + VerticalChannelSort(frame); + cv::Scalar average; + ScalarAverage(frame, average); + Transform(copy, frame, [&](cv::Vec3b &pixel, int , int ) { + for(int j = 0; j < 3; ++j) { + pixel[j] *= static_cast(average[j]); + } + }); + cv::Mat out = frame.clone(); + AlphaBlend(out, copy, frame, 0.5); +} + +void ac::Scalar_Average(cv::Mat &frame) { + cv::Mat copy = frame.clone(); + cv::Scalar value; + ScalarAverage(frame, value); + Transform(copy, frame,[&](cv::Vec3b &pixel, int , int ) { + for(int j = 0; j < 3; ++j) + pixel[j] *= static_cast(value[j]); + }); + cv::Mat out = frame.clone(); + AlphaBlend(copy, out, frame, 0.5); +} + +void ac::Total_Average(cv::Mat &frame) { + cv::Mat frames[3]; + static double alpha = 1.0, alpha_max = 8.0; + frames[0] = frame.clone(); + frames[1] = frame.clone(); + frames[2] = frame.clone(); + + SelfScale(frames[0]); + rainbowBlend(frames[1]); + SelfAlphaRGB(frames[2]); + + unsigned long total[3]; + + for(int j = 0; j < 3; ++j) + TotalAverageOffset(frames[j], total[j]); + + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] += static_cast((alpha*total[j])); + + swapColors(frame, z, i); + // if isNegative true invert pixel + if(isNegative) invert(frame, z, i); + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max); + +} + +void ac::FlashWhite(cv::Mat &frame) { + static cv::Vec3b white(255,255,255); + static bool state = false; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + if(state) + frame.at(z, i) = white; + } + } + state = (state == true) ? false : true; +} + +void ac::FlashBlackAndWhite(cv::Mat &frame) { + static int index = 0; + static cv::Vec3b white(255,255,255), black(0,0,0); + if(index != 1 && index != 3) { + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + switch(index) { + case 0: + frame.at(z, i) = white; + break; + case 2: + frame.at(z, i) = black; + } + } + } + } + ++index; + if(index > 3) index = 0; +} + +void ac::GaussianBlend(cv::Mat &frame) { + static double alpha = 1.0, alpha_max = 3.0; + static MatrixCollection<8> collection; + unsigned int r = 3+(rand()%10); + for(unsigned int q = 0; q < r; ++q) + GaussianBlur(frame); + + collection.shiftFrames(frame); + int value[3] = { rand()%255, rand()%255, rand()%255 }; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] = static_cast((pixel[j] ^ value[j]) * alpha); + + swapColors(frame, z, i); + // if isNegative true invert pixel + if(isNegative) invert(frame, z, i); + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 15, 0.1); + collection.shiftFrames(frame); + Smooth(frame, &collection); + +} + +void ac::RandomXor(cv::Mat &frame) { + int r_color[3] = { rand()%255, rand()%255, rand()%255 }; + static double alpha = 1.0, alpha_max = 3.0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] = static_cast((pixel[j] ^ r_color[j]) * alpha); + + swapColors(frame, z, i); + // if isNegative true invert pixel + if(isNegative) invert(frame, z, i); + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max); + +} + diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter6.cpp b/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter6.cpp new file mode 100755 index 0000000..83b2aa5 --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter6.cpp @@ -0,0 +1,1287 @@ +/* + * Software written by Jared Bruni https://github.com/lostjared + + This software is dedicated to all the people that experience mental illness. + + Website: http://lostsidedead.com + YouTube: http://youtube.com/LostSideDead + Instagram: http://instagram.com/jaredbruni + Twitter: http://twitter.com/jaredbruni + Facebook: http://facebook.com/LostSideDead0x + + You can use this program free of charge and redistrubute it online as long + as you do not charge anything for this program. This program is meant to be + 100% free. + + BSD 2-Clause License + + Copyright (c) 2019, Jared Bruni + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + */ + + +#include"ac.h" + +double blend_percentage = 0.5; + +void ac::RandomXorFlash(cv::Mat &frame) { + static int index = 0; + int col_p[3] = { rand()%255, rand()%255, rand()%255 }; + int col_x[3] = { rand()%255, rand()%255, rand()%255 }; + static double alpha = 1.0, alpha_max = 3.0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + switch(index) { + case 0: + pixel[j] = static_cast(pixel[j] ^ ((col_p[j] ^ col_x[j]) * static_cast(alpha))); + break; + case 1: + pixel[j] = static_cast(pixel[j] ^ col_p[j]); + break; + case 2: + pixel[j] = static_cast(pixel[j] ^ (col_p[j]+col_x[j])); + break; + } + } + swapColors(frame, z, i); + // if isNegative true invert pixel + if(isNegative) invert(frame, z, i); + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max); + + ++index; + if(index > 2) index = 0; +} + +void ac::RandomAmountMedianBlur(cv::Mat &frame) { + int random = rand()%10; + for(int j = 0; j < random; ++j) + MedianBlur(frame); +} + +void ac::SoftXor(cv::Mat &frame) { + static MatrixCollection<4> collection; + RandomAmountMedianBlur(frame); + collection.shiftFrames(frame); + double alpha = 1.0, alpha_max = 3.0; + + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Scalar s; + for(int q = 0; q < collection.size(); ++q) { + cv::Vec3b val = collection.frames[q].at(z, i); + unsigned char v[3] = { static_cast(s[0]), static_cast(s[1]), static_cast(s[2])}; + s[0] = (v[0] + val[0]) ^ static_cast(s[0]); + s[1] = (v[1] + val[1]) ^ static_cast(s[1]); + s[2] = (v[2] + val[2]) ^ static_cast(s[2]); + } + + s[0] /= (collection.size()); + s[1] /= (collection.size()); + s[2] /= (collection.size()); + + for(int j = 0; j < 3; ++j) { + unsigned char v = static_cast(s[j]); + pixel[j] = static_cast((pixel[j] ^ v) * static_cast(alpha)); + } + + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } + + static int dir = 1; + procPos(dir, alpha, alpha_max, 8.0, 0.1); + +} + +void ac::SelfXorBlend(cv::Mat &frame) { + static unsigned char index[3] = {static_cast(rand()%255), static_cast(rand()%255), static_cast(rand()%255)}; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = pixel[j] ^ index[j]; + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } + for(int j = 0; j < 3; ++j) + ++index[j]; +} + +void ac::SelfXorDoubleFlash(cv::Mat &frame) { + static double alpha = 1.0; + int r[3] = {rand()%255,rand()%255,rand()%255}; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] = pixel[j] ^ (static_cast(alpha)+r[j]); + + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } + static int dir = 1; + if(dir == 1) { + alpha += alpha_increase; + if(alpha > 255) + dir = 0; + } else { + alpha -= alpha_increase; + if(alpha <= 0) + dir = 1; + } +} + +void ac::SelfOrDoubleFlash(cv::Mat &frame) { + static double alpha = 1.0; + int r[3] = {rand()%255,rand()%255,rand()%255}; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] = pixel[j] | (static_cast(alpha) ^ r[j]); + + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } + static int dir = 1; + if(dir == 1) { + alpha += alpha_increase; + if(alpha > 255) + dir = 0; + } else { + alpha -= alpha_increase; + if(alpha <= 0) + dir = 1; + } +} + +void ac::BlendRowCurvedSqrt(cv::Mat &frame) { + static double alpha = 1.0, alpha_max = 3.0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + double amount = sqrt(i*z); + pixel[j] = static_cast((pixel[j]^static_cast(amount))*alpha); + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max); +} + +void ac::CycleShiftRGB(cv::Mat &frame) { + static int offset[3] = {0, ((frame.cols/2)/2), (frame.cols/2)}; + if(reset_filter == true) { + offset[0] = 0; + offset[1] = ((frame.cols/2)/2); + offset[2] = (frame.cols/2); + reset_filter = false; + } + cv::Mat frame_copy = frame.clone(); + for(int z = 0; z < frame.rows; ++z) { + for(int j = 0; j < 3; ++j) { + for(int i = 0; i < offset[j]; ++i) { + if(i >= 0 && i < frame.cols) { + if(offset[j]-i-1 >= 0 && offset[j]-i-1 < frame.cols) { + cv::Vec3b &pixel = frame.at(z, offset[j]-i-1); + cv::Vec3b pix_copy = frame_copy.at(z, i); + pixel[j] = pix_copy[j]; + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } + } + int index = 0; + for(int i = offset[j]; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix_copy = frame_copy.at(z, index); + pixel[j] = pix_copy[j]; + ++index; + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + + } + } + for(int j = 0; j < 3; ++j) { + ++offset[j] += 50; + if(offset[j] > frame.cols) + offset[j] = 0; + } +} + +void ac::CycleShiftRandomRGB(cv::Mat &frame) { + static int offset[3] = {0, ((frame.cols/2)/2), (frame.cols/2)}; + static bool lazy = false; + if(reset_filter == true || lazy == false) { + switch(rand()%2) { + case 0: + offset[0] = 0; + offset[1] = ((frame.cols/2)/2); + offset[2] = (frame.cols/2); + break; + case 1: + offset[2] = 0; + offset[0] = ((frame.cols/2)/2); + offset[1] = (frame.cols/2); + break; + default: + offset[1] = 0; + offset[2] = ((frame.cols/2)/2); + offset[0] = (frame.cols/2); + break; + } + lazy = true; + reset_filter = false; + } + cv::Mat frame_copy = frame.clone(); + for(int z = 0; z < frame.rows; ++z) { + for(int j = 0; j < 3; ++j) { + for(int i = 0; i < offset[j]; ++i) { + if(i >= 0 && i < frame.cols) { + if(offset[j]-i-1 >= 0 && offset[j]-i-1 < frame.cols) { + cv::Vec3b &pixel = frame.at(z, offset[j]-i-1); + cv::Vec3b pix_copy = frame_copy.at(z, i); + pixel[j] = pix_copy[j]; + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } + int index = 0; + for(int i = offset[j]; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix_copy = frame_copy.at(z, index); + pixel[j] = pix_copy[j]; + ++index; + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } + } + for(int j = 0; j < 3; ++j) { + ++offset[j] += 50; + if(offset[j] > frame.cols) + offset[j] = 0; + } +} + +void ac::CycleShiftRandomRGB_XorBlend(cv::Mat &frame) { + static int offset[3] = {0, ((frame.cols/2)/2), (frame.cols/2)}; + static bool lazy = false; + if(reset_filter == true || lazy == false) { + switch(rand()%2) { + case 0: + offset[0] = 0; + offset[1] = ((frame.cols/2)/2); + offset[2] = (frame.cols/2); + break; + case 1: + offset[2] = 0; + offset[0] = ((frame.cols/2)/2); + offset[1] = (frame.cols/2); + break; + default: + offset[1] = 0; + offset[2] = ((frame.cols/2)/2); + offset[0] = (frame.cols/2); + break; + } + lazy = true; + reset_filter = false; + } + cv::Mat frame_copy = frame.clone(); + for(int z = 0; z < frame.rows; ++z) { + for(int j = 0; j < 3; ++j) { + for(int i = 0; i < offset[j]; ++i) { + if(i >= 0 && i < frame.cols) { + if(offset[j]-i-1 >= 0 && offset[j]-i-1 < frame.cols) { + cv::Vec3b &pixel = frame.at(z, offset[j]-i-1); + cv::Vec3b pix_copy = frame_copy.at(z, i); + pixel[j] ^= pix_copy[j]; + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } + } + int index = 0; + for(int i = offset[j]; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix_copy = frame_copy.at(z, index); + pixel[j] ^= pix_copy[j]; + ++index; + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } + } + for(int j = 0; j < 3; ++j) { + ++offset[j] += 50; + if(offset[j] > frame.cols) + offset[j] = 0; + } +} + +void ac::CycleShiftRandomAlphaBlend(cv::Mat &frame) { + static double alpha[3] = {1.0,4.0,2.5}, alpha_max = 3.0; + static int offset[3] = {0, ((frame.cols/2)/2), (frame.cols/2)}; + static bool lazy = false; + if(reset_filter == true || lazy == false) { + switch(rand()%2) { + case 0: + offset[0] = 0; + offset[1] = ((frame.cols/2)/2); + offset[2] = (frame.cols/2); + break; + case 1: + offset[2] = 0; + offset[0] = ((frame.cols/2)/2); + offset[1] = (frame.cols/2); + break; + default: + offset[1] = 0; + offset[2] = ((frame.cols/2)/2); + offset[0] = (frame.cols/2); + break; + } + lazy = true; + reset_filter = false; + alpha[0] = 1.0; + alpha[1] = 4.0; + alpha[2] = 2.5; + } + cv::Mat frame_copy = frame.clone(); + for(int z = 0; z < frame.rows; ++z) { + for(int j = 0; j < 3; ++j) { + for(int i = 0; i < offset[j]; ++i) { + if(i >= 0 && i < frame.cols) { + if(offset[j]-i-1 >= 0 && offset[j]-i-1 < frame.cols) { + cv::Vec3b &pixel = frame.at(z, offset[j]-i-1); + cv::Vec3b pix_copy = frame_copy.at(z, i); + pixel[j] = static_cast((pixel[j] * alpha[j]) + (pix_copy[j] * alpha[j])); + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } + } + int index = 0; + for(int i = offset[j]; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix_copy = frame_copy.at(z, index); + pixel[j] = static_cast((pixel[j] * alpha[j]) + (pix_copy[j] * alpha[j])); + ++index; + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } + } + + static int dir[3] = {1,0,1}; + for(int j = 0; j < 3; ++j) { + ++offset[j] += 50; + if(offset[j] > frame.cols) + offset[j] = 0; + + procPos(dir[j], alpha[j], alpha_max, 6, 0.03); + } +} + +void ac::VerticalColorBars(cv::Mat &frame) { + static double alpha[3] = { 1.0, 3.0, 7.0}, alpha_max = 3.0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] = static_cast(pixel[j]^(i)*static_cast(alpha[j])); + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } + static int dir[3] = { 1,1,0 }; + for(int j = 0; j < 3; ++j) + procPos(dir[j], alpha[j], alpha_max,10.0, 0.3); +} + +void ac::GradientLeftRight(cv::Mat &frame) { + static double inc[3] = {1, 25, 50}, alpha_max = 3.0; + for(int z = 0; z < frame.rows; ++z) { + double amt[3] = {5, 16, 30}; + for(int i = 0; i < frame.cols/2; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] += static_cast(amt[j]); + amt[j] += inc[j]; + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + for(int i = frame.cols/2; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] -= static_cast(amt[j]); //static_cast(amt); + amt[j] -= inc[j]; + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } + static int dir[3] = {1, 1, 1}; + for(int j = 0; j < 3; ++j) { + procPos(dir[j], inc[j], alpha_max, 10, 0.1); + } +} + +void ac::GraidentUpDown(cv::Mat &frame) { + static double inc[3] = {1, 25, 50}, alpha_max = 3.0; + for(int i = 0; i < frame.cols; ++i) { + double amt[3] = {5, 16, 30}; + for(int z = 0; z < frame.rows/2; ++z) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] += static_cast(amt[j]); + amt[j] += inc[j]; + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + for(int z = frame.rows/2; z < frame.rows; ++z) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] -= static_cast(amt[j]); + amt[j] -= inc[j]; + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } + static int dir[3] = {1, 1, 1}; + for(int j = 0; j < 3; ++j) { + procPos(dir[j], inc[j], alpha_max, 10, 0.1); + } +} + +void ac::GradientLeftRightInOut(cv::Mat &frame) { + static double inc[3] = {1, 25, 50}, alpha_max = 3.0; + static int dir[3] = {1, 0, 1}; + for(int z = 0; z < frame.rows; ++z) { + double amt[3] = {5, 16, 30}; + for(int i = 0; i < frame.cols/2; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + if(dir[j] == 0) { + pixel[j] += static_cast(amt[j]); + amt[j] += inc[j]; + } else { + pixel[j] -= static_cast(amt[j]); + amt[j] -= inc[j]; + } + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + for(int i = frame.cols/2; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + if(dir[j] == 1) { + pixel[j] += static_cast(amt[j]); + amt[j] += inc[j]; + } else { + pixel[j] -= static_cast(amt[j]); + amt[j] -= inc[j]; + } + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } + for(int j = 0; j < 3; ++j) { + procPos(dir[j], inc[j], alpha_max, 10, 0.1); + } +} + +void ac::GradientUpDownInOut(cv::Mat &frame) { + static double inc[3] = {1, 25, 50}, alpha_max = 3.0; + static int dir[3] = {1, 0, 1}; + for(int i = 0; i < frame.cols; ++i) { + double amt[3] = {5, 16, 30}; + for(int z = 0; z < frame.rows/2; ++z) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + if(dir[j] == 0) { + pixel[j] += static_cast(amt[j]); + amt[j] += inc[j]; + } else { + pixel[j] -= static_cast(amt[j]); + amt[j] -= inc[j]; + } + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + for(int z = frame.rows/2; z < frame.rows; ++z) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + if(dir[j] == 1) { + pixel[j] += static_cast(amt[j]); + amt[j] += inc[j]; + } else { + pixel[j] -= static_cast(amt[j]); + amt[j] -= inc[j]; + } + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } + for(int j = 0; j < 3; ++j) { + procPos(dir[j], inc[j], alpha_max, 10, 0.1); + } +} + +void ac::Lines(cv::Mat &frame) { + static double alpha = 1.0, alpha_max = 3.0; + for(int z = 0; z < frame.rows; ++z) { + int r_start = (rand()%(frame.cols/2)); + int r_stop = (frame.cols/2)+(rand()%(frame.cols/2)); + int r_height = 1+rand()%3; + bool sw = true; + for(int q = z; q < frame.rows && q < z+r_height; ++q) { + for(int i = r_start; i < frame.cols && i < r_stop; ++i) { + if(q >= 0 && q < frame.rows && i >= 0 && i < frame.cols) { + cv::Vec3b &pixel = frame.at(q, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = (sw == true) ? 255 : 0; + } + swapColors(frame, q, i);// swap colors + if(isNegative) invert(frame, q, i);// if isNegative invert pixel */ + } + } + sw = (sw == true) ? false : true; + } + z += r_height-1; + } + static int dir = 1; + procPos(dir, alpha, alpha_max); +} + +void ac::ColorLines(cv::Mat &frame) { + int diff = (frame.cols/255); + static double alpha = 1.0, alpha_max = 2.0; + for(int z = 0; z < frame.rows; ++z) { + int total[3] = {rand()%16, rand()%32, rand()%64}; + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = (pixel[j]^total[j])*alpha; + if((i%(diff+1))==0) { + ++total[j]; + } + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 8.0, 0.01); +} + +void ac::WhiteLines(cv::Mat &frame) { + for(int z = 0; z < frame.rows; z += rand()%20) { + int num = rand()%25, skip = rand()%10; + int count = 0, skip_count = 0; + for(int i = 0; i < frame.cols; ++i) { + if(count < num) { + if(z >= 0 && z < frame.rows && i >= 0 && i < frame.cols) { + cv::Vec3b &pixel = frame.at(z, i); + pixel[0] = pixel[1] = pixel[2] = 255; + } + ++count; + } else { + if(skip_count >= skip) { + skip_count = 0; + count = 0; + num = rand()%25; + skip = rand()%10; + } else { + ++skip_count; + } + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } +} + +void ac::ThickWhiteLines(cv::Mat &frame) { + for(int j = 0; j < 5; ++j) { + int start_y = 0; + if(j > 0) start_y = rand()%frame.rows; + for(int z = start_y; z < frame.rows; z += rand()%30) { + int num = rand()%50, skip = rand()%25; + int count = 0, skip_count = 0; + for(int i = 0; i < frame.cols; ++i) { + if(count < num) { + if(i >= 0 && i < frame.cols && z >= 0 && z < frame.rows) { + cv::Vec3b &pixel = frame.at(z, i); + pixel[0] = pixel[1] = pixel[2] = 255; + } + ++count; + } else { + if(skip_count >= skip) { + skip_count = 0; + count = 0; + num = rand()%50; + skip = rand()%20; + } else { + ++skip_count; + } + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } + } +} + +void ac::UseLineObject(cv::Mat &frame) { + static HLine obj_lines; + if(obj_lines.empty()) { + obj_lines.createLines(100, frame.cols, frame.rows); + } + obj_lines.drawLines(frame); +} + +void ac::TanAlphaGrid(cv::Mat &frame) { + static double alpha[3] = {1.0, 32.0, 64.0}, alpha_max = 7.0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + pixel[0] = static_cast((tan(i)*alpha[0])+pixel[0]); + pixel[1] = static_cast((tan(z)*alpha[1])+pixel[1]); + pixel[2] = static_cast((tan(z-i)*alpha[2])+pixel[2]); + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } + static int dir[3] = {1,1,1}; + for(int j = 0; j < 3; ++j) + procPos(dir[j], alpha[j], alpha_max); +} + +void ac::MedianBlendAnimation(cv::Mat &frame) { + static MatrixCollection<8> collection; + + int r = 3+rand()%7; + for(int i = 0; i < r; ++i) + MedianBlur(frame); + + collection.shiftFrames(frame); + static double alpha = 1.0, alpha_max = 3.0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Scalar value; + for(int j = 0; j < collection.size(); ++j) { + cv::Vec3b pixel = collection.frames[j].at(z, i); + for(int q = 0; q < 3; ++q) { + value[q] += pixel[q]; + } + } + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + int val = 1+static_cast(value[j]); + pixel[j] = static_cast(static_cast(pixel[j]*(alpha+1)) ^ static_cast(val * alpha)); + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } + static int direction = 1; + procPos(direction, alpha, alpha_max, 10, 0.08); +} + +void ac::FibFlash(cv::Mat &frame) { + static int values[13] = {1,2,3,5,8,13,21,34,55,89,144,233}; + static int index = 0; + static double alpha = 1.0, alpha_max = 3.0; + + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + int value = values[index]; + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = pixel[j] ^ (static_cast(alpha)*value); + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } + static int idir = 1; + if(idir == 1) { + ++index; + if(index > 12) idir = 0; + } else { + --index; + if(index <= 1) idir = 1; + } + static int dir = 1; + procPos(dir, alpha, alpha_max); +} + +void ac::ScaleFlash(cv::Mat &frame) { + static double pos = 1.0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] = static_cast(pixel[j]*pos); + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } + static int idir = 1; + if(idir == 1) { + pos += 0.5; + + if(pos > 12) + idir = 0; + } else if(idir == 0) { + pos -= 0.5; + if(pos <= 1) + idir = 1; + } +} + +void ac::LeftLines(cv::Mat &frame) { + static std::unique_ptr line_width; + static int width = 0; + if(!line_width || frame.rows != width) { + line_width.reset(new unsigned int[frame.rows+1]); + width = frame.rows; + for(int i = 0; i < width; ++i) { + line_width[i] = rand()%50; + } + } + static double alpha = 1.0, alpha_max = 3.0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < line_width[z]; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] ^= static_cast(pixel[j]*(alpha+1)); + + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + line_width[z] += 50; + if(line_width[z] > frame.cols) + line_width[z] = 1; + } + int direction = 1; + procPos(direction, alpha, alpha_max, 4.0, 0.05); +} + +void ac::Curtain(cv::Mat &frame) { + static int start = 0; + static int direction = 1; + static double alpha = 1.0, alpha_max = 7.0; + for(int z = 0; z < frame.rows; ++z) { + if(direction == 1) { + for(int i = 0; i < start; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] ^= static_cast(pixel[j]*(alpha+1)); + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + + } else { + + for(int i = frame.cols-1; i > start; --i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] ^= static_cast(pixel[j]*(alpha+1)); + + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } + } + if(direction == 1) { + start += 40; + if(start > frame.cols-1) { + direction = 0; + } + } else { + start -= 40; + if(start <= 1) { + direction = 1; + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max); +} + +void ac::RandomCurtain(cv::Mat &frame) { + + if(testSize(frame) == false) + return; + + static int start = 0; + static int direction = 1; + static double alpha = 1.0, alpha_max = 7.0; + int i = 0; + static DrawFunction rf = getRandomFilter(i); + cv::Mat frame_copy = frame.clone(); + rf(frame_copy); + + + for(int z = 0; z < frame.rows; ++z) { + if(direction == 1) { + for(int i = 0; i < start; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b copy_pix = frame_copy.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] ^= static_cast(copy_pix[j]+pixel[j]); + } + } + } else { + + for(int i = frame.cols-1; i > start; --i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b copy_pix = frame_copy.at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] ^= static_cast(copy_pix[j]+pixel[j]); + } + } + } + if(direction == 1) { + start += 40; + if(start > frame.cols-1) { + direction = 0; + int i = 0; + rf = getRandomFilter(i); + } + } else { + start -= 40; + if(start <= 1) { + direction = 1; + int i = 0; + rf = getRandomFilter(i); + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max); + AddInvert(frame); +} + +void ac::CurtainVertical(cv::Mat &frame) { + static int start = 0; + static int direction = 1; + static double alpha = 1.0, alpha_max = 7.0; + for(int z = 0; z < frame.cols; ++z) { + if(direction == 1) { + for(int i = 0; i < start; ++i) { + cv::Vec3b &pixel = frame.at(i, z); + for(int j = 0; j < 3; ++j) { + pixel[j] ^= static_cast(pixel[j]*(alpha+1)); + } + } + } else { + + for(int i = frame.rows-1; i > start; --i) { + cv::Vec3b &pixel = frame.at(i, z); + for(int j = 0; j < 3; ++j) + pixel[j] ^= static_cast(pixel[j]*(alpha+1)); + } + } + } + if(direction == 1) { + start += 50; + if(start > frame.rows-1) { + direction = 0; + } + } else { + start -= 50; + if(start <= 1) { + direction = 1; + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max); + AddInvert(frame); +} + +void ac::RandomCurtainVertical(cv::Mat &frame) { + + if(frame.rows < 320 || frame.cols < 240) + return; + + static int start = 0; + static int direction = 1; + static double alpha = 1.0, alpha_max = 7.0; + int i = 0; + static DrawFunction rf = getRandomFilter(i); + cv::Mat frame_copy = frame.clone(); + rf(frame_copy); + + for(int z = 0; z < frame.cols; ++z) { + if(direction == 1) { + for(int i = 0; i < start; ++i) { + cv::Vec3b &pixel = frame.at(i, z); + cv::Vec3b copy_pix = frame_copy.at(i, z); + for(int j = 0; j < 3; ++j) { + pixel[j] ^= static_cast(copy_pix[j]+pixel[j]); + } + } + } else { + for(int i = frame.rows-1; i > start; --i) { + cv::Vec3b &pixel = frame.at(i, z); + cv::Vec3b copy_pix = frame_copy.at(i, z); + for(int j = 0; j < 3; ++j) + pixel[j] ^= static_cast(copy_pix[j]+pixel[j]); + + } + } + } + if(direction == 1) { + start += 50; + if(start > frame.rows-1) { + direction = 0; + rf = getRandomFilter(i); + } + } else { + start -= 50; + if(start <= 1) { + direction = 1; + rf = getRandomFilter(i); + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max); + AddInvert(frame); +} + +void ac::inOrderBySecond(cv::Mat &frame) { + static int index = 0; + if(index < ac::draw_max-8) { + static int frame_count = 0; + if(index >= 0 && index < ac::draw_max-8 && ac::draw_strings[index] != "inOrderBySecond" && ac::draw_strings[index] != "inOrder" && ac::draw_strings[index] != "inOrderAlpha" && ac::draw_strings[index] != "inOrderAlphaXor") CallFilter(index, frame); + ++frame_count; + if(frame_count >= ac::fps) { + frame_count = 0; + ++index; + if(index >= ac::draw_max-10) { + index = 0; + } + } + } else index = 0; + AddInvert(frame); +} + +void ac::inOrder(cv::Mat &frame) { + static int index = 0; + if(index < ac::draw_max-8) { + if(index >= 0 && index < ac::draw_max-8 && ac::draw_strings[index] != "inOrderBySecond" && ac::draw_strings[index] != "inOrder" && ac::draw_strings[index] != "inOrderAlpha" && ac::draw_strings[index] != "inOrderAlphaXor") CallFilter(index, frame); + ++index; + } else index = 0; + + AddInvert(frame); +} + +void ac::DarkenFilter(cv::Mat &frame) { + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] = pixel[j] / 2; + } + } +} + +void ac::RandomFilterBySecond(cv::Mat &frame) { + if(testSize(frame) == false) + return; + + static int frame_count = 0; + static int f = 0; + static DrawFunction func = getRandomFilter(f); + if(ac::draw_strings[f] == "RandomFilterBySecond") { + func = getRandomFilter(f); + return; + } + func(frame); + if(++frame_count >= ac::fps) { + frame_count = 0; + func = getRandomFilter(f); + } + AddInvert(frame); +} + +void ac::ThreeRandom(cv::Mat &frame) { + + if(testSize(frame) == false) + return; + + for(int j = 0; j < 3; ++j) { + int f = 0; + ac::DrawFunction func = getRandomFilter(f); + if(ac::draw_strings[f] != "ThreeRandom") + func(frame); + } + AddInvert(frame); +} + +void ac::inOrderAlpha(cv::Mat &frame) { + static double alpha = 1.0, alpha_max = 7.0; + cv::Mat copy[2]; + copy[0] = frame.clone(); + copy[1] = frame.clone(); + inOrder(copy[0]); + inOrder(copy[1]); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b colors[3]; + cv::Vec3b &pixel = frame.at(z, i); + colors[0] = copy[0].at(z, i); + colors[1] = copy[1].at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] ^= (colors[0][j] * static_cast(alpha)) + (colors[1][j] * static_cast(alpha)); + } + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max); + AddInvert(frame); +} + +void ac::inOrderAlphaXor(cv::Mat &frame) { + static double alpha = 1.0, alpha_max = 4.0; + cv::Mat copy[2]; + copy[0] = frame.clone(); + copy[1] = frame.clone(); + inOrder(copy[0]); + AlphaXorBlend(copy[0], copy[1], frame, alpha); + static int dir = 1; + procPos(dir, alpha, alpha_max, 10, 0.01); + AddInvert(frame); +} + +void ac::SlideFilter(cv::Mat &frame) { + static const int speed = 40; + static int start_1 = 0, start_2 = frame.cols-1; + static int direction_1 = 1, direction_2 = 0; + static double alpha = 1.0, alpha_max = 3.0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < start_1; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = pixel[j]*(1+static_cast(alpha)); + } + } + for(int i =(frame.cols-1); i > start_2; --i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] = pixel[j]*(1+static_cast(alpha)); + + } + } + if(direction_1 == 1) { + start_1 += speed; + if(start_1 > (frame.cols-1)) { + direction_1 = 0; + start_1 = (frame.cols-1); + } + } else { + start_1 -= speed; + if(start_1 <= 0) { + direction_1 = 1; + start_1 = 0; + } + } + if(direction_2 == 1) { + start_2 += speed; + if(start_2 >= (frame.cols-1)) { + direction_2 = 0; + start_2 = (frame.cols-1); + } + } else { + start_2 -= speed; + if(start_2 <= 0) { + direction_2 = 1; + start_2 = 0; + } + } + + static int dir = 1; + procPos(dir, alpha, alpha_max, 9.0, 0.005); + AddInvert(frame); +} + +void ac::SlideFilterXor(cv::Mat &frame) { + static const int speed = 40; + static int start_1 = 0, start_2 = frame.cols-1; + static int direction_1 = 1, direction_2 = 0; + static double alpha = 1.0, alpha_max = 3.0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < start_1; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] ^= pixel[j]*static_cast(1+alpha); + } + } + for(int i =(frame.cols-1); i > start_2; --i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] ^= pixel[j]*static_cast(1+alpha); + + } + } + if(direction_1 == 1) { + start_1 += speed; + if(start_1 > (frame.cols-1)) { + direction_1 = 0; + start_1 = (frame.cols-1); + } + } else { + start_1 -= speed; + if(start_1 <= 0) { + direction_1 = 1; + start_1 = 0; + } + } + if(direction_2 == 1) { + start_2 += speed; + if(start_2 >= (frame.cols-1)) { + direction_2 = 0; + start_2 = (frame.cols-1); + } + } else { + start_2 -= speed; + if(start_2 <= 0) { + direction_2 = 1; + start_2 = 0; + } + } + + static int dir = 1; + procPos(dir, alpha, alpha_max, 9.0, 0.005); + AddInvert(frame); +} + +void ac::RandomSlideFilter(cv::Mat &frame) { + + if(testSize(frame) == false) + return; + + static const int speed = 40; + static int start_1 = 0, start_2 = frame.cols-1; + static int direction_1 = 1, direction_2 = 0; + static double alpha = 1.0, alpha_max = 7.0; + static int index[2]; + DrawFunction f1, f2; + f1 = getRandomFilter(index[0]); + f2 = getRandomFilter(index[1]); + if(ac::draw_strings[index[0]] == "RandomSlideFilter") return; + if(ac::draw_strings[index[1]] == "RandomSlideFilter") return; + cv::Mat frames[2]; + frames[0] = frame.clone(); + frames[1] = frame.clone(); + f1(frames[0]); + f2(frames[1]); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < start_1; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = frames[0].at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] ^= static_cast(pix[j]*alpha); + } + } + for(int i =(frame.cols-1); i > start_2; --i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = frames[1].at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] ^= static_cast(pix[j]*alpha); + } + } + if(direction_1 == 1) { + start_1 += speed; + if(start_1 > (frame.cols-1)) { + direction_1 = 0; + start_1 = (frame.cols-1); + } + } else { + start_1 -= speed; + if(start_1 <= 0) { + direction_1 = 1; + start_1 = 0; + } + } + if(direction_2 == 1) { + start_2 += speed; + if(start_2 >= (frame.cols-1)) { + direction_2 = 0; + start_2 = (frame.cols-1); + } + } else { + start_2 -= speed; + if(start_2 <= 0) { + direction_2 = 1; + start_2 = 0; + } + } + + static int dir = 1; + procPos(dir, alpha, alpha_max); + AddInvert(frame); +} + +// No Filter +void ac::NoFilter(cv::Mat &) {} +// Alpha Blend with Original Frame +void ac::BlendWithSource(cv::Mat &frame) { + cv::Mat copyf = frame.clone(); + ac::pass2_alpha = blend_percentage; // set to 50% + Pass2Blend(copyf);// call Pass2 function + frame = copyf.clone(); +} + +void ac::setBlendPercentage(const double &value) { + blend_percentage = value; +} + diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter7.cpp b/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter7.cpp new file mode 100755 index 0000000..3685c57 --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter7.cpp @@ -0,0 +1,1047 @@ +/* + * Software written by Jared Bruni https://github.com/lostjared + + This software is dedicated to all the people that experience mental illness. + + Website: http://lostsidedead.com + YouTube: http://youtube.com/LostSideDead + Instagram: http://instagram.com/jaredbruni + Twitter: http://twitter.com/jaredbruni + Facebook: http://facebook.com/LostSideDead0x + + You can use this program free of charge and redistrubute it online as long + as you do not charge anything for this program. This program is meant to be + 100% free. + + BSD 2-Clause License + + Copyright (c) 2019, Jared Bruni + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + */ + + +#include "ac.h" + + +void ac::SlideUpDown(cv::Mat &frame) { + static const int speed = 40; + static int start_1 = 0, start_2 = frame.rows-1; + static int direction_1 = 1, direction_2 = 0; + static double alpha = 1.0, alpha_max = 3.0; + for(int i = 0; i < frame.cols; ++i) { + for(int z = 0; z < start_1; ++z) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = static_cast(pixel[j]*(alpha+1)); + } + } + for(int z =(frame.rows-1); z > start_2; --z) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] = static_cast(pixel[j]*(alpha+1)); + + } + } + if(direction_1 == 1) { + start_1 += speed; + if(start_1 > (frame.rows-1)) { + direction_1 = 0; + start_1 = (frame.rows-1); + } + } else { + start_1 -= speed; + if(start_1 <= 0) { + direction_1 = 1; + start_1 = 0; + } + } + if(direction_2 == 1) { + start_2 += speed; + if(start_2 >= (frame.rows-1)) { + direction_2 = 0; + start_2 = (frame.rows-1); + } + } else { + start_2 -= speed; + if(start_2 <= 0) { + direction_2 = 1; + start_2 = 0; + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 9.0, 0.005); + AddInvert(frame); +} + +void ac::SlideUpDownXor(cv::Mat &frame) { + static const int speed = 40; + static int start_1 = 0, start_2 = frame.rows-1; + static int direction_1 = 1, direction_2 = 0; + static double alpha = 1.0, alpha_max = 3.0; + for(int i = 0; i < frame.cols; ++i) { + for(int z = 0; z < start_1; ++z) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] ^= static_cast(pixel[j]*(alpha+1)); + } + } + for(int z =(frame.rows-1); z > start_2; --z) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] ^= static_cast(pixel[j]*(alpha+1)); + + } + } + if(direction_1 == 1) { + start_1 += speed; + if(start_1 > (frame.rows-1)) { + direction_1 = 0; + start_1 = (frame.rows-1); + } + } else { + start_1 -= speed; + if(start_1 <= 0) { + direction_1 = 1; + start_1 = 0; + } + } + if(direction_2 == 1) { + start_2 += speed; + if(start_2 >= (frame.rows-1)) { + direction_2 = 0; + start_2 = (frame.rows-1); + } + } else { + start_2 -= speed; + if(start_2 <= 0) { + direction_2 = 1; + start_2 = 0; + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 9.0, 0.005); + AddInvert(frame); +} + +void ac::SlideUpDownRandom(cv::Mat &frame) { + + if(testSize(frame) == false) + return; + + DrawFunction f1, f2; + static int index[2]; + f1 = getRandomFilter(index[0]); + f2 = getRandomFilter(index[1]); + if(ac::draw_strings[index[0]] == "SlideUpDownRandom") return; + if(ac::draw_strings[index[1]] == "SlideUpDownRandom") return; + cv::Mat frames[2]; + frames[0] = frame.clone(); + frames[1] = frame.clone(); + f1(frames[0]); + f2(frames[1]); + static const int speed = 40; + static int start_1 = 0, start_2 = frame.rows-1; + static int direction_1 = 1, direction_2 = 0; + static double alpha = 1.0, alpha_max = 3.0; + for(int i = 0; i < frame.cols; ++i) { + for(int z = 0; z < start_1; ++z) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = frames[0].at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] ^= static_cast(pix[j]*alpha); + } + } + for(int z =(frame.rows-1); z > start_2; --z) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = frames[1].at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] ^= static_cast(pix[j]*alpha); + + } + } + if(direction_1 == 1) { + start_1 += speed; + if(start_1 > (frame.rows-1)) { + direction_1 = 0; + start_1 = (frame.rows-1); + } + } else { + start_1 -= speed; + if(start_1 <= 0) { + direction_1 = 1; + start_1 = 0; + } + } + if(direction_2 == 1) { + start_2 += speed; + if(start_2 >= (frame.rows-1)) { + direction_2 = 0; + start_2 = (frame.rows-1); + } + } else { + start_2 -= speed; + if(start_2 <= 0) { + direction_2 = 1; + start_2 = 0; + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 9.0, 0.005); + AddInvert(frame); +} + +void ac::SlideSubFilter(cv::Mat &frame) { + static const int speed = 40; + static int start_1 = 0, start_2 = frame.cols-1; + static int direction_1 = 1, direction_2 = 0; + static double alpha = 1.0, alpha_max = 7.0; + if(subfilter == -1 || ac::draw_strings[subfilter] == "SlideSubFilter") return; + cv::Mat frame_x; + frame_x = frame.clone(); + if(ac::subfilter != -1) { + CallFilter(subfilter, frame_x); + } else return; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < start_1; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = frame_x.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] ^= static_cast(pix[j]*alpha); + } + } + for(int i =(frame.cols-1); i > start_2; --i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = frame_x.at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] ^= static_cast(pix[j]*alpha); + } + } + if(direction_1 == 1) { + start_1 += speed; + if(start_1 > (frame.cols-1)) { + direction_1 = 0; + start_1 = (frame.cols-1); + } + } else { + start_1 -= speed; + if(start_1 <= 0) { + direction_1 = 1; + start_1 = 0; + } + } + if(direction_2 == 1) { + start_2 += speed; + if(start_2 >= (frame.cols-1)) { + direction_2 = 0; + start_2 = (frame.cols-1); + } + } else { + start_2 -= speed; + if(start_2 <= 0) { + direction_2 = 1; + start_2 = 0; + } + } + + static int dir = 1; + procPos(dir, alpha, alpha_max); + AddInvert(frame); +} + +void ac::SlideSubUpDownFilter(cv::Mat &frame) { + static const int speed = 40; + static int start_1 = 0, start_2 = frame.rows-1; + static int direction_1 = 1, direction_2 = 0; + static double alpha = 1.0, alpha_max = 3.0; + if(subfilter == -1 || ac::draw_strings[subfilter] == "SlideSubUpDownFilter") return; + cv::Mat frame_x; + frame_x = frame.clone(); + if(ac::subfilter != -1) { + CallFilter(subfilter, frame_x); + } else return; + + for(int i = 0; i < frame.cols; ++i) { + for(int z = 0; z < start_1; ++z) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = frame_x.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] ^= static_cast(pix[j]*alpha); + } + } + for(int z =(frame.rows-1); z > start_2; --z) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = frame_x.at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] ^= static_cast(pix[j]*alpha); + + } + } + if(direction_1 == 1) { + start_1 += speed; + if(start_1 > (frame.rows-1)) { + direction_1 = 0; + start_1 = (frame.rows-1); + } + } else { + start_1 -= speed; + if(start_1 <= 0) { + direction_1 = 1; + start_1 = 0; + } + } + if(direction_2 == 1) { + start_2 += speed; + if(start_2 >= (frame.rows-1)) { + direction_2 = 0; + start_2 = (frame.rows-1); + } + } else { + start_2 -= speed; + if(start_2 <= 0) { + direction_2 = 1; + start_2 = 0; + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 9.0, 0.005); + AddInvert(frame); +} + +void ac::BlendInAndOut(cv::Mat &frame) { + static cv::Scalar color(rand()%255, rand()%255, rand()%255); + static int step[3] = {1,1,1}; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] ^= static_cast(color[j]); + } + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } + static int dir[3] = {1,1,1}; + for(int j = 0; j < 3; ++j) { + if(dir[j] == 1) { + color[j] += step[j]; + if(color[j] >= 255) { + dir[j] = 0; + } + + } else if(dir[j] == 0) { + color[j] -= step[j]; + if(color[j] <= 0) { + step[j] = 1+(rand()%10); + dir[j] = 1; + color[j] = rand()%255; + } + } + } +} + +void ac::BlendScaleInAndOut(cv::Mat &frame) { + static cv::Scalar color(rand()%255, rand()%255, rand()%255); + static double alpha = 1.0, alpha_max = 6.0; + static int step[3] = {1,1,1}; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] ^= static_cast(color[j]*alpha); + } + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } + static int dir[3] = {1,1,1}; + for(int j = 0; j < 3; ++j) { + if(dir[j] == 1) { + color[j] += step[j]; + if(color[j] >= 255) { + dir[j] = 0; + } + } else if(dir[j] == 0) { + color[j] -= step[j]; + if(color[j] <= 0) { + step[j] = 1+(rand()%10); + dir[j] = 1; + color[j] = rand()%255; + } + } + } + static int alpha_direction = 1; + procPos(alpha_direction, alpha, alpha_max, 10, 0.09); +} +void ac::AcidGlitch(cv::Mat &frame) { + static double alpha = 1.0, alpha_max = 6.0; + static int step[3] = {1,1,1}; + static cv::Scalar color(rand()%255, rand()%255, rand()%255); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix_copy = pixel; + for(int j = 0; j < 3; ++j) { + pixel[j] += (((pix_copy[3-j-1] ^ static_cast(color[j]))) * alpha); + } + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } + static int dir[3] = {1,1,1}; + for(int j = 0; j < 3; ++j) { + if(dir[j] == 1) { + color[j] += step[j]; + if(color[j] >= 255) { + dir[j] = 0; + } + } else if(dir[j] == 0) { + color[j] -= step[j]; + if(color[j] <= 0) { + step[j] = 1+(rand()%10); + dir[j] = 1; + color[j] = rand()%255; + } + } + } + static int alpha_direction = 1; + procPos(alpha_direction, alpha, alpha_max, 10, 0.09); +} + +void ac::XorBackwards(cv::Mat &frame) { + static double alpha = 1.0, alpha_max = 6.0; + static cv::Mat frame_copy = frame.clone(); + cv::Mat orig = frame.clone(); + if(frame_copy.size()!=frame.size()) { + frame_copy = frame.clone(); + } + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = frame_copy.at(z, i); + for(int j = 0; j < 3; ++j) { + double val = 0; + val = (pixel[j]^pix[3-j-1])*alpha; + pixel[j] += static_cast(val); + } + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max); + frame_copy = orig; +} + +void ac::LiquidFilter(cv::Mat &frame) { + static double alpha = 1.0, alpha_max = 7.0; + static MatrixCollection<3> collection; + collection.shiftFrames(frame); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b frame_pix[3]; + for(int j = 0; j < 3; ++j) { + frame_pix[j] = collection.frames[j].at(z, i); + } + for(int j = 0; j < 3; ++j) { + double value = 0; + for(int q = 0; q < 3; ++q) { + value += frame_pix[j][q] * alpha; + } + pixel[j] = pixel[j]^static_cast(value); + } + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max); +} + +void ac::MatrixXorAnd(cv::Mat &frame) { + static MatrixCollection<3> collection; + static double alpha = 1.0, alpha_max = 7.0; + collection.shiftFrames(frame); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b frame_pix[3]; + for(int j = 0; j < 3; ++j) + frame_pix[j] = collection.frames[j].at(z, i); + + for(int j = 0; j < 3; ++j) { + static bool dir = true; + double value = 0; + for(int q = 0; q < 3; ++q) { + if(dir == true) + value += frame_pix[j][q] * alpha; + else + value += frame_pix[3-j-1][q] * alpha; + dir = (dir == true) ? false : true; + } + pixel[j] = (cv::saturate_cast(pixel[j]&(static_cast(value))))^static_cast(alpha); + } + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 8.0, 0.1); +} + + +void ac::XorAlpha(cv::Mat &frame) { + static cv::Scalar color_value(rand()%255, rand()%255, rand()%255); + static int index = 0; + static double alpha = 1.0, alpha_max = 7.0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] ^= static_cast(color_value[j]*alpha); + + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } + if(color_value[index] >= 255) { + color_value[index] = rand()%255; + ++index; + if(index > 2) + index = 0; + } else { + color_value[index] += 5; + } + static int dir = 1; + procPos(dir, alpha, alpha_max); +} + +void ac::AlphaAcidTrails(cv::Mat &frame) { + XorAlpha(frame); + MedianBlend(frame); +} + +void ac::SelfXorAverage(cv::Mat &frame) { + static MatrixCollection<4> collection; + collection.shiftFrames(frame); + static double alpha = 1.0, alpha_max = 7.0; + + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix[3]; + for(int j = 0; j < 3; ++j) { + pix[j] = collection.frames[j].at(z, i); + } + for(int j = 0; j < 3; ++j) { + double value = ((pix[0][j] ^ pix[1][j] ^ pix[2][j])/3) * alpha; + pixel[j] ^= static_cast(value) ^ static_cast(alpha); + } + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max); +} + +void ac::RandomXorBlend(cv::Mat &frame) { + cv::Vec3b pix(rand()%255, rand()%255, rand()%255); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = cv::saturate_cast(pixel[j]^pix[j]); + } + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } +} + +void ac::RGBVerticalXor(cv::Mat &frame) { + static int pos[3] = {0, 0, 0}; + static cv::Size old_size; + if(frame.size() != old_size) { + pos[0] = pos[1] = pos[2] = 0; + old_size = frame.size(); + } + static int index = 0; + static double alpha = 1.0, alpha_max = 6.0; + for(int i = 0; i < frame.cols; ++i) { + for(int z = 0; z < pos[index]; ++z) { + cv::Vec3b &pixel = frame.at(z, i); + pixel[3-index-1] ^= static_cast(pixel[index]*alpha); + + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + for(int z = pos[index]; z < frame.rows; ++z) { + cv::Vec3b &pixel = frame.at(z, i); + pixel[index] ^= static_cast(pixel[index]*alpha); + + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } + + pos[index] += 100; + + if(pos[index] > frame.rows) { + pos[index] = 0; + ++index; + if(index > 2) + index = 0; + } + + static int dir = 1; + procPos(dir, alpha, alpha_max); +} + +void ac::RGBVerticalXorScale(cv::Mat &frame) { + RGBVerticalXor(frame); + BlendScaleInAndOut(frame); +} + +void ac::RGBHorizontalXor(cv::Mat &frame) { + static int pos[3] = {0, 0, 0}; + static cv::Size old_size; + if(frame.size() != old_size) { + pos[0] = pos[1] = pos[2] = 0; + old_size = frame.size(); + } + static int index = 0; + static double alpha = 1.0, alpha_max = 6.0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < pos[index]; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + pixel[3-index-1] ^= static_cast(pixel[index]*alpha); + + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + for(int i = pos[index]; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + pixel[index] ^= static_cast(pixel[index]*alpha); + + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } + pos[index] += 100; + if(pos[index] > frame.cols) { + pos[index] = 0; + ++index; + if(index > 2) + index = 0; + } + + static int dir = 1; + procPos(dir, alpha, alpha_max); +} + +void ac::RGBHorizontalXorScale(cv::Mat &frame) { + RGBHorizontalXor(frame); + BlendScaleInAndOut(frame); +} + +void ac::FadeStrobe(cv::Mat &frame) { + static cv::Scalar colorval(rand()%255, rand()%255, rand()%255); + if(frames_released == true || reset_alpha == true) { + colorval = cv::Scalar(rand()%255, rand()%255, rand()%255); + } + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = (pixel[j]^static_cast(1+colorval[j])); + } + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } + for(int j = 0; j < 3; ++j) { + colorval[j] += 20; + if(colorval[j] >= 255) { + colorval[j] = 0; + } + } +} + +void ac::RGBMirror(cv::Mat &frame) { + cv::Mat f_copy = frame.clone(); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b f_pixel[4]; + f_pixel[0] = f_copy.at(frame.rows-z-1, frame.cols-i-1); + f_pixel[1] = f_copy.at(frame.rows-z-1, i); + f_pixel[2] = f_copy.at(z, frame.cols-i-1); + for(int j = 0; j < 3; ++j) { + pixel[j] = (pixel[j]^f_pixel[j][j]); + } + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } +} + +void ac::MirrorStrobe(cv::Mat &frame) { + cv::Mat copy_f = frame.clone(); + static cv::Scalar value(rand()%255, rand()%255, rand()%255); + static int index = 0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = copy_f.at(copy_f.rows-z-1, copy_f.cols-i-1); + pixel[index] = cv::saturate_cast((pixel[index]^pix[index])+value[index]); + + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } + + value[index] += 50; + if(value[index] > 255) + value[index] = 0; + + ++index; + if(index > 2) + index = 0; +} + +void ac::AndStrobe(cv::Mat &frame) { + cv::Vec3b colorval(rand()%255, rand()%255, rand()%255); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = pixel[j]&colorval[j]; + } + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } +} + +void ac::AndStrobeScale(cv::Mat &frame) { + static double alpha = 1.0, pos_max = 7.0; + cv::Vec3b colorval(rand()%255, rand()%255, rand()%255); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = static_cast((pixel[j]&colorval[j])*alpha); + } + } + } + static int dir = 1; + procPos(dir, alpha, pos_max); +} + +void ac::AndPixelStrobe(cv::Mat &frame) { + static cv::Scalar colorval(rand()%255, rand()%255, rand()%255); + static int index = 0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = pixel[j] & static_cast(colorval[j]); + pixel[j] = pixel[j] ^ static_cast(colorval[j]); + } + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } + colorval[index] += 50; + if(colorval[index] > 255) { + colorval[index] = rand()%255; + ++index; + if(index > 2) + index = 0; + } +} + +void ac::AndOrXorStrobe(cv::Mat &frame) { + static int index = 0; + cv::Scalar colorval(rand()%255, rand()%255, rand()%255); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + switch(index) { + case 0: + pixel[j] = pixel[j] & static_cast(colorval[j]); + break; + case 1: + pixel[j] = pixel[j] | static_cast(colorval[j]); + break; + case 2: + pixel[j] = pixel[j] ^ static_cast(colorval[j]); + break; + } + } + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } + ++index; + if(index > 2) + index = 0; + +} + +void ac::AndOrXorStrobeScale(cv::Mat &frame) { + static int index = 0; + static double alpha = 1.0, alpha_max = 7.0; + cv::Scalar colorval(rand()%255, rand()%255, rand()%255); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + switch(index) { + case 0: + pixel[j] = (pixel[j] & static_cast(colorval[j]))*static_cast(1+alpha); + break; + case 1: + pixel[j] = (pixel[j] | static_cast(colorval[j]))*static_cast(1+alpha); + break; + case 2: + pixel[j] = (pixel[j] ^ static_cast(colorval[j]))*static_cast(1+alpha); + break; + } + } + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } + ++index; + if(index > 2) + index = 0; + + static int dir = 1; + procPos(dir, alpha, alpha_max); +} + +void ac::FadeInAndOut(cv::Mat &frame) { + static int speed[3] = {5+rand()%10, 5+rand()%10, 5+rand()%10}; + static cv::Scalar colorval(rand()%255, rand()%255, rand()%255); + static int dir[3] = {rand()%2, rand()%2, rand()%2}; + if(frames_released == true || reset_alpha == true) { + colorval = cv::Scalar(rand()%255, rand()%255, rand()%255); + for(int j = 0; j < 3; ++j) { + dir[j] = rand()%2; + speed[j] = 5+rand()%10; + } + } + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] ^= cv::saturate_cast(colorval[j]); + + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } + for(int j = 0; j < 3; ++j) { + if(dir[j] == 1) { + colorval[j] += speed[j]; + if(colorval[j] > 255) { + colorval[j] = 255; + dir[j] = 0; + speed[j] = 5+rand()%10; + } + } else if(dir[j] == 0) { + colorval[j] -= speed[j]; + if(colorval[j] <= 0) { + colorval[j] = 0; + dir[j] = 1; + speed[j] = 5+rand()%10; + } + } + } +} + +void ac::BrightStrobe(cv::Mat &frame) { + static int speed[3] = {1,6,13}; + static int dir[3] = {1,1,1}; + cv::Scalar colorval(rand()%255, rand()%255, rand()%255); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] ^= static_cast((colorval[j]*speed[j])); + } + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } + for(int j = 0; j < 3; ++j) { + if(dir[j] == 1) { + colorval[j] += speed[j]; + if(colorval[j] > 255) { + dir[j] = 0; + } + ++speed[j]; + if(speed[j] > 25) { + speed[j] = 25; + } + } else { + colorval[j] -= speed[j]; + if(colorval[j] <= 0) { + colorval[j] = speed[j]--; + dir[j] = 1; + } + --speed[j]; + if(speed[j] <= 0) { + speed[j] = 1; + } + } + } + +} + +void ac::DarkStrobe(cv::Mat &frame) { + static double alpha = 1.0, alpha_max = 7.0; + cv::Scalar colorval(rand()%255, rand()%255, rand()%255); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i ){ + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] &= static_cast((pixel[j]%(1+static_cast(colorval[j])))*alpha); + } + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max); +} + +void ac::RandomXorOpposite(cv::Mat &frame) { + cv::Vec3b colorval(rand()%255, rand()%255, rand()%255); + cv::Vec3b colorval2(rand()%255, rand()%255, rand()%255); + for(int z = 0; z < frame.rows; ++z){ + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = ~pixel[j] ^ colorval[j] ^ ~colorval2[j]; + } + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } +} + +void ac::StrobeTransform(cv::Mat &frame) { + cv::Vec3b colorval(rand()%255, rand()%255, rand()%255); + static double value = 25.0, alpha = 1.0, alpha_max = 7.0; + static int dir = 1, speed_dir = 1; + static int speed = 2, speed_increase = 5; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] += ((pixel[j] + (static_cast(value))) ^ static_cast(alpha)) ^ colorval[j]; + } + } + } + if(dir == 1) + value += speed; + else + value -= speed; + + if(dir == 1) { + if(value > (255)) { + dir = 0; + if(speed_dir == 1) { + speed += speed_increase; + if(speed > 25) + speed_dir = 0; + } else if(speed_dir == 0) { + speed -= speed_increase; + if(speed <= 1) + speed_dir = 1; + } + } + } else if(dir == 0) { + if(value <= 25) { + dir = 1; + } + } + static int cdir = 1; + procPos(cdir, alpha, alpha_max); +} + +void ac::InitBlend(cv::Mat &frame) { + static cv::Vec3b colorval(rand()%255, rand()%255, rand()%255); + static double value = 25.0, alpha = 1.0, alpha_max = 7.0; + static int dir = 1, speed_dir = 1; + static int speed = 2, speed_increase = 5; + if(reset_alpha == true || frames_released == true) { + colorval = cv::Vec3b(rand()%255, rand()%255, rand()%255); + value = 25.0; + alpha = 1.0; + alpha_max = 7.0; + dir = 1; + speed_dir = 1; + speed = 2; + speed_increase = 5; + } + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] += ((pixel[j] + (static_cast(value))) ^ static_cast(alpha)) ^ colorval[j]; + } + } + } + if(dir == 1) + value += speed; + else + value -= speed; + if(dir == 1) { + if(value > (255)) { + dir = 0; + if(speed_dir == 1) { + speed += speed_increase; + if(speed > 25) + speed_dir = 0; + } else if(speed_dir == 0) { + speed -= speed_increase; + if(speed <= 1) + speed_dir = 1; + } + } + } else if(dir == 0) { + if(value <= 25) { + dir = 1; + } + } + static int cdir = 1; + procPos(cdir, alpha, alpha_max); +} + diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter8.cpp b/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter8.cpp new file mode 100755 index 0000000..ab22823 --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter8.cpp @@ -0,0 +1,1220 @@ +/* + * Software written by Jared Bruni https://github.com/lostjared + + This software is dedicated to all the people that experience mental illness. + + Website: http://lostsidedead.com + YouTube: http://youtube.com/LostSideDead + Instagram: http://instagram.com/jaredbruni + Twitter: http://twitter.com/jaredbruni + Facebook: http://facebook.com/LostSideDead0x + + You can use this program free of charge and redistrubute it online as long + as you do not charge anything for this program. This program is meant to be + 100% free. + + BSD 2-Clause License + + Copyright (c) 2019, Jared Bruni + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + */ + + +#include "ac.h" + +void ac::MoveUpLeft(cv::Mat &frame) { + + static double alpha = 1.0, alpha_max = 7.0; + + static cv::Mat old_frame = frame.clone(); + static cv::Size old_size = old_frame.size(); + + if(reset_alpha == true || frames_released == true || old_size != frame.size()) { + old_frame = frame.clone(); + old_size = old_frame.size(); + } + for(int z = 0; z < old_frame.rows-1; ++z) { + for(int i = 0; i < old_frame.cols-1; ++i) { + cv::Vec3b &pixel = old_frame.at(z, i); + cv::Vec3b pix = old_frame.at(z+1, i+1); + pixel = pix; + } + } + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = old_frame.at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] = static_cast((pixel[j]^pix[j])*alpha); + } + } + + static int dir = 1; + procPos(dir, alpha, alpha_max); + AddInvert(frame); +} + +void ac::RandomStrobe(cv::Mat &frame) { + static double alpha = 1.0, alpha_max = 7.0; + static std::vector svStrobe{ "StrobeEffect", "Blank", "Type","Random Flash","Strobe Red Then Green Then Blue","Flash Black","FlashWhite","StrobeScan", "RGBFlash", "ReinterpretDouble", "DiamondStrobe", "BitwiseXorStrobe","FlashBlackAndWhite", "StrobeBlend", "FibFlash", "ScaleFlash", "FadeStrobe", "AndStrobe", "AndStrobeScale", "AndPixelStrobe", "AndOrXorStrobe", "AndOrXorStrobeScale", "BrightStrobe", "DarkStrobe", "RandomXorOpposite", "StrobeTransform"}; + + cv::Mat old_frame = frame.clone(); + DrawFilter(svStrobe[rand()%svStrobe.size()], old_frame); + cv::Mat copy = frame.clone(); + AlphaBlend(old_frame, copy, frame, alpha); + static int dir = 1; + procPos(dir, alpha, alpha_max, 15, 0.1); + AddInvert(frame); +} + +void ac::RandomBlur(cv::Mat &frame) { + std::vector svBlur { "GaussianBlur", "Median Blur", "Blur Distortion", "ColorTrails","TrailsFilter", "TrailsFilterIntense", "TrailsFilterSelfAlpha", "TrailsFilterXor","BlurSim", "TrailsInter", "TrailsBlend", "TrailsNegate", "AcidTrails", "HorizontalTrailsInter" ,"Trails", "BlendTrails", "SmoothTrails", "SmoothTrailsSelfAlphaBlend", "SmoothTrailsRainbowBlend", "MedianBlend", "XorTrails", "RainbowTrails", "NegativeTrails", "IntenseTrails", "GaussianBlend", "RandomAmountMedianBlur", "MedianBlendAnimation", "AlphaAcidTrails"}; + static double alpha = 1.0, alpha_max = 7.0; + cv::Mat old_frame = frame.clone(); + DrawFilter(svBlur[rand()%svBlur.size()], old_frame); + cv::Mat copy = frame.clone(); + AlphaBlend(old_frame, copy, frame, alpha); + static int dir = 1; + procPos(dir, alpha, alpha_max, 15, 0.1); + AddInvert(frame); +} + + +void ac::StuckStrobe(cv::Mat &frame) { + static double alpha = 1.0, alpha_max = 7.0; + static cv::Mat old_frame = frame.clone(); + if(reset_alpha == true || frames_released == true || old_frame.size() != frame.size()) { + old_frame = frame.clone(); + } + cv::Mat copy = frame.clone(); + AlphaBlend(old_frame, copy, frame, alpha); + static int dir = 1; + procPos(dir, alpha, alpha_max, 15, 0.1); + AddInvert(frame); +} + +void ac::Stuck(cv::Mat &frame) { + static cv::Mat old_frame = frame.clone(); + if(reset_alpha == true || frames_released == true || old_frame.size() != frame.size()) { + old_frame = frame.clone(); + } + Add(frame, old_frame); + AddInvert(frame); +} + +void ac::OrStrobe(cv::Mat &frame) { + cv::Mat copy = frame.clone(); + static cv::Mat prev_frame = frame.clone(); + if(prev_frame.size() != frame.size()) { + prev_frame = frame.clone(); + } + cv::Vec3b randval(rand()%255, rand()%255, rand()%255); + static double alpha = 1.0, alpha_max = 7.0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = prev_frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = static_cast((pixel[j]|randval[j]|pix[j])*alpha); + } + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max); + prev_frame = copy.clone(); + AddInvert(frame); +} + +void ac::LagBlend(cv::Mat &frame) { + static MatrixCollection<8> collection; + static cv::Size c_size = frame.size(); + // lazy init + static bool init = false; + if(c_size != frame.size() || init == false) { + collection.shiftFrames(frame); + init = true; + c_size = frame.size(); + } + static int frame_count = 0; + ++frame_count; + if(frame_count > (ac::fps/8)) { + collection.shiftFrames(frame); + frame_count = 0; + } + for(int i = 0; i < collection.size(); ++i) { + DarkenFilter(frame); + Add(frame, collection.frames[i]); + } + AddInvert(frame); +} + +void ac::SubFilter(cv::Mat &frame) { + static MatrixCollection<8> collection; + collection.shiftFrames(frame); + for(int j = 0; j < collection.size(); ++j) { + Sub(frame, collection.frames[j]); + } + AddInvert(frame); +} + +void ac::AddFilter(cv::Mat &frame) { + static MatrixCollection<12> collection; + collection.shiftFrames(frame); + for(int j = 0; j < collection.size(); ++j) { + Add(frame, collection.frames[j]); + } + AddInvert(frame); +} + +// Use in a custom with Darken Filter twice +void ac::RGBTrails(cv::Mat &frame) { + static MatrixCollection<8> collection; + collection.shiftFrames(frame); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + int offset = 0; + for(int j = 0; j < collection.size(); ++j) { + cv::Vec3b pix = collection.frames[j].at(z, i); + pixel[offset] = static_cast(pixel[offset]+(pix[offset])); + + ++offset; + if(offset > 2) + offset = 0; + } + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } +} + +void ac::RGBTrailsDark(cv::Mat &frame) { + DarkenFilter(frame); + DarkenFilter(frame); + RGBTrails(frame); +} + +void ac::RGBTrailsAlpha(cv::Mat &frame) { + static MatrixCollection<8> collection; + DarkenFilter(frame); + DarkenFilter(frame); + collection.shiftFrames(frame); + static double alpha = 1.0, alpha_max = 4.0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + int offset = 0; + for(int j = 0; j < collection.size(); ++j) { + cv::Vec3b pix = collection.frames[j].at(z, i); + pixel[offset] = static_cast((pixel[offset]+pix[offset])*alpha); + + ++offset; + if(offset > 2) + offset = 0; + } + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 4.5, 0.01); +} + +void ac::RGBTrailsNegativeAlpha(cv::Mat &frame) { + static MatrixCollection<8> collection; + DarkenFilter(frame); + DarkenFilter(frame); + collection.shiftFrames(frame); + static double alpha = 1.0, alpha_max = 8.0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + int offset = 0; + for(int j = 0; j < collection.size(); ++j) { + cv::Vec3b pix = collection.frames[j].at(z, i); + pixel[offset] = static_cast((pixel[offset]+~pix[offset])*alpha); + + ++offset; + if(offset > 2) + offset = 0; + } + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 9.0, 0.005); +} + +void ac::MovementRGBTrails(cv::Mat &frame) { + static MatrixCollection<16> collection; + SmoothRGB(frame, &collection); +} + +void ac::RGBTrailsXor(cv::Mat &frame) { + RGBTrails(frame); + RandomXorOpposite(frame); +} + +void ac::DifferenceStrobe(cv::Mat &frame) { + static cv::Mat frame_copy = frame.clone(); + cv::Mat orig_frame = frame.clone(); + if(frame_copy.size() != frame.size()) { + frame_copy = frame.clone(); + } + static int offset = 0; + static double alpha = 1.0, alpha_max = 7.0; + int rand_value = rand()%255; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = frame_copy.at(z, i); + if(pixel[offset]+5 >= pix[offset] && pixel[offset]-5 <= pix[offset]) { + for(int j = 0; j < 3; ++j) { + pixel[j] ^= static_cast(pixel[j]*(alpha+1))+static_cast(pix[j]*alpha); + } + } else { + pixel[offset] = rand_value; + } + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } + + ++offset; + if(offset > 2) + offset = 0; + + static int dir = 1; + procPos(dir, alpha, alpha_max); + frame_copy = orig_frame.clone(); +} + +void ac::BlackAndWhiteDifferenceStrobe(cv::Mat &frame) { + static cv::Mat frame_copy = frame.clone(); + cv::Mat orig_frame = frame.clone(); + if(frame_copy.size() != frame.size()) { + frame_copy = frame.clone(); + } + static int offset = 0; + static double alpha = 1.0, alpha_max = 7.0; + static int counter = 0; + static cv::Vec3b white(255, 255, 255), black(0, 0, 0); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = frame_copy.at(z, i); + if(pixel[offset]+5 >= pix[offset] && pixel[offset]-5 <= pix[offset]) { + for(int j = 0; j < 3; ++j) { + pixel[j] ^= static_cast(pixel[j]*(alpha+1))+static_cast(pix[j]*alpha); + } + } else { + if(counter == 0) + pixel = black; + else + pixel = white; + } + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } + counter = (counter == 0) ? 1 : 0; + ++offset; + if(offset > 2) + offset = 0; + static int dir = 1; + procPos(dir, alpha, alpha_max); + frame_copy = orig_frame.clone(); +} + +void ac::DifferenceXor(cv::Mat &frame) { + static cv::Mat frame_copy = frame.clone(); + cv::Mat orig_frame = frame.clone(); + if(frame_copy.size() != frame.size()) { + frame_copy = frame.clone(); + } + static int offset = 0; + static double alpha = 1.0, alpha_max = 7.0; + cv::Vec3b pix_color(rand()%255, rand()%255, rand()%255); + static cv::Vec3b white(255, 255, 255), black(0, 0, 0); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = frame_copy.at(z, i); + if(pixel[offset]+5 >= pix[offset] && pixel[offset]-5 <= pix[offset]) { + for(int j = 0; j < 3; ++j) { + pixel[j] ^= static_cast(pixel[j]*(alpha+1))+static_cast(pix[j]*alpha); + } + } else { + for(int j = 0; j < 3; ++j) { + pixel[j] = pixel[j]^pix_color[j]; + } + } + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } + ++offset; + if(offset > 2) + offset = 0; + static int dir = 1; + procPos(dir, alpha, alpha_max); + frame_copy = orig_frame.clone(); +} + +void ac::DifferenceRand(cv::Mat &frame) { + static cv::Mat frame_copy = frame.clone(); + cv::Mat orig_frame = frame.clone(); + if(frame_copy.size() != frame.size()) { + frame_copy = frame.clone(); + } + static int offset = 0; + static double alpha = 1.0, alpha_max = 7.0; + cv::Vec3b pix_color(rand()%255, rand()%255, rand()%255); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = frame_copy.at(z, i); + if(pixel[offset]+5 >= pix[offset] && pixel[offset]-5 <= pix[offset]) { + for(int j = 0; j < 3; ++j) { + pixel[j] = pixel[j]^pix_color[j]; + } + } else { + for(int j = 0; j < 3; ++j) { + pixel[j] ^= static_cast(pixel[j]*(alpha+1))+static_cast(pix[j]*alpha); + } + } + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } + ++offset; + if(offset > 2) + offset = 0; + static int dir = 1; + procPos(dir, alpha, alpha_max); + frame_copy = orig_frame.clone(); +} + +void ac::DifferenceBrightStrobe(cv::Mat &frame) { + static cv::Mat frame_copy = frame.clone(); + cv::Mat orig_frame = frame.clone(); + if(frame_copy.size() != frame.size()) { + frame_copy = frame.clone(); + } + static int offset = 0; + static double alpha = 1.0, alpha_max = 7.0; + static int sw = 0; + cv::Vec3b rand_pix(rand()%255, rand()%255, rand()%255); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = frame_copy.at(z, i); + if(pixel[offset]+5 >= pix[offset] && pixel[offset]-5 <= pix[offset]) { + for(int j = 0; j < 3; ++j) { + if(sw == 0) + pixel[j] = ~pixel[j]; + else + pixel[j] ^= static_cast((pixel[j]^rand_pix[j])*alpha); + } + } else { + for(int j = 0; j < 3; ++j) { + if(sw == 1) + pixel[j] = ~pixel[j]; + else + pixel[j] ^= static_cast((pixel[j]^rand_pix[j])*alpha); + } + } + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } + ++offset; + if(offset > 2) + offset = 0; + static int dir = 1; + + ++sw; + if(sw > 1) + sw = 0; + + procPos(dir, alpha, alpha_max); + frame_copy = orig_frame.clone(); +} + +void ac::PsycheTrails(cv::Mat &frame) { + static MatrixCollection<16> collection; + DarkenImage(frame, 8); + collection.shiftFrames(frame); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + int offset = 0; + for(int j = 0; j < collection.size(); ++j) { + cv::Vec3b pix = collection.frames[j].at(z, i); + pixel[offset] = static_cast(pixel[offset]+(pix[offset])); + ++offset; + if(offset > 2) + offset = 0; + } + swapColors(frame, z, i); + if(isNegative) invert(frame, z, i); + } + } + DifferenceXor(frame); +} + +void ac::FourSquare(cv::Mat &frame) { + static MatrixCollection<4> collection; + collection.shiftFrames(frame); + int pos_x = 0; + int pos_y = 0; + for(int i = 0; i < collection.size(); ++i) { + cv::Mat out_frame; + if(frame.cols/2 > 0 && frame.rows/2 > 0) { + cv::resize(collection.frames[i], out_frame, cv::Size(frame.cols/2,frame.rows/2)); + copyMat(out_frame, 0,0, frame, pos_x, pos_y, frame.cols/2, frame.rows/2); + } + pos_x += frame.cols/2; + if(pos_x > frame.cols-(frame.cols/2)) { + pos_x = 0; + pos_y += frame.rows/2; + } + } + AddInvert(frame); +} + +void ac::EightSquare(cv::Mat &frame) { + static MatrixCollection<8> collection; + collection.shiftFrames(frame); + int pos_x = 0; + int pos_y = 0; + for(int i = 0; i < collection.size(); ++i) { + cv::Mat out_frame; + if(frame.cols/4 > 0 && frame.rows/2 > 0) { + cv::resize(collection.frames[i], out_frame, cv::Size(frame.cols/4,frame.rows/2)); + copyMat(out_frame, 0,0, frame, pos_x, pos_y, frame.cols/4, frame.rows/2); + } + pos_x += frame.cols/4; + if(pos_x > frame.cols-(frame.cols/4)) { + pos_x = 0; + pos_y += frame.rows/2; + } + } + AddInvert(frame); +} + +void ac::DiagonalSquare(cv::Mat &frame) { + int pos_x = 0, pos_y = 0; + int col_w = (frame.cols/4)-1; + int col_h = (frame.rows/4)-1; + cv::Mat copy_frame = frame.clone(); + for(int i = 0; i < 3; ++i) { + cv::Mat out_frame; + if(col_w > 0 && col_h > 0) { + cv::resize(copy_frame, out_frame, cv::Size(col_w,col_h)); + if(pos_x >= 0 && pos_x < frame.cols-col_w && pos_y >= 0 && pos_y < frame.rows-col_h) + copyMat(out_frame, 0, 0, frame, pos_x, pos_y, col_w, col_h); + } + pos_x += col_w; + pos_y += col_h; + } + AddInvert(frame); +} + +void ac::DiagonalSquareRandom(cv::Mat &frame) { + if(testSize(frame) == false) + return; + static MatrixCollection<4> collection; + collection.shiftFrames(frame); + int pos_x = 0, pos_y = 0; + int col_w = (frame.cols/4)-1; + int col_h = (frame.rows/4)-1; + if(col_w < 25 || col_h < 25) + return; + Negate(frame); + for(int i = 0; i < 4; ++i) { + cv::Mat ©_frame = collection.frames[i]; + cv::Mat out_frame; + if(col_w > 0 && col_h > 0) { + cv::resize(copy_frame, out_frame, cv::Size(col_w,col_h)); + randomFilter(out_frame); + copyMat(out_frame, 0, 0, frame, pos_x, pos_y, col_w, col_h); + } + pos_x += col_w; + pos_y += col_h; + } + AddInvert(frame); +} + +void ac::SquareStretchDown(cv::Mat &frame) { + cv::Mat copy_frame = frame.clone(); + static int z = 10; + if(z > frame.rows-1) { + z = 10; + } + cv::Mat out_frame; + if(frame.cols > 0 && z > 0) { + cv::resize(copy_frame, out_frame, cv::Size(frame.cols,z)); + if(subfilter != -1 && ac::draw_strings[subfilter] != "SquareStretchDown") { + CallFilter(subfilter, out_frame); + } + copyMat(out_frame, 0, 0, frame, 0, 0, frame.cols, z); + } + z += 50; + AddInvert(frame); +} + +void ac::SquareStretchRight(cv::Mat &frame) { + cv::Mat copy_frame = frame.clone(); + static int z = 10; + if(z > frame.cols-1) { + z = 10; + } + cv::Mat out_frame; + if(z > 0 && frame.rows > 0) { + cv::resize(copy_frame, out_frame, cv::Size(z,frame.rows)); + if(subfilter != -1 && ac::draw_strings[subfilter] != "SquarehStretcRight") { + CallFilter(subfilter, out_frame); + } + copyMat(out_frame, 0, 0, frame, 0, 0, z,frame.rows); + } + z += 50; + AddInvert(frame); +} + +void ac::SquareStretchUp(cv::Mat &frame) { + cv::Mat copy_frame = frame.clone(); + cv::Mat out_frame; + static int size = 1; + static int y = frame.rows-10; + if(y < 1) { + y = frame.rows-10; + size = 1; + } + if(frame.cols > 0 && size > 0) { + cv::resize(copy_frame, out_frame, cv::Size(frame.cols, size)); + if(subfilter != -1 && ac::draw_strings[subfilter] != "SquareStretchUp") { + CallFilter(subfilter, out_frame); + } + copyMat(out_frame, 0, 0, frame, 0, y, frame.cols, size); + } + y -= 50; + size += 50; + AddInvert(frame); +} + +void ac::SquareStretchLeft(cv::Mat &frame) { + cv::Mat copy_frame = frame.clone(); + cv::Mat out_frame; + static int size = 1; + static int y = frame.cols-10; + if(y < 1) { + y = frame.cols-10; + size = 1; + } + if(size > 0 && frame.rows > 0) { + cv::resize(copy_frame, out_frame, cv::Size(size, frame.rows)); + if(subfilter != -1 && ac::draw_strings[subfilter] != "SquareStretchLeft") { + CallFilter(subfilter, out_frame); + } + copyMat(out_frame, 0, 0, frame, y, 0, size, frame.rows); + } + y -= 50; + size += 50; + AddInvert(frame); +} + +void ac::DarkTrails(cv::Mat &frame) { + RGBTrailsDark(frame); + Bitwise_XOR(frame); +} + +void ac::SoftFeedback(cv::Mat &frame) { + Rect source(0, 0, frame.cols-1, frame.rows-1); + cv::Mat frame_copy = frame.clone(); + + int add_w = source.w/16; + int add_h = source.h/16; + + while(source.x < frame.cols-1 && source.w > add_w) { + if(source.w > 100 && source.w > add_w && source.h > add_h) { + cv::Mat out_frame; + cv::resize(frame_copy, out_frame, cv::Size(source.w, source.h)); + copyMat(out_frame, 0, 0, frame, source.x, source.y, source.w, source.h); + } + source.x += add_w; + source.y += add_h; + source.w -= add_w*2; + source.h -= add_h*2; + } + AddInvert(frame); +} + +void ac::SoftFeedbackFrames(cv::Mat &frame) { + static MatrixCollection<16> collection; + collection.shiftFrames(frame); + Rect source(0, 0, frame.cols-1, frame.rows-1); + cv::Mat frame_copy = frame.clone(); + int add_w = source.w/16; + int add_h = source.h/16; + int offset = 0; + while(source.x < frame.cols-1 && source.w > add_w) { + if(offset < collection.size() && source.w > add_w && source.h > add_h) { + cv::Mat out_frame; + cv::resize(collection.frames[offset], out_frame, cv::Size(source.w, source.h)); + copyMat(out_frame, 0, 0, frame, source.x, source.y, source.w, source.h); + } + source.x += add_w; + source.y += add_h; + source.w -= add_w*2; + source.h -= add_h*2; + offset++; + } + AddInvert(frame); +} + +void ac::ResizeSoftFeedback(cv::Mat &frame) { + static MatrixCollection<16> collection; + collection.shiftFrames(frame); + Rect source(0, 0, frame.cols-1, frame.rows-1); + cv::Mat frame_copy = frame.clone(); + static int num_squares = 2; + int add_w = source.w/num_squares; + int add_h = source.h/num_squares; + int offset = 0; + while(source.x < frame.cols-1 && source.w > add_w) { + if(offset < collection.size() && source.w > add_w && source.h > add_h) { + cv::Mat out_frame; + cv::resize(collection.frames[offset], out_frame, cv::Size(source.w, source.h)); + copyMat(out_frame, 0, 0, frame, source.x, source.y, source.w, source.h); + } + source.x += add_w; + source.y += add_h; + source.w -= add_w*2; + source.h -= add_h*2; + offset++; + } + static int dir = 1; + if(dir == 1) { + num_squares += 2; + if(num_squares >= 16) + dir = 0; + } else if(dir == 0) { + num_squares -= 2; + if(num_squares <= 2) + dir = 1; + } + AddInvert(frame); +} + + +void ac::SoftFeedback8(cv::Mat &frame) { + Rect source(0, 0, frame.cols-1, frame.rows-1); + cv::Mat frame_copy = frame.clone(); + + int add_w = source.w/8; + int add_h = source.h/8; + + while(source.x < frame.cols-1 && source.w > add_w) { + if(source.w > add_w && source.h > add_h) { + cv::Mat out_frame; + cv::resize(frame_copy, out_frame, cv::Size(source.w, source.h)); + copyMat(out_frame, 0, 0, frame, source.x, source.y, source.w, source.h); + } + source.x += add_w; + source.y += add_h; + source.w -= add_w*2; + source.h -= add_h*2; + } + AddInvert(frame); +} +void ac::SoftFeedbackFrames8(cv::Mat &frame) { + static MatrixCollection<8> collection; + collection.shiftFrames(frame); + Rect source(0, 0, frame.cols-1, frame.rows-1); + cv::Mat frame_copy = frame.clone(); + int add_w = source.w/8; + int add_h = source.h/8; + int offset = 0; + while(source.x < frame.cols-1 && source.w > add_w) { + if(offset < collection.size() && source.w > add_w && source.h > add_h) { + cv::Mat out_frame; + cv::resize(collection.frames[offset], out_frame, cv::Size(source.w, source.h)); + copyMat(out_frame, 0, 0, frame, source.x, source.y, source.w, source.h); + } + source.x += add_w; + source.y += add_h; + source.w -= add_w*2; + source.h -= add_h*2; + offset++; + } + AddInvert(frame); +} +void ac::ResizeSoftFeedback8(cv::Mat &frame) { + static MatrixCollection<8> collection; + collection.shiftFrames(frame); + Rect source(0, 0, frame.cols-1, frame.rows-1); + cv::Mat frame_copy = frame.clone(); + static int num_squares = 2; + int add_w = source.w/num_squares; + int add_h = source.h/num_squares; + int offset = 0; + while(source.x < frame.cols-1 && source.w > add_w) { + if(offset < collection.size() && source.w > add_w && source.h > add_h) { + cv::Mat out_frame; + cv::resize(collection.frames[offset], out_frame, cv::Size(source.w, source.h)); + copyMat(out_frame, 0, 0, frame, source.x, source.y, source.w, source.h); + } + source.x += add_w; + source.y += add_h; + source.w -= add_w*2; + source.h -= add_h*2; + offset++; + } + static int dir = 1; + if(dir == 1) { + num_squares += 2; + if(num_squares >= 8) + dir = 0; + } else if(dir == 0) { + num_squares -= 2; + if(num_squares <= 2) + dir = 1; + } + AddInvert(frame); +} + +void ac::ResizeSoftFeedbackSubFilter(cv::Mat &frame) { + if(subfilter != -1 && ac::draw_strings[subfilter] != "ResizeSoftFeedbackSubFilter") { + static MatrixCollection<16> collection; + collection.shiftFrames(frame); + Rect source(0, 0, frame.cols-1, frame.rows-1); + cv::Mat frame_copy = frame.clone(); + static int num_squares = 2; + int add_w = source.w/num_squares; + int add_h = source.h/num_squares; + int offset = 0; + while(source.x < frame.cols-1 && source.w > add_w) { + if(offset < collection.size() && source.w > add_w && source.h > add_h) { + cv::Mat out_frame; + cv::resize(collection.frames[offset], out_frame, cv::Size(source.w, source.h)); + CallFilter(subfilter, out_frame); + copyMat(out_frame, 0, 0, frame, source.x, source.y, source.w, source.h); + } + source.x += add_w; + source.y += add_h; + source.w -= add_w*2; + source.h -= add_h*2; + offset++; + } + static int dir = 1; + if(dir == 1) { + num_squares += 2; + if(num_squares >= 16) + dir = 0; + } else if(dir == 0) { + num_squares -= 2; + if(num_squares <= 2) + dir = 1; + } + AddInvert(frame); + } +} + +void ac::SoftFeedbackRandFilter(cv::Mat &frame) { + static DrawFunction func[10] = {DifferenceXor, RandomXorOpposite, FadeInAndOut, FadeStrobe, AndPixelStrobe, AndStrobe, AndStrobeScale, AndPixelStrobe, AndOrXorStrobe, AndOrXorStrobeScale }; + + Rect source(0, 0, frame.cols-1, frame.rows-1); + cv::Mat frame_copy = frame.clone(); + int add_w = source.w/16; + int add_h = source.h/16; + while(source.x < frame.cols-1 && source.w > add_w) { + if(source.w > add_w && source.h > add_h) { + cv::Mat out_frame; + cv::resize(frame_copy, out_frame, cv::Size(source.w, source.h)); + func[rand()%10](out_frame); + copyMat(out_frame, 0, 0, frame, source.x, source.y, source.w, source.h); + } + source.x += add_w; + source.y += add_h; + source.w -= add_w*2; + source.h -= add_h*2; + } + AddInvert(frame); +} + +void ac::SoftFeedback32(cv::Mat &frame) { + Rect source(0, 0, frame.cols-1, frame.rows-1); + cv::Mat frame_copy = frame.clone(); + + int add_w = source.w/32; + int add_h = source.h/32; + + while(source.x < frame.cols-1 && source.w > add_w) { + if(source.w > 100 && source.h > 100) { + cv::Mat out_frame; + cv::resize(frame_copy, out_frame, cv::Size(source.w, source.h)); + copyMat(out_frame, 0, 0, frame, source.x, source.y, source.w, source.h); + } + source.x += add_w; + source.y += add_h; + source.w -= add_w*2; + source.h -= add_h*2; + } + AddInvert(frame); +} +void ac::SoftFeedbackFrames32(cv::Mat &frame) { + static MatrixCollection<24> collection; + collection.shiftFrames(frame); + Rect source(0, 0, frame.cols-1, frame.rows-1); + cv::Mat frame_copy = frame.clone(); + int add_w = source.w/32; + int add_h = source.h/32; + int offset = 0; + while(source.x < frame.cols-1 && source.w > add_w) { + if(offset < collection.size() && source.w > add_w+10 && source.h > add_h+10) { + cv::Mat out_frame; + cv::resize(collection.frames[offset], out_frame, cv::Size(source.w, source.h)); + copyMat(out_frame, 0, 0, frame, source.x, source.y, source.w, source.h); + } + source.x += add_w; + source.y += add_h; + source.w -= add_w*2; + source.h -= add_h*2; + offset++; + } + AddInvert(frame); +} + +void ac::ResizeSoftFeedback32(cv::Mat &frame) { + static MatrixCollection<32> collection; + collection.shiftFrames(frame); + Rect source(0, 0, frame.cols-1, frame.rows-1); + cv::Mat frame_copy = frame.clone(); + static int num_squares = 2; + int add_w = source.w/num_squares; + int add_h = source.h/num_squares; + static const int MAX_SQUARES=32; + int offset = 0; + while(source.x < frame.cols-1 && source.w > add_w+10 && source.h > add_h+10) { + if(offset < collection.size() && source.w > add_w && source.h > add_h) { + cv::Mat out_frame; + cv::resize(collection.frames[offset], out_frame, cv::Size(source.w, source.h)); + copyMat(out_frame, 0, 0, frame, source.x, source.y, source.w, source.h); + } + source.x += add_w; + source.y += add_h; + source.w -= add_w*2; + source.h -= add_h*2; + offset++; + } + static int dir = 1; + if(dir == 1) { + num_squares += 2; + if(num_squares >= MAX_SQUARES) + dir = 0; + } else if(dir == 0) { + num_squares -= 2; + if(num_squares <= 2) + dir = 1; + } + AddInvert(frame); +} + +void ac::SoftFeedbackRandFilter32(cv::Mat &frame) { + static DrawFunction func[10] = {DifferenceXor, RandomXorOpposite, FadeInAndOut, FadeStrobe, AndPixelStrobe, AndStrobe, AndStrobeScale, AndPixelStrobe, AndOrXorStrobe, AndOrXorStrobeScale }; + + Rect source(0, 0, frame.cols-1, frame.rows-1); + cv::Mat frame_copy = frame.clone(); + int add_w = source.w/32; + int add_h = source.h/32; + while(source.x < frame.cols-1 && source.w > add_w+10 && source.h > add_h+10) { + if(source.w > add_w && source.h > add_h) { + cv::Mat out_frame; + cv::resize(frame_copy, out_frame, cv::Size(source.w, source.h)); + func[rand()%10](out_frame); + copyMat(out_frame, 0, 0, frame, source.x, source.y, source.w, source.h); + } + source.x += add_w; + source.y += add_h; + source.w -= add_w*2; + source.h -= add_h*2; + } + AddInvert(frame); +} + + +void ac::SoftFeedbackSubFilter(cv::Mat &frame) { + + + if(subfilter != -1 && ac::draw_strings[subfilter] == "SoftFeedbackSubFilter") + return; + + Rect source(0, 0, frame.cols-1, frame.rows-1); + cv::Mat frame_copy = frame.clone(); + int add_w = source.w/32; + int add_h = source.h/32; + while(source.x < frame.cols-1 && source.w > add_w+10 && source.h > add_h+10) { + if(source.w > 100 && source.h > 100) { + cv::Mat out_frame; + cv::resize(frame_copy, out_frame, cv::Size(source.w, source.h)); + size_t rand_test = 0; + if(subfilter != -1) rand_test = ac::draw_strings[subfilter].find("Rand"); + if(testSize(out_frame) && rand_test == std::string::npos && subfilter != -1 && ac::draw_strings[subfilter] != "SoftFeedbackSubFilter" && ac::draw_strings[subfilter] != "Random Filter") { + CallFilter(subfilter, out_frame); + } + copyMat(out_frame, 0, 0, frame, source.x, source.y, source.w, source.h); + } + source.x += add_w; + source.y += add_h; + source.w -= add_w*2; + source.h -= add_h*2; + } + AddInvert(frame); + +} +void ac::SoftFeedbackResizeSubFilter(cv::Mat &frame) { + + if(subfilter != -1 && ac::draw_strings[subfilter] == "SoftFeedbackResizeSubFilter") + return; + + static MatrixCollection<32> collection; + collection.shiftFrames(frame); + Rect source(0, 0, frame.cols-1, frame.rows-1); + cv::Mat frame_copy = frame.clone(); + static int num_squares = 2; + int add_w = source.w/num_squares; + int add_h = source.h/num_squares; + static const int MAX_SQUARES=32; + int offset = 0; + while(source.x < frame.cols-1 && source.w > add_w+10 && source.h > add_h+10) { + if(offset < collection.size() && source.w > add_w && source.h > add_h) { + cv::Mat out_frame; + cv::resize(collection.frames[offset], out_frame, cv::Size(source.w, source.h)); + size_t rand_test = 0; + if(subfilter != -1) rand_test = ac::draw_strings[subfilter].find("Rand"); + if(testSize(out_frame) && rand_test == std::string::npos && subfilter != -1 && ac::draw_strings[subfilter] != "SoftFeedbackResizeSubFilter" && ac::draw_strings[subfilter] != "Random Filter") { + CallFilter(subfilter, out_frame); + } + copyMat(out_frame, 0, 0, frame, source.x, source.y, source.w, source.h); + } + source.x += add_w; + source.y += add_h; + source.w -= add_w*2; + source.h -= add_h*2; + offset++; + } + static int dir = 1; + if(dir == 1) { + num_squares += 2; + if(num_squares >= MAX_SQUARES) + dir = 0; + } else if(dir == 0) { + num_squares -= 2; + if(num_squares <= 2) + dir = 1; + } + AddInvert(frame); +} + +void ac::SoftFeedbackResizeSubFilter64(cv::Mat &frame) { + + if(subfilter != -1 && ac::draw_strings[subfilter] == "SoftFeedbackResizeSubFilter64") + return; + + static MatrixCollection<64> collection; + collection.shiftFrames(frame); + Rect source(0, 0, frame.cols-1, frame.rows-1); + cv::Mat frame_copy = frame.clone(); + static int num_squares = 2; + int add_w = source.w/num_squares; + int add_h = source.h/num_squares; + static const int MAX_SQUARES=64; + int offset = 0; + while(source.x >= 0 && source.x < frame.cols-1 && source.w > add_w+10 && source.h > add_h+10) { + if(offset >= 0 && offset < collection.size() && source.w > add_w && source.h > add_h) { + cv::Mat out_frame; + cv::resize(collection.frames[offset], out_frame, cv::Size(source.w, source.h)); + size_t rand_test = 0; + if(subfilter != -1) rand_test = ac::draw_strings[subfilter].find("Rand"); + if(testSize(out_frame) && rand_test == std::string::npos && subfilter != -1 && ac::draw_strings[subfilter] != "SoftFeedbackResizeSubFilter64") { + CallFilter(subfilter, out_frame); + } + copyMat(out_frame, 0, 0, frame, source.x, source.y, source.w, source.h); + } + source.x += add_w; + source.y += add_h; + source.w -= add_w*2; + source.h -= add_h*2; + offset++; + } + static int dir = 1; + if(dir == 1) { + num_squares += 2; + if(num_squares >= MAX_SQUARES) + dir = 0; + } else if(dir == 0) { + num_squares -= 2; + if(num_squares <= 2) + dir = 1; + } + AddInvert(frame); +} + +void ac::SoftFeedbackResize64(cv::Mat &frame) { + + static MatrixCollection<64> collection; + collection.shiftFrames(frame); + Rect source(0, 0, frame.cols-1, frame.rows-1); + cv::Mat frame_copy = frame.clone(); + static int num_squares = 2; + int add_w = source.w/num_squares; + int add_h = source.h/num_squares; + static const int MAX_SQUARES=64; + int offset = 0; + while(source.x >= 0 && source.x < frame.cols-1 && source.w > add_w+10 && source.h > add_h+10) { + if(offset >= 0 && offset < collection.size() && source.w > add_w && source.h > add_h) { + cv::Mat out_frame; + cv::resize(collection.frames[offset], out_frame, cv::Size(source.w, source.h)); + copyMat(out_frame, 0, 0, frame, source.x, source.y, source.w, source.h); + } + source.x += add_w; + source.y += add_h; + source.w -= add_w*2; + source.h -= add_h*2; + offset++; + } + static int dir = 1; + if(dir == 1) { + num_squares += 2; + if(num_squares >= MAX_SQUARES) + dir = 0; + } else if(dir == 0) { + num_squares -= 2; + if(num_squares <= 2) + dir = 1; + } + AddInvert(frame); +} + +void ac::SoftFeedbackReszieSubFilter64_Negate(cv::Mat &frame) { + + if(subfilter != -1 && ac::draw_strings[subfilter] == "SoftFeedbackReszieSubFilter64_Negate") + return; + + static MatrixCollection<64> collection; + collection.shiftFrames(frame); + Rect source(0, 0, frame.cols-1, frame.rows-1); + cv::Mat frame_copy = frame.clone(); + static int num_squares = 2; + int add_w = source.w/num_squares; + int add_h = source.h/num_squares; + static const int MAX_SQUARES=64; + int offset = 0; + while(source.x < frame.cols-1 && source.w > add_w) { + if(offset < collection.size() && source.w > add_w && source.h > add_h) { + cv::Mat out_frame; + cv::resize(collection.frames[offset], out_frame, cv::Size(source.w, source.h)); + size_t rand_test = 0; + if(subfilter != -1) rand_test = ac::draw_strings[subfilter].find("Rand"); + + if(testSize(out_frame) && rand_test != std::string::npos && subfilter != -1 && ac::draw_strings[subfilter] != "SoftFeedbackResizeSubFilter64" && ac::draw_strings[subfilter] != "Random Filter") { + CallFilter(subfilter, out_frame); + } + if((offset%2) == 0) + Negate(out_frame); + + copyMat(out_frame, 0, 0, frame, source.x, source.y, source.w, source.h); + } + source.x += add_w; + source.y += add_h; + source.w -= add_w*2; + source.h -= add_h*2; + offset++; + } + static int dir = 1; + if(dir == 1) { + num_squares += 2; + if(num_squares >= MAX_SQUARES) + dir = 0; + } else if(dir == 0) { + num_squares -= 2; + if(num_squares <= 2) + dir = 1; + } + AddInvert(frame); +} + +void ac::SoftFeedbackReszieSubFilter64_Mirror(cv::Mat &frame) { + + + if(subfilter != -1 && ac::draw_strings[subfilter] == "SoftFeedbackReszieSubFilter64_Mirror") + return; + + + static MatrixCollection<64> collection; + collection.shiftFrames(frame); + Rect source(0, 0, frame.cols-1, frame.rows-1); + cv::Mat frame_copy = frame.clone(); + static int num_squares = 2; + int add_w = source.w/num_squares; + int add_h = source.h/num_squares; + static const int MAX_SQUARES=64; + int offset = 0; + while(source.x < frame.cols-1 && source.w > add_w) { + if(offset < collection.size() && source.w > add_w && source.h > add_h) { + cv::Mat out_frame; + cv::resize(collection.frames[offset], out_frame, cv::Size(source.w, source.h)); + size_t rand_test = 0; + if(subfilter != -1) rand_test = ac::draw_strings[subfilter].find("Rand"); + + if(testSize(out_frame) && rand_test != std::string::npos && subfilter != -1 && ac::draw_strings[subfilter] != "SoftFeedbackResizeSubFilter64" && ac::draw_strings[subfilter] != "Random Filter") { + CallFilter(subfilter, out_frame); + } + if((offset%2) == 0) + Reverse(out_frame); + + copyMat(out_frame, 0, 0, frame, source.x, source.y, source.w, source.h); + } + source.x += add_w; + source.y += add_h; + source.w -= add_w*2; + source.h -= add_h*2; + offset++; + } + static int dir = 1; + if(dir == 1) { + num_squares += 2; + if(num_squares >= MAX_SQUARES) + dir = 0; + } else if(dir == 0) { + num_squares -= 2; + if(num_squares <= 2) + dir = 1; + } + AddInvert(frame); +} + diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter9.cpp b/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter9.cpp new file mode 100755 index 0000000..5a25fca --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/ac-filter9.cpp @@ -0,0 +1,1061 @@ +/* + * Software written by Jared Bruni https://github.com/lostjared + + This software is dedicated to all the people that experience mental illness. + + Website: http://lostsidedead.com + YouTube: http://youtube.com/LostSideDead + Instagram: http://instagram.com/jaredbruni + Twitter: http://twitter.com/jaredbruni + Facebook: http://facebook.com/LostSideDead0x + + You can use this program free of charge and redistrubute it online as long + as you do not charge anything for this program. This program is meant to be + 100% free. + + BSD 2-Clause License + + Copyright (c) 2019, Jared Bruni + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + */ + +#include "ac.h" + + +void ac::HalfNegateStrobe(cv::Mat &frame) { + int f_len = frame.cols/2; + auto neg = [](cv::Vec3b &pixel) { + for(int j = 0; j < 3; ++j) + pixel[j] = ~pixel[j]; + }; + static int off = 0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < f_len; ++i) { + if(off == 0) { + cv::Vec3b &pixel = frame.at(z, i); + neg(pixel); + } + + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + for(int i = f_len; i < frame.cols; ++i) { + if(off == 1) { + cv::Vec3b &pixel = frame.at(z, i); + neg(pixel); + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } + ++off; + if(off >= 2) { + off = 0; + } +} + +void ac::MedianBlurXor(cv::Mat &frame) { + cv::Mat copy_f = frame.clone(); + MedianBlend(frame); + Negate(frame); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b v = copy_f.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = pixel[j] ^ v[j]; + } + } + } + Negate(frame); + AddInvert(frame); +} + +void ac::NegateTrails(cv::Mat &frame) { + MovementRGBTrails(frame); + MedianBlur(frame); + RGBTrailsDark(frame); + MedianBlur(frame); + Negate(frame); + AddInvert(frame); +} + +void ac::RandomGradient(cv::Mat &frame) { + static std::vector svGradient { "CosSinMultiply","New Blend","Color Accumlate1", "Color Accumulate2", "Color Accumulate3", "Filter8", "Graident Rainbow","Gradient Rainbow Flash","Outward", "Outward Square","GradientLines","GradientSelf","GradientSelfVertical","GradientDown","GraidentHorizontal","GradientRGB","GradientStripes", "GradientReverse", "GradientReverseBox", "GradientReverseVertical", "GradientNewFilter", "AverageLines", "QuadCosSinMultiply", "GradientColors", "GradientColorsVertical", "GradientXorSelfScale", "GradientLeftRight", "GraidentUpDown", "GradientLeftRightInOut", "GradientUpDownInOut"}; + CallFilter(svGradient[rand()%svGradient.size()], frame); + AddInvert(frame); +} + +void ac::RandomStrobeFlash(cv::Mat &frame) { + static std::vector svStrobe{ "StrobeEffect", "Blank", "Type","Random Flash","Strobe Red Then Green Then Blue","StrobeScan", "RGBFlash", "ReinterpretDouble", "BitwiseXorStrobe","StrobeBlend", "FibFlash", "ScaleFlash", "FadeStrobe", "AndStrobe", "AndStrobeScale", "AndPixelStrobe", "AndOrXorStrobe", "AndOrXorStrobeScale", "BrightStrobe", "DarkStrobe", "RandomXorOpposite", "StrobeTransform", "OrStrobe", "DifferenceStrobe", "DifferenceXor", "DifferenceRand"}; + CallFilter(svStrobe[rand()%svStrobe.size()], frame); + AddInvert(frame); +} + +void ac::RandomMirror(cv::Mat &frame) { + static std::vector svMirror { "NewOne", "MirrorBlend", "Sideways Mirror","Mirror No Blend","Mirror Average", "Mirror Average Mix","Reverse","Double Vision","RGB Shift","RGB Sep","Side2Side","Top2Bottom", "Soft_Mirror", "KanapaTrip", "InterReverse", "InterMirror", "InterFullMirror", "MirrorRGB", "LineByLineReverse", "CycleShiftRGB", "CycleShiftRandomRGB", "CycleShiftRandomRGB_XorBlend", "RGBMirror", "MirrorStrobe"}; + CallFilter(svMirror[rand()%svMirror.size()], frame); + AddInvert(frame); +} + +void ac::RandomOther(cv::Mat &frame) { + static std::vector svOther_Custom { "Mean", "Laplacian", "Bitwise_XOR", "Bitwise_AND", "Bitwise_OR", "Channel Sort", "Reverse_XOR","Bitwise_Rotate","Bitwise_Rotate Diff", "Equalize","PixelSort", "GlitchSort","HPPD","FuzzyLines","Alpha Flame Filters","Scanlines", "TV Static","FlipTrip", "Canny","Inter","Circular","MoveRed","MoveRGB", "MoveRedGreenBlue", "Wave","HighWave","VerticalSort","VerticalChannelSort","ScanSwitch", "ScanAlphaSwitch","XorAddMul", "RandomIntertwine","RandomFour","RandomTwo","Darken","AverageRandom","RandomCollectionAverage","RandomCollectionAverageMax","BitwiseXorScale","XorChannelSort","Bitwise_XOR_Average","NotEqual","Sort_Vertical_Horizontal","Sort_Vertical_Horizontal_Bitwise_XOR", "Scalar_Average_Multiply","Scalar_Average","Total_Average","VerticalColorBars","inOrder","inOrderBySecond","DarkenFilter","RandomFilterBySecond","ThreeRandom","inOrderAlpha","XorBackwards", "MoveUpLeft", "Stuck", "StuckStrobe", "SoftFeedback", "SoftFeedbackFrames", "ResizeSoftFeedback", "SoftFeedback8","SoftFeedbackFrames8","ResizeSoftFeedback8", "ResizeSoftFeedbackSubFilter", "SoftFeedbackRandFilter", "SoftFeedback32","SoftFeedbackFrames32","ResizeSoftFeedback32", "SoftFeedbackRandFilter32", "SoftFeedbackSubFilter","SoftFeedbackResizeSubFilter", "SoftFeedbackResizeSubFilter64", "SoftFeedbackReszieSubFilter64_Negate", "SoftFeedbackReszieSubFilter64_Mirror"}; + CallFilter(svOther_Custom[rand()%svOther_Custom.size()], frame); + AddInvert(frame); +} + +void ac::RandomXorFilter(cv::Mat &frame) { + static std::vector Xor {"XorMultiBlend", "XorSine", "TrailsFilterXor", "BlockXor", "XorAddMul", "SurroundPixelXor", "BlendAlphaXor", "SelfXorScale","XorTrails","XorChannelSort", "GradientXorSelfScale", "RandomXor", "RandomXorFlash", "SoftXor", "SelfXorBlend", "SelfXorDoubleFlash", "CycleShiftRandomRGB_XorBlend", "inOrderAlphaXor", "SlideFilterXor", "SlideUpDownXor", "XorBackwards", "MatrixXorAnd", "XorAlpha", "SelfXorAverage", "RandomXorBlend", "RGBVerticalXor", "RGBVerticalXorScale", "RGBHorizontalXor", "RGBHorizontalXorScale", "AndOrXorStrobe", "AndOrXorStrobeScale", "RandomXorOpposite","RGBTrailsXor", "DifferenceXor","MedianBlurXor"}; + CallFilter(Xor[rand()%Xor.size()], frame); + AddInvert(frame); +} + +void ac::RandomMirrorBlend(cv::Mat &frame) { + cv::Mat frame_copy = frame.clone(); + RandomMirror(frame_copy); + static double alpha = 1.0, alpha_max = 7.0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = frame_copy.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = static_cast((pixel[j]^pix[j])*alpha); + } + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 10.0, 0.005); + AddInvert(frame); +} + +void ac::RandomMirrorAlphaBlend(cv::Mat &frame) { + DarkenImage(frame, 4); + cv::Mat frame_copy = frame.clone(); + RandomMirror(frame_copy); + static double alpha = 1.0, alpha_max = 7.0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = frame_copy.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = static_cast((pixel[j]*(alpha+1))+(pix[j]*alpha)); + } + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max); + AddInvert(frame); +} + +void ac::Bitwise_XOR_AlphaSubFilter(cv::Mat &frame) { + if(subfilter == -1) + return; + if(ac::draw_strings[subfilter] == "Bitwise_XOR_AlphaSubFilter") + return; + cv::Mat frame_copy = frame.clone(); + static double alpha = 1.0, alpha_max = 7.0; + CallFilter(subfilter, frame_copy); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = frame_copy.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = static_cast((pixel[j]^pix[j])*alpha); + } + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 10, 0.005); + AddInvert(frame); +} + +void ac::AlphaBlendSubFilter(cv::Mat &frame) { + if(subfilter == -1) + return; + if(ac::draw_strings[subfilter] == "AlphaBlendSubFilter") + return; + double alpha = 1.0, alpha_max = 7.0; + cv::Mat frame_copy = frame.clone(); + cv::Mat output_copy = frame.clone(); + CallFilter(subfilter, frame_copy); + AlphaBlend(frame_copy, output_copy, frame, alpha); + static int dir = 1; + procPos(dir, alpha, alpha_max, 10, 0.005); + AddInvert(frame); +} + +void ac::GradientSubFilterXor(cv::Mat &frame) { + if(subfilter == -1) + return; + if(ac::draw_strings[subfilter] == "GradientSubFilterXor") + return; + cv::Mat frame_copy = frame.clone(); + CallFilter(subfilter, frame_copy); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = frame_copy.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = (pixel[j]+z)^(pix[j]+i); + } + } + } + AddInvert(frame); +} + +void ac::XorBlend_SubFilter(cv::Mat &frame) { + if(subfilter == -1) + return; + if(ac::draw_strings[subfilter] == "XorBlend_SubFilter") + return; + cv::Mat frame_copy = frame.clone(); + static double alpha = 1.0, alpha_max = 7.0; + CallFilter(subfilter, frame_copy); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = frame_copy.at(z, i); + for(int j = 0; j < 3; ++j) { + unsigned int alpha_val = static_cast(1+alpha); + pixel[j] = (static_cast((pixel[j]*alpha_val))) ^ (static_cast((pix[j]*alpha_val))); + } + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 10, 0.005); + AddInvert(frame); +} + +void ac::SmoothSubFilterAlphaBlend(cv::Mat &frame) { + if(subfilter == -1) + return; + if(ac::draw_strings[subfilter] == "SmoothSubFilterAlphaBlend") + return; + static MatrixCollection<8> collection; + cv::Mat frame_copy = frame.clone(); + cv::Mat same_copy = frame.clone(); + CallFilter(subfilter, frame_copy); + collection.shiftFrames(frame_copy); + Smooth(frame_copy, &collection); + static double alpha = 1.0, alpha_max = 3.0; + AlphaBlend(frame_copy, same_copy, frame, alpha); + static int dir = 1; + procPos(dir, alpha, alpha_max, 4.0, 0.1); + AddInvert(frame); +} + +void ac::SmoothSubFilterXorBlend(cv::Mat &frame) { + if(subfilter == -1) + return; + if(ac::draw_strings[subfilter] == "SmoothSubFilterXorBlend") + return; + static MatrixCollection<8> collection; + cv::Mat frame_copy = frame.clone(); + cv::Mat same_copy = frame.clone(); + CallFilter(subfilter, frame_copy); + collection.shiftFrames(frame_copy); + Smooth(frame_copy, &collection); + static double alpha = 1.0, alpha_max = 3.0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = frame_copy.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = (static_cast(pixel[j]*(alpha+1))) ^ (static_cast(pix[j]*alpha)); + } + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 4.0, 0.1); + AddInvert(frame); +} + +void ac::IntertwineSubFilter(cv::Mat &frame) { + if(subfilter == -1) + return; + if(ac::draw_strings[subfilter] == "IntertwineSubFilter") + return; + + cv::Mat frame_copy = frame.clone(); + CallFilter(subfilter, frame_copy); + bool skip_val = true; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = frame_copy.at(z, i); + if(skip_val == true) { + pixel = pix; + } + } + skip_val = (skip_val == true) ? false : true; + } + AddInvert(frame); +} + +void ac::RandBlend(cv::Mat &frame) { + static std::vector filter_names {"Self AlphaBlend", "Blend #3", "RandTriBlend", "Rainbow Blend", "Rand Blend","XorMultiBlend", "BlendedScanLines", "FrameBlend", "FrameBlendRGB", "PrevFrameBlend", "HorizontalBlend", "VerticalBlend", "OppositeBlend", "BlendSwitch", "IncreaseBlendHorizontal", "BlendIncrease","TrailsBlend", "BlendThree", "BlendTrails", "WeakBlend", "SmoothTrailsSelfAlphaBlend", "SmoothTrailsRainbowBlend","RandomAlphaBlend", "RandomTwoFilterAlphaBlend", "AlphaBlendPosition", "BlendAlphaXor", "AlphaBlendRandom", "ChannelSortAlphaBlend", "StrobeBlend", "GaussianBlend", "SelfXorBlend","CycleShiftRandomRGB_XorBlend", "CycleShiftRandomAlphaBlend","ParticleBlend", "BlendInAndOut", "BlendScaleInAndOut", "RandomXorBlend", "InitBlend"}; + + CallFilter(filter_names[rand()%filter_names.size()], frame); + AddInvert(frame); +} + +void ac::EveryOther(cv::Mat &frame) { + static double alpha = 1.0, alpha_max = 6.0; + bool on_off = true; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + if(on_off == true) { + for(int j = 0; j < 3; ++j) { + pixel[j] = static_cast(pixel[j]*(alpha+1)); + } + } + on_off = (on_off == true) ? false : true; + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max); + AddInvert(frame); +} + +void ac::EveryOtherSubFilter(cv::Mat &frame) { + if(subfilter == -1) + return; + if(ac::draw_strings[subfilter] == "EveryOtherSubFilter") + return; + + cv::Mat frame_copy = frame.clone(); + CallFilter(subfilter, frame_copy); + bool on_off = true; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + if(on_off == true) { + cv::Vec3b pix = frame_copy.at(z, i); + pixel = pix; + } + on_off = (on_off == true) ? false : true; + } + } + AddInvert(frame); +} + +void ac::SmoothRandomFilter(cv::Mat &frame) { + static MatrixCollection<8> collection; + randomFilter(frame); + collection.shiftFrames(frame); + Smooth(frame, &collection); + AddInvert(frame); +} + +void ac::RandomFilterRandomTimes(cv::Mat &frame) { + randomFilter(frame); + int num = rand()%4; + for(int i = 0; i < num; ++i) { + randomFilter(frame); + } + AddInvert(frame); +} + +void ac::RandomSubFilterRandomTimes(cv::Mat &frame) { + if(subfilter == -1) + return; + if(ac::draw_strings[subfilter] == "RandomSubFilterRandomTimes") + return; + CallFilter(subfilter, frame); + int num = rand()%4; + for(int i = 0; i < num; ++i) { + CallFilter(subfilter, frame); + } + AddInvert(frame); +} + +void ac::AddToFrameSubFilter(cv::Mat &frame) { + if(subfilter == -1) + return; + if(ac::draw_strings[subfilter] == "AddToFrameSubFilter") + return; + + cv::Mat frame_copy = frame.clone(); + CallFilter(subfilter, frame_copy); + Add(frame, frame_copy); + AddInvert(frame); +} + +void ac::MirrorXor(cv::Mat &frame) { + cv::Mat frame_copy = frame.clone(); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b val = frame_copy.at(frame.rows-z-1, frame.cols-i-1); + for(int j = 0; j < 3; ++j) { + pixel[j] = (pixel[j] ^ val[j]); + } + } + } + AddInvert(frame); +} + +void ac::MirrorXorAll(cv::Mat &frame) { + cv::Mat frame_copy = frame.clone(); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b values[3]; + values[0] = frame_copy.at(frame.rows-z-1, frame.cols-i-1); + values[1] = frame_copy.at(frame.rows-z-1, i); + values[2] = frame_copy.at(z, frame.cols-i-1); + for(int j = 0; j < 3; ++j) { + pixel[j] = (pixel[j] ^ values[0][j] ^ values[1][j] ^ values[2][j]); + } + } + } + AddInvert(frame); +} + +void ac::MirrorXorScale(cv::Mat &frame) { + static double alpha = 1.0, alpha_max = 4.0; + cv::Mat frame_copy = frame.clone(); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b values[3]; + values[0] = frame_copy.at(frame.rows-z-1, frame.cols-i-1); + values[1] = frame_copy.at(frame.rows-z-1, i); + values[2] = frame_copy.at(z, frame.cols-i-1); + for(int j = 0; j < 3; ++j) { + pixel[j] = (pixel[j] ^ values[0][j] ^ values[1][j] ^ values[2][j]); + pixel[j] = static_cast(pixel[j]*(alpha+1)); + } + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 5.0, 0.01); + AddInvert(frame); +} + +void ac::EnergyMirror(cv::Mat &frame) { + static MatrixCollection<8> collection; + cv::Mat frame_copy = frame.clone(); + MirrorXorAll(frame_copy); + collection.shiftFrames(frame_copy); + Smooth(frame, &collection); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::SmoothSubFilter(cv::Mat &frame) { + if(subfilter == -1) + return; + if(ac::draw_strings[subfilter] == "SmoothSubFilter") + return; + static MatrixCollection<8> collection; + cv::Mat frame_copy = frame.clone(); + CallFilter(subfilter, frame_copy); + collection.shiftFrames(frame_copy); + Smooth(frame, &collection); + AddInvert(frame); +} + +void ac::EnergizeSubFilter(cv::Mat &frame) { + if(subfilter == -1) + return; + if(ac::draw_strings[subfilter] == "EnergizeSubFilter") + return; + static MatrixCollection<8> collection; + cv::Mat frame_copy = frame.clone(); + CallFilter(subfilter, frame_copy); + collection.shiftFrames(frame_copy); + Smooth(frame, &collection); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::SmoothSubFilter16(cv::Mat &frame) { + if(subfilter == -1) + return; + if(ac::draw_strings[subfilter] == "SmoothSubFilter16") + return; + static MatrixCollection<16> collection; + cv::Mat frame_copy = frame.clone(); + CallFilter(subfilter, frame_copy); + collection.shiftFrames(frame_copy); + Smooth(frame, &collection); + AddInvert(frame); +} + +void ac::EnergizeSubFilter16(cv::Mat &frame) { + if(subfilter == -1) + return; + if(ac::draw_strings[subfilter] == "EnergizeSubFilter16") + return; + static MatrixCollection<16> collection; + cv::Mat frame_copy = frame.clone(); + CallFilter(subfilter, frame_copy); + collection.shiftFrames(frame_copy); + Smooth(frame, &collection); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::EnergizeSubFilter32(cv::Mat &frame) { + if(subfilter == -1) + return; + if(ac::draw_strings[subfilter] == "EnergizeSubFilter32") + return; + + static MatrixCollection<32> collection; + cv::Mat frame_copy = frame.clone(); + CallFilter(subfilter, frame_copy); + collection.shiftFrames(frame_copy); + Smooth(frame, &collection); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::SmoothSubFilter32(cv::Mat &frame) { + if(subfilter == -1) + return; + if(ac::draw_strings[subfilter] == "SmoothSubFilter32") + return; + static MatrixCollection<32> collection; + cv::Mat frame_copy = frame.clone(); + CallFilter(subfilter, frame_copy); + collection.shiftFrames(frame_copy); + Smooth(frame, &collection); + AddInvert(frame); +} + +void ac::HalfAddSubFilter(cv::Mat &frame) { + if(subfilter == -1) + return; + if(ac::draw_strings[subfilter] == "HalfAddSubFilter") + return; + cv::Mat frame_copy = frame.clone(); + CallFilter(subfilter, frame_copy); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = frame_copy.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] /= 4; + pixel[j] += pix[j]; + } + } + } + AddInvert(frame); +} +void ac::HalfXorSubFilter(cv::Mat &frame) { + if(subfilter == -1) + return; + if(ac::draw_strings[subfilter] == "HalfXorSubFilter") + return; + cv::Mat frame_copy = frame.clone(); + CallFilter(subfilter, frame_copy); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = frame_copy.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] /= 4; + pixel[j] ^= pix[j]; + } + } + } + AddInvert(frame); +} + +void ac::StaticXorBlend(cv::Mat &frame) { + static cv::Vec3b value(rand()%255, rand()%255, rand()%255); + static MatrixCollection<8> collection; + ChannelSort(frame); + collection.shiftFrames(frame); + StaticXor(frame, &collection, value); + AddInvert(frame); +} + +void ac::PsycheSort(cv::Mat &frame) { + cv::Vec3b value(rand()%255,rand()%255,rand()%255); + static MatrixCollection<8> collection; + collection.shiftFrames(frame); + ChannelSort(frame); + StaticXor(frame, &collection,value); + AddInvert(frame); +} + +void ac::XorScale(cv::Mat &frame) { + static cv::Scalar scale(rand()%255, rand()%255, rand()%255); + static int speed = 1; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] = pixel[j]^static_cast(scale[j]); + } + } + static int dir[3] = {1,1,1}; + for(int j = 0; j < 3; ++j) { + if(dir[j] == 1) { + scale[j] += speed; + + if(scale[j] >= 255) + dir[j] = 0; + + } else if(dir[j] == 0) { + scale[j] -= speed; + + if(scale[j] <= 1) + dir[j] = 1; + } + } + AddInvert(frame); +} + +void ac::ChannelMedianSubFilter(cv::Mat &frame) { + if(subfilter == -1) + return; + if(ac::draw_strings[subfilter] == "ChannelMedianSubFilter") + return; + cv::Mat frame_copy = frame.clone(), output; + ChannelSort(frame_copy); + CallFilter(subfilter, frame_copy); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::GaussianStrobe(cv::Mat &frame) { + rainbowBlend(frame); + GaussianBlur(frame); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::StrobeSort(cv::Mat &frame) { + ChannelSort(frame); + GaussianStrobe(frame); +} + +void ac::GlitchSortStrobe(cv::Mat &frame) { + static MatrixCollection<8> collection; + static cv::Vec3b color_(rand()%255, rand()%255, rand()%255); + cv::Mat frame_copy = frame.clone(); + glitchSort(frame_copy); + collection.shiftFrames(frame_copy); + StaticXor(frame, &collection, color_); + MedianBlend(frame); + AddInvert(frame); +} + +void ac::Bitwise_XOR_Blend(cv::Mat &frame) { + static MatrixCollection<8> collection; + static double alpha = 1.0, alpha_max = 4.0; + cv::Mat frame_copy = frame.clone(); + GaussianBlur(frame_copy); + collection.shiftFrames(frame_copy); + cv::Scalar values; + for(int z = 0; z < frame.rows; ++z) { + for(int i =0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < collection.size(); ++j) { + cv::Vec3b inner = collection.frames[j].at(z, i); + for(int q = 0; q < 3; ++q) { + values[q] += (inner[q]*alpha); + } + } + for(int q = 0; q < 3; ++q) { + values[q] /= collection.size(); + pixel[q] = static_cast(values[q]) ^ static_cast(pixel[q]*alpha); + } + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 6.0); + AddInvert(frame); +} + +void ac::Bitwise_XOR_Sort(cv::Mat &frame) { + ChannelSort(frame); + Bitwise_XOR_Blend(frame); +} + +void ac::Bitwise_OR_Blend(cv::Mat &frame) { + static MatrixCollection<8> collection; + static double alpha = 1.0, alpha_max = 4.0; + cv::Mat frame_copy = frame.clone(); + GaussianBlur(frame_copy); + collection.shiftFrames(frame_copy); + cv::Scalar values; + for(int z = 0; z < frame.rows; ++z) { + for(int i =0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < collection.size(); ++j) { + cv::Vec3b inner = collection.frames[j].at(z, i); + for(int q = 0; q < 3; ++q) { + values[q] += (inner[q]*alpha); + } + } + for(int q = 0; q < 3; ++q) { + values[q] /= collection.size(); + pixel[q] = static_cast(values[q]) | static_cast(pixel[3-q-1]*alpha); + } + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 6.0); + AddInvert(frame); +} + +void ac::Bitwise_AND_Blend(cv::Mat &frame) { + static MatrixCollection<8> collection; + static double alpha = 1.0, alpha_max = 4.0; + cv::Mat frame_copy = frame.clone(); + GaussianBlur(frame_copy); + collection.shiftFrames(frame_copy); + cv::Scalar values; + for(int z = 0; z < frame.rows; ++z) { + for(int i =0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < collection.size(); ++j) { + cv::Vec3b inner = collection.frames[j].at(z, i); + for(int q = 0; q < 3; ++q) { + values[q] += (inner[q]*alpha); + } + } + for(int q = 0; q < 3; ++q) { + values[q] /= collection.size(); + pixel[q] = static_cast(values[q]) & static_cast(pixel[3-q-1]*alpha); + } + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 6.0); + AddInvert(frame); +} + +void ac::BitwiseColorMatrix(cv::Mat &frame) { + static MatrixCollection<8> collection; + static double alpha[3] = {1.0,4.0,1.0}, alpha_max = 4.0; + cv::Mat frame_copy = frame.clone(); + GaussianBlur(frame_copy); + collection.shiftFrames(frame_copy); + cv::Scalar values; + for(int z = 0; z < frame.rows; ++z) { + for(int i =0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < collection.size(); ++j) { + cv::Vec3b inner = collection.frames[j].at(z, i); + for(int q = 0; q < 3; ++q) { + values[q] += (inner[q]*alpha[q]); + } + } + for(int q = 0; q < 3; ++q) { + values[q] /= collection.size(); + pixel[q] ^= static_cast(values[q]) & static_cast(pixel[3-q-1]*alpha[q]); + } + } + } + static int dir[3] = {1, 0, 1};; + + for(int j = 0; j < 3; ++j) + procPos(dir[j], alpha[j], alpha_max, 6.0, 0.1); + + AddInvert(frame); +} + +void ac::PixelReverseXor(cv::Mat &frame) { + static double alpha[3] = {1.0,4.0,1.0}, alpha_max = 4.0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = pixel; + for(int j = 0; j < 3; ++j) { + pixel[j] = static_cast(pix[3-j-1]*alpha[j])^pixel[j]; + } + } + } + static int dir[3] = {1, 0, 1};; + for(int j = 0; j < 3; ++j) + procPos(dir[j], alpha[j], alpha_max, 6.0, 0.1); + AddInvert(frame); +} + +void ac::PixelatedSubFilterSort(cv::Mat &frame) { + if(ac::draw_strings[subfilter] == "PixelatedSubFilterSort") + return; + + static MatrixCollection<8> collection; + Block(frame); + ChannelSort(frame); + collection.shiftFrames(frame); + SmoothRGB(frame, &collection); + if(subfilter != -1) + CallFilter(subfilter, frame); +} + +void ac::SilverBlend(cv::Mat &frame) { + static double alpha = 1.0, alpha_max = 3.0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + double total = (pixel[0]+pixel[1]+pixel[2]) * alpha; + unsigned int value = static_cast(total); + for(int j = 0; j < 3; ++j) { + pixel[j] = pixel[j]^value; + } + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 4.0, 0.1); +} + +void ac::RandomPixelOrderSort(cv::Mat &frame) { + static double alpha = 1.0, alpha_max = 5.0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + SwapColors(pixel); + for(int j = 0; j < 3; ++j) { + pixel[j] = static_cast(pixel[j]*(alpha+1)); + } + } + } + StrobeSort(frame); + static int dir = 1; + procPos(dir, alpha, alpha_max); + AddInvert(frame); +} + +void ac::ImageXorAlpha(cv::Mat &frame) { + if(blend_set == true) { + static double alpha = 1.0, alpha_max = 3.0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + int cX = AC_GetFX(blend_image.cols, i, frame.cols); + int cY = AC_GetFZ(blend_image.rows, z, frame.rows); + cv::Vec3b pix = blend_image.at(cY, cX); + for(int j = 0; j < 3; ++j) { + pixel[j] = (static_cast((pixel[j]*(alpha+1))) ^ static_cast((pix[j]*alpha))); + } + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 4.0, 0.01); + AddInvert(frame); + } +} + +void ac::ImageAverageXor(cv::Mat &frame) { + if(blend_set == true) { + static MatrixCollection<8> collection; + static double alpha = 1.0, alpha_max = 3.0; + collection.shiftFrames(frame); + DarkenFilter(frame); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Scalar values; + for(int q = 0; q < collection.size(); ++q) { + cv::Vec3b pix = collection.frames[q].at(z, i); + for(int j = 0; j < 3; ++j) + values[j] += pix[j]; + } + int cX = AC_GetFX(blend_image.cols, i, frame.cols); + int cY = AC_GetFZ(blend_image.rows, z, frame.rows); + cv::Vec3b pix = blend_image.at(cY, cX); + for(int j = 0; j < 3; ++j) { + values[j] /= collection.size(); + pixel[j] = (static_cast(pixel[j]*(alpha+1)) ^ static_cast((pix[j]*alpha)) ^ static_cast((values[j]*alpha))); + } + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 3.1, 0.1); + AddInvert(frame); + } +} + +void ac::PixelXorBlend(cv::Mat &frame) { + static double alpha = 1.0, alpha_max = 2.0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pix = pixel; + for(int j = 0; j < 3; ++j) { + unsigned char v = static_cast(pix[j]*alpha); + pixel[j] = (pix[0]^pix[1]^pix[2])^v; + } + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 5.0, 0.1); + AddInvert(frame); +} + +void ac::SelfAlphaScale(cv::Mat &frame) { + static double alpha = 1.0, alpha_max = 4.0; + static int index[3] = {0,255/3,255/2}; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] = static_cast((pixel[j]^index[j])*alpha); + } + } + + for(int j = 0; j < 3; ++j) { + ++index[j]; + if(index[j] >= 255) { + index[j] = 0; + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max); + AddInvert(frame); +} + +void ac::SelfScaleAlpha(cv::Mat &frame) { + static double alpha = 1.0, alpha_max = 4.0; + static int index[3] = {0,255/3,255/2}; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] = static_cast((pixel[j]*(alpha+1)))^index[j]; + } + } + static int direction[3] = {1,1,1}; + for(int j = 0; j < 3; ++j) { + if(direction[j] == 1) { + if(index[j] >= 255) + direction[j] = 0; + else + ++index[j]; + + } else if(direction[j] == 0) { + if(index[j] <= 1) + direction[j] = 1; + else + --index[j]; + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max); + AddInvert(frame); +} + +void ac::RainbowXorBlend(cv::Mat &frame) { + static double alpha = 1.0f, alpha_max = 6.0; + static int rb = 0, gb = 0, bb = 0; + if(rb == 0) + rb = rand()%255; + else ++rb; + if(gb == 0) + gb = rand()%255; + else ++gb; + if(bb == 0) + bb = rand()%255; + else ++bb; + static int i = 0, z = 0; + for(z = 0; z < frame.rows; ++z) { + for(i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + pixel[0] = (pixel[0]^static_cast(alpha*rb)); + pixel[1] = (pixel[1]^static_cast(alpha*gb)); + pixel[2] = (pixel[2]^static_cast(alpha*bb)); + } + } + if(rb > 255) rb = 0; + if(gb > 255) gb = 0; + if(bb > 255) bb = 0; + static int direction = 1; + procPos(direction, alpha, alpha_max); + resetAlpha(direction, alpha); + AddInvert(frame); +} + +void ac::FrameDifference(cv::Mat &frame) { + static MatrixCollection<8> collection; + cv::Vec3b r(rand()%255, rand()%255, rand()%255); + ImageDifference(frame, &collection, [=](cv::Vec3b &val) { + for(int j = 0; j < 3; ++j) { + val[j] = val[j]^r[j]; + } + }); + AddInvert(frame); +} + +void ac::SmallDiffference(cv::Mat &frame) { + static MatrixCollection<8> collection; + cv::Vec3b pix_value(rand()%255, rand()%255, rand()%255); + ImageDifference(frame, &collection, [=](cv::Vec3b &val) { + for(int j = 0; j < 3; ++j) { + val[j] = val[j]^pix_value[j]; + } + }, 5); + AddInvert(frame); +} + +void ac::FadeBlend(cv::Mat &frame) { + static cv::Scalar fade(rand()%255, rand()%255, rand()%255); + static int dir[3] = { 1, 1, 1 }; + static double alpha = 1.0, alpha_max = 4.0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + unsigned char ch = static_cast(fade[j]*alpha); + pixel[j] = pixel[j]^ch; + } + } + } + for(int j = 0; j < 3; ++j) { + if(dir[j] == 1) { + fade[j] += alpha_increase; + if(fade[j] >= 255) { + dir[j] = 0; + } + } else if(dir[j] == 0) { + fade[j] -= alpha_increase; + if(fade[j] <= 1) { + dir[j] = 1; + fade[j] = rand()%255; + } + } + } + static int direction = 1; + procPos(direction, alpha, alpha_max); + AddInvert(frame); +} + +void ac::FilteredDifferenceSubFilter(cv::Mat &frame) { + if(subfilter == -1 || ac::draw_strings[subfilter] == "FilteredDifferenceSubFilter") + return; + static MatrixCollection<8> collection; + cv::Mat copy_frame = frame.clone(); + CallFilter(subfilter,copy_frame); + ImageCopyDifference(frame, copy_frame, &collection); + AddInvert(frame); +} diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/ac-filtercat.cpp b/windows/Acid.Cam.Qt.Windows.March.2019/ac-filtercat.cpp new file mode 100755 index 0000000..5a41486 --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/ac-filtercat.cpp @@ -0,0 +1,128 @@ +/* + * Software written by Jared Bruni https://github.com/lostjared + + This software is dedicated to all the people that experience mental illness. + + Website: http://lostsidedead.com + YouTube: http://youtube.com/LostSideDead + Instagram: http://instagram.com/jaredbruni + Twitter: http://twitter.com/jaredbruni + Facebook: http://facebook.com/LostSideDead0x + + You can use this program free of charge and redistrubute it online as long + as you do not charge anything for this program. This program is meant to be + 100% free. + + BSD 2-Clause License + + Copyright (c) 2019, Jared Bruni + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + */ + +#include"ac.h" + +namespace ac { + + std::unordered_map filter_menu_map; + std::vector svAll; + std::vector svAllSorted; + std::vector svUser; + + void add_filter(std::vector *menu_list, std::string menu_name) { + filter_menu_map[menu_name].menu_name = menu_name; + filter_menu_map[menu_name].menu_list = menu_list; + } + + void init_filter_menu_map() { + for(int i = 0; i < draw_max-4; ++i) { + svAll.push_back(ac::draw_strings[i]); + svAllSorted.push_back(ac::draw_strings[i]); + } + std::sort(svAllSorted.begin(), svAllSorted.end()); + add_filter(&svAll, "All Filters"); + add_filter(&svAllSorted, "All Filters Sorted"); + add_filter(&vzBlend, "Blend"); + add_filter(&svDistort, "Distort"); + add_filter(&svPattern, "Pattern"); + add_filter(&svGradient, "Gradient"); + add_filter(&svMirror, "Mirror"); + add_filter(&svStrobe, "Strobe"); + add_filter(&svBlur, "Blur"); + add_filter(&svImage, "Image"); + add_filter(&svSquare, "Square"); + add_filter(&svOther_Custom, "Other"); + add_filter(&vSub, "SubFilter"); + add_filter(&svCustom_Spec, "Special"); + add_filter(&svUser, "User"); + } + + const char *szCustom[] = {"Negate","DarkNegate","DarkenFilter","Reverse","ReverseFrameBlend", "No Filter", "Blend with Source","BlendFor360","XorWithSource","AlphaBlendWithSource", "Plugin", "Custom",0}; + const char *szCustom_Spec[] = {"Negate","DarkNegate", "DarkenFilter","Reverse","ReverseFrameBlend", "No Filter", "Blend with Source","BlendFor360", "XorWithSource", "AlphaBlendWithSource", "Plugin",0}; + + std::vector svCustom_Spec {"Negate","DarkenFilter","Reverse","ReverseFrameBlend", "No Filter", "Blend with Source", "BlendFor360", "XorWithSource", "AlphaBlendWithSource", "DarkNegate"}; + + + std::vector vzBlend { "Self AlphaBlend", "Self Scale", "Blend #3", "Negative Paradox", "ThoughtMode", "RandTriBlend", "Filter3","Rainbow Blend","Rand Blend","Pixel Scale","Pulse", "Combine Pixels", "Blend_Angle", "XorMultiBlend", "UpDown","LeftRight", "BlendedScanLines","XorSine", "FrameBlend", "FrameBlendRGB", "PrevFrameBlend", "HorizontalBlend", "VerticalBlend", "OppositeBlend", "DiagonalLines", "HorizontalLines", "BlendSwitch", "IncreaseBlendHorizontal", "BlendIncrease", "ColorRange", "VectorIncrease", "BlendThree", "HorizontalStripes", "Dual_SelfAlphaRainbow", "Dual_SelfAlphaBlur", "SurroundPixelXor", "WeakBlend", "AverageVertical", "RandomAlphaBlend", "RandomTwoFilterAlphaBlend", "AlphaBlendPosition", "BlendRowAlpha", "BlendRow", "BlendRowByVar", "BlendRowByDirection", "BlendAlphaXor", "SelfXorScale", "SelfAlphaRGB", "XorSelfAlphaImage", "AlphaBlendRandom", "ChannelSortAlphaBlend", "RandomXor", "RandomXorFlash", "SoftXor", "SelfXorBlend", "SelfXorDoubleFlash", "SelfOrDoubleFlash", "BlendRowCurvedSqrt", "CycleShiftRandomAlphaBlend", "TanAlphaGrid", "BlendInAndOut", "BlendScaleInAndOut", "AcidGlitch", "LiquidFilter", "MatrixXorAnd", "XorAlpha", "SelfXorAverage", "RandomXorBlend", "RGBVerticalXor", "RGBVerticalXorScale", "RGBHorizontalXor", "RGBHorizontalXorScale", "FadeInAndOut", "InitBlend", "LagBlend", "SubFilter", "AddFilter", "AlphaBlendSubFilter", "SmoothSubFilterAlphaBlend", "IntertwineSubFilter", "RandBlend", "EveryOther", "EveryOtherSubFilter", "SmoothSubFilter", "EnergizeSubFilter", "SmoothSubFilter16", "EnergizeSubFilter16", "EnergizeSubFilter32", "SmoothSubFilter32", "HalfAddSubFilter", "HalfXorSubFilter", "StaticXorBlend", "XorScale", "ChannelMedianSubFilter", "Bitwise_XOR_Blend", "Bitwise_OR_Blend", "Bitwise_AND_Blend", "PixelReverseXor", "SilverBlend", "PixelXorBlend", "SelfAlphaScale", "SelfScaleAlpha", "RainbowXorBlend", "FadeBlend", "SelfAlphaScaleBlend", "FadeBars", "ShadeRGB", "InterRGB_SubFilter", "InterSmoothSubFilter", "InterRGB_Bars_XY", "InterRGB_Bars_X", "InterRGB_Bars_Y", "StoredFramesAlphaBlend_SubFilter", "BlendSubFilter", "BlendAlphaSubFilter", "ReverseFrameBlend", "ReverseFrameBlendSwitch", "Blend_AlphaSubFilter","RandomBlendFilter","DoubleRandomBlendFilter", "FlipBlendW", "FlipBlendH", "FlipBlendWH", "FlipBlendAll", "FrameMedianBlendSubFilter", "SelfScaleXorIncrease", "Blend_RedGreenBlue", "Blend_RedReenBlue_Dark", "DarkModBlend", "IncDifference", "IncDifferenceAlpha", "MirrorMedianBlend", "SubFilterMedianBlend", "DarkenBlend", "DarkCollectionSubFilter", "DarkSmooth_Filter", "DarkSelfAlpha", "FlipMedian", "FlipMedianSubFilter", "Bars", "BlendBurred", "BlendCombinedValues", "BlendCombinedValueSubFilter", "BlendSubFilterAlpha", "PurpleRain", "CopyXorAlpha", "AveragePixelsXor", "AveragePixelAlpha", "NegativeByRow", "AveragePixelCollection", "IncorrectLine", "XorShift", "RGBSep1x", "RandomIncrease", "BGRBlend", "RGBBlend", "IncreaseDecreaseGamma", "GammaIncDecIncrease", "SelfScaleSortBlend", "FlipAlphaBlend", "RandomFlipFilter", "FlipMatrixCollection", "SelfScaleByFrame", "SmoothCollectionAlphaBlend", "ShuffleAlphaWithRGB", "ShuffleAlphaMedianBlend", "AverageLinesBlend", "AverageVerticalLinesBlend", "PixelValuesPlusOne", "AverageHorizontalFilter", "AverageVerticalFilter", "SmoothRainbowMedian", "MatrixCollectionBlend", "MatrixCollectionXor", "MatrixCollectionXor32", "MatrixCollectionRandomColorMap", "MatrixCollectionDarkXor", "MatrixCollectionRGB", "SmoothMedianBlend", "ColorTransition", "ColorTransitionRandom", "CosSinMedianBlend", "CosSinMultiplyCollectionXor", "RandomSmoothAlphaMedian", "ColorExpand", "ColorXorScale", "MatrixCollectionSmoothAlphaBlend", "Bitwise_XOR_BlendFrame", "SimpleMatrixBlend", "SurroundingPixels", "SurroundingPixelsAlpha", "MatrixCollectionSurroundingPixels", "ColorFlashIncrease", "ScaleFilter", "NegativeDarkenXor", "ChangeXorEachSecond", "MorphXor", "XorFrameShuffle", "ChannelSortMedianBlend", "SplitFrameBlend", "SplitFrameCollection", "SplitFrameMirror", "IncreaseRGB", "XorDifferenceFilter"}; + + std::vector svDistort { "Tri","Distort","CDraw","Sort Fuzz","Fuzz","Boxes","Boxes Fade", "ShiftPixels", "ShiftPixelsDown","WhitePixel", "Block", "BlockXor","BlockStrobe", "BlockScale", "InvertedScanlines", "ColorMorphing", "NegativeStrobe", "ParticleRelease","ParticleBlend","ParticleFlash","ParticleAlpha","ParticleReleaseXor","ParticleReleaseXorVec", "All Red", "All Green", "All Blue", "LineRGB", "PixelRGB", "BoxedRGB", "KruegerSweater", "RGBStatic1", "RGBStatic2", "FrameBars", "Lines", "WhiteLines", "ThickWhiteLines", "UseLineObject", "LeftLines", "ParticleFast", "PictureBuzz", "ParticleSnow", "RandomPixels", "DarkRandomPixels", "PixelatedHorizontalLines", "PixelatedVerticalLines", "TwistedVision", "ParticleReleaseAlphaBlend", "ParticleReleaseWithImage"}; + + std::vector svPattern { "Blend Fractal","Blend Fractal Mood","Diamond Pattern" }; + + std::vector svGradient { "RandomGradient", "CosSinMultiply","New Blend","Color Accumlate1", "Color Accumulate2", "Color Accumulate3", "Filter8", "Graident Rainbow","Gradient Rainbow Flash","Outward", "Outward Square","GradientLines","GradientSelf","GradientSelfVertical","GradientDown","GraidentHorizontal","GradientRGB","GradientStripes", "GradientReverse", "GradientReverseBox", "GradientReverseVertical", "GradientNewFilter", "AverageLines", "QuadCosSinMultiply", "GradientColors", "GradientColorsVertical", "GradientXorSelfScale", "GradientLeftRight", "GraidentUpDown", "GradientLeftRightInOut", "GradientUpDownInOut", "GradientSubFilterXor","GradientXorPixels", "DivideAndIncH", "DivideAndIncW", "GradientAlphaXorHorizontal", "GradientAlphaXorVertical", "Filter8_Blend"}; + + std::vector svMirror { "ImageXorMirrorFilter", "NewOne", "MirrorBlend", "Sideways Mirror","Mirror No Blend","Mirror Average", "Mirror Average Mix","Reverse","Double Vision","RGB Shift","RGB Sep","Side2Side","Top2Bottom", "Soft_Mirror", "KanapaTrip", "InterReverse", "InterMirror", "InterFullMirror", "MirrorRGB", "LineByLineReverse", "CycleShiftRGB", "CycleShiftRandomRGB", "CycleShiftRandomRGB_XorBlend", "RGBMirror", "MirrorStrobe", "RandomMirror", "RandomMirrorBlend", "RandomMirrorAlphaBlend", "MirrorXor", "MirrorXorAll", "MirrorXorScale", "EnergyMirror", "MirrorXorAlpha", "MirrorEnergizeSubFilter", "IntertwinedMirror", "BlurredMirror", "DoubleRandomMirror", "FlipMirror", "FlipMirrorAverage","FlipMirrorSubFilter", "RGBMirror1", "RGBMirror1Median", "FlashMirror", "ReverseMirrorX", "MirrorXorAll_Reverse", "MirrorRGBReverse", "MirrorRGBReverseBlend", "MirrorBitwiseXor", "EnergyMirrorDark", "AlphaBlendMirror", "TwistedMirror", "MirrorMatrixCollection", "MirrorMatrixSource", "SmoothMirrorBlurFlip", "MirrorOrder", "BlurMirrorOrder", "AveragePixelMirror", "SoftFeedbackMirror", "MirrorAlphaBlend","RandomMirrorBitwiseXor", "MirrorBlendFrame", "MirrorBlendVertical", "MirrorVerticalAndHorizontal", "MirrorSidesMedian", "MirrorEachSecond", "Mirror_Xor_Combined", "MirrorFrameShuffle", "MirrorShuffleSmooth", "Mirror_Xor_Smooth", "XorMirrorBlendFrame", "MatrixCollectionMirrorDirection"}; + + std::vector svStrobe{ "StrobeEffect", "Blank", "Type","Random Flash","Strobe Red Then Green Then Blue","Flash Black","FlashWhite","StrobeScan", "RGBFlash", "ReinterpretDouble", "DiamondStrobe", "BitwiseXorStrobe","FlashBlackAndWhite", "StrobeBlend", "FibFlash", "ScaleFlash", "FadeStrobe", "AndStrobe", "AndStrobeScale", "AndPixelStrobe", "AndOrXorStrobe", "AndOrXorStrobeScale", "BrightStrobe", "DarkStrobe", "RandomXorOpposite", "StrobeTransform", "RandomStrobe", "OrStrobe", "DifferenceStrobe", "BlackAndWhiteDifferenceStrobe", "DifferenceXor", "DifferenceRand", "HalfNegateStrobe", "RandomStrobeFlash", "GaussianStrobe", "StrobeSort", "GlitchSortStrobe", "StrobeXor", "AlphaMorph", "StrobeXorAndOr", "FlashMedianBlend", "RainbowGlichStrobe", "NegateSwitchStrobe", "StrobeAlphaShuffle","MirrorOrderAlpha", "StrobeNegatePixel", "StrobeNegateInOut", "AlphaStrobeBlend", "StrobeRandomChannel", "MaxRGB", "IncreaseQuick"}; + + + std::vector svBlur { "GaussianBlur", "Median Blur", "Blur Distortion", "ColorTrails","TrailsFilter", "TrailsFilterIntense", "TrailsFilterSelfAlpha", "TrailsFilterXor","BlurSim", "TrailsInter", "TrailsBlend", "TrailsNegate", "AcidTrails", "HorizontalTrailsInter" ,"Trails", "BlendTrails", "SmoothTrails", "SmoothTrailsSelfAlphaBlend", "SmoothTrailsRainbowBlend", "MedianBlend", "XorTrails", "RainbowTrails", "NegativeTrails", "IntenseTrails", "GaussianBlend", "RandomAmountMedianBlur", "MedianBlendAnimation", "AlphaAcidTrails", "RandomBlur", "RGBTrails", "RGBTrailsDark", "RGBTrailsAlpha", "RGBTrailsNegativeAlpha", "MovementRGBTrails", "RGBTrailsXor", "DifferenceBrightStrobe", "PsycheTrails", "DarkTrails", "MedianBlurXor", "NegateTrails", "FrameBlurSubFilter", "Headrush", "MedianBlurSubFilter", "RGBColorTrails", "PixelByPixelXor", "RGBMedianBlend", "MedianBlend16", "BlurSmooth", "BlurSmoothMedian", "BlurFlip", "BlurMirrorGamma", "MedianBlendDark", "MedianBlendSubFilterEx", "SmoothTrailsBlend", "MatrixCollectionRGBXor", "LinesMedianBlend", "MedianBlendSoft", "MatrixCollectionBlurAlpha", "MedianTrails", "ColorTransitionMedian", "ColorTransitionRandomMedian", "RandomTrails", "TrailsRGB", "MatrixTrailsXorRandom", "MedianBlendSelfBlend", "RandomAmountOfMedianBlur", "GaussianBlendEx", "BlurSmoothSubFilterAlphaBlend", "BlurSmoothMatrix", "MedianBlurInc", "GaussianBlurInc", "BlurSmoothMedianInc", "BlurSmoothGaussianInc", "BlurMatrixCollectionXor", "BlurSmoothRevFilter", "SmoothMedian64", "DarkTrailsEffect", "MedianBlend64", "SmoothRandomChannels", "SaturateBlend", "ColorTrailsFilter", "DarkNegateRainbowMedian"}; + + std::vector svImage{"Blend with Image", "Blend with Image #2", "Blend with Image #3", "Blend with Image #4", "ImageFile", "ImageXor", "ImageAlphaBlend", "ImageInter", "ImageX", "SmoothRandomImageBlend", "SmoothImageAlphaBlend", "BlendImageOnOff", "ImageShiftUpLeft", "AlphaBlendImageXor", "ExactImage", "BlendImageXor", "BlendImageAround_Median", "ImageBlendTransform", "ImageXorAlpha", "ImageAverageXor", "DarkImageMedianBlend", "ImageBlendSubFilter", "ImageBlendXorSubFilter", "ImageCollectionSubFilter", "MirrorAlphaBlendedImage", "AlphaBlendXorImage", "ImageXorFrame", "ImageXorFunction", "ImageXorAlphaBlend", "ImageSubtractMedianBlend", "ImageDarkBlend", "ImageAverageDark", "ImageRemainderPixel", "ImageEnergy", "ImageDistortion", "SmoothExactImageXorAlpha", "SmoothImageAlphaBlendMedian", "ImageDarkenSmoothMedian", "XorReverseImageSmooth", "ImageSmoothMedianBlend", "ImageAlphaXorMedianBlend", "ColorTransitionImageSubFilter", "RotateImage", "RotateBlendImage", "RotateAlphaBlendImage", "ImageXorScale", "MatrixCollectionBlurImageXorAlpha", "MatrixCollectionSurroundingPixelsImage", "ImageTransparent", "ImageAlphaCollectionSmoothBlend", "ImageRandomColormap", "ImageRandomColormapAlphaBlend", "ImageRandomColormapAlphaScale", "ImageRandomColormapSubFilter", "ImageShuffle","ImageFadeInOut", "ImageFadeBlackInOut", "ImageFadeFrameInOut", "ImageFadeDouble", "ImageXor_SubFilter", "ImageStrobeOnOff", "FrameImageFadeInOut", "FrameImageFadeInOutDouble", "ShuffleImage", "ChangeImageEachSecond", "ChangeImageFilterOnOff", "ImageXorSmooth", "ImageNegate", "ImageNegateAlphaBlend", "FrameNegateAlphaBlendImage", "ImageChannelSubFilter"}; + + std::vector svOther { "Mean", "Laplacian", "Bitwise_XOR", "Bitwise_AND", "Bitwise_OR", "Channel Sort", "Reverse_XOR", "Bitwise_Rotate", "Bitwise_Rotate Diff","Equalize","PixelSort", "GlitchSort", "HPPD", "FuzzyLines","Random Filter", "Alpha Flame Filters","Scanlines", "TV Static","FlipTrip", "Canny", "Inter","Circular","MoveRed","MoveRGB","MoveRedGreenBlue", "Wave","HighWave","VerticalSort","VerticalChannelSort","ScanSwitch","ScanAlphaSwitch", "XorAddMul","RandomIntertwine","RandomFour","RandomTwo","Darken", "AverageRandom","RandomCollectionAverage","RandomCollectionAverageMax","BitwiseXorScale","XorChannelSort","Bitwise_XOR_Average","NotEqual","Sort_Vertical_Horizontal","Sort_Vertical_Horizontal_Bitwise_XOR","Scalar_Average_Multiply","Scalar_Average","Total_Average","VerticalColorBars","inOrder","inOrderBySecond","DarkenFilter","RandomFilterBySecond","ThreeRandom", "Blend with Source", "Plugin", "Custom", "inOrderAlpha", "XorBackwards", "MoveUpLeft", "Stuck", "StuckStrobe", "SoftFeedback", "SoftFeedbackFrames", "ResizeSoftFeedback","SoftFeedback8","SoftFeedbackFrames8","ResizeSoftFeedback8", "ResizeSoftFeedbackSubFilter", "SoftFeedbackRandFilter","SoftFeedback32","SoftFeedbackFrames32","ResizeSoftFeedback32", "SoftFeedbackRandFilter32", "SoftFeedbackSubFilter","SoftFeedbackResizeSubFilter", "SoftFeedbackResizeSubFilter64", "SoftFeedbackReszieSubFilter64_Negate", "SoftFeedbackReszieSubFilter64_Mirror", "RandomOther", "RandomXorFilter", "Bitwise_XOR_AlphaSubFilter", "XorBlend_SubFilter", "RandomFilterRandomTimes", "RandomSubFilterRandomTimes", "PsycheSort", "Bitwise_XOR_Sort", "BitwiseColorMatrix", "PixelatedSubFilterSort", "RandomPixelOrderSort", "FrameDifference", "SmallDiffference","FilteredDifferenceSubFilter", "GammaDarken5", "GammaDarken10","ChannelSort_NoBlend_Descending", "ChannelSort_NoBlend_Ascending", "ShuffleRGB", "ShuffleAlpha", "ShuffleSelf", "StrobeShuffle", "RainbowGlitch", "ShuffleColorMap", "RandomColorMap", "RandomOrder", "RandomAlphaBlend", "FlipShuffle", "FlipRandom", "CannyRandomPixels", "ChangeEachSecond", "SplitFramesSort", "SplitFrameFilter", "RandomChannels", "AlphaBlendChannelSort", "IncreaseRandomIndex"}; + + std::vector svOther_Custom { "Mean", "Laplacian", "Bitwise_XOR", "Bitwise_AND", "Bitwise_OR", "Channel Sort", "Reverse_XOR","Bitwise_Rotate","Bitwise_Rotate Diff", "Equalize","PixelSort", "GlitchSort","HPPD","FuzzyLines","Random Filter", "Alpha Flame Filters","Scanlines", "TV Static","FlipTrip", "Canny","Inter","Circular","MoveRed","MoveRGB", "MoveRedGreenBlue", "Wave","HighWave","VerticalSort","VerticalChannelSort","ScanSwitch", "ScanAlphaSwitch","XorAddMul", "RandomIntertwine","RandomFour","RandomTwo","Darken", "Blend with Source","AverageRandom","RandomCollectionAverage","RandomCollectionAverageMax","BitwiseXorScale","XorChannelSort","Bitwise_XOR_Average","NotEqual","Sort_Vertical_Horizontal","Sort_Vertical_Horizontal_Bitwise_XOR", "Scalar_Average_Multiply","Scalar_Average","Total_Average","VerticalColorBars","inOrder","inOrderBySecond","DarkenFilter","RandomFilterBySecond","ThreeRandom","inOrderAlpha","XorBackwards", "Plugin", "MoveUpLeft", "Stuck", "StuckStrobe", "SoftFeedback", "SoftFeedbackFrames", "ResizeSoftFeedback", "SoftFeedback8","SoftFeedbackFrames8","ResizeSoftFeedback8", "ResizeSoftFeedbackSubFilter", "SoftFeedbackRandFilter", "SoftFeedback32","SoftFeedbackFrames32","ResizeSoftFeedback32", "SoftFeedbackRandFilter32", "SoftFeedbackSubFilter","SoftFeedbackResizeSubFilter", "SoftFeedbackResizeSubFilter64", "SoftFeedbackReszieSubFilter64_Negate", "SoftFeedbackReszieSubFilter64_Mirror", "RandomOther", "RandomXorFilter", "Bitwise_XOR_AlphaSubFilter", "XorBlend_SubFilter", "RandomFilterRandomTimes", "RandomSubFilterRandomTimes", "PsycheSort", "Bitwise_XOR_Sort", "BitwiseColorMatrix", "PixelatedSubFilterSort", "RandomPixelOrderSort", "FrameDifference", "SmallDiffference", "FilteredDifferenceSubFilter", "GammaDarken5", "GammaDarken10", "ChannelSort_NoBlend_Descending", "ChannelSort_NoBlend_Ascending", "ShuffleRGB", "ShuffleAlpha", "ShuffleSelf", "StrobeShuffle", "RainbowGlitch", "ShuffleColorMap", "RandomColorMap", "RandomOrder", "FeedbackColormap", "RandomAlphaBlendFilter", "FlipShuffle", "FlipRandom", "SplitFramesSort", "SplitFrameFilter", "RandomChannels", "IncreaseRandomIndex", "AlphaBlendChannelSort", "IncreaseRandomIndex"}; + + std::vector svSquare {"SquareSwap","SquareSwap4x2","SquareSwap8x4", "SquareSwap16x8","SquareSwap64x32", "SquareBars","SquareBars8","SquareSwapRand16x8","SquareVertical8","SquareVertical16","SquareVertical_Roll","SquareSwapSort_Roll","SquareVertical_RollReverse","SquareSwapSort_RollReverse", "RandomFilteredSquare","RandomQuads","QuadRandomFilter", "RollRandom", "GridFilter8x", "GridFilter16x", "GridFilter8xBlend", "GridRandom", "GridRandomPixel", "PixelatedSquare", "SmoothSourcePixel", "ColorLines", "Curtain", "RandomCurtain", "RandomCurtainVertical", "CurtainVertical", "SlideFilter","SlideFilterXor", "RandomSlideFilter", "SlideUpDown", "SlideUpDownXor", "SlideUpDownRandom", "SlideSubFilter", "SlideSubUpDownFilter", "FourSquare", "EightSquare", "DiagonalSquare", "DiagonalSquareRandom", "SquareStretchDown", "SquareStretchRight", "SquareStretchUp", "SquareStretchLeft", "ExpandSquareBlendSubFilter", "ExpandSquareSubFilter", "ExpandSquareVerticalSubFilter", "SquareDivideSubFilter", "SquareSubFilter", "SquareSubFilter8", "SquareRandomFilter"}; + + + std::vector vSub { "SlideSubFilter", "SubFilter", "ResizeSoftFeedbackSubFilter", "SoftFeedbackSubFilter", "SoftFeedbackResizeSubFilter", "SoftFeedbackResizeSubFilter64", "SoftFeedbackReszieSubFilter64_Negate", "SoftFeedbackReszieSubFilter64_Mirror", "Bitwise_XOR_AlphaSubFilter", "AlphaBlendSubFilter", "GradientSubFilterXor", "XorBlend_SubFilter", "SmoothSubFilterAlphaBlend", "SmoothSubFilterXorBlend", "IntertwineSubFilter", "EveryOtherSubFilter", "RandomSubFilterRandomTimes", "AddToFrameSubFilter", "SmoothSubFilter", "EnergizeSubFilter", "SmoothSubFilter16", "EnergizeSubFilter16", "EnergizeSubFilter32", "SmoothSubFilter32", "HalfAddSubFilter", "HalfXorSubFilter", "ChannelMedianSubFilter", "PixelatedSubFilterSort", "FilteredDifferenceSubFilter", "ExpandSquareSubFilter", "ExpandSquareBlendSubFilter", "ExpandSquareVerticalSubFilter", "MirrorEnergizeSubFilter", "InterRGB_SubFilter", "InterSmoothSubFilter", "StoredFramesAlphaBlend_SubFilter", "BlendSubFilter", "BlendAlphaSubFilter", "Blend_AlphaSubFilter", "FrameMedianBlendSubFilter", "FrameBlurSubFilter", "ImageBlendSubFilter", "ImageBlendXorSubFilter", "ImageCollectionSubFilter", "SubFilterMedianBlend", "DarkCollectionSubFilter", "FlipMedianSubFilter", "FlipMirrorSubFilter", "BlendCombinedValueSubFilter", "BlendSubFilterAlpha", "CollectionXorSourceSubFilter", "BlendReverseSubFilter", "SmoothBlendReverseSubFilter", "MedianBlendBufferSubFilter", "RGBBlendSubFilter", "XorOppositeSubFilter", "BlendSmoothSubFilter", "BlurSmoothSubFilter", "BlurFlipSubFilter", "MedianBlendSubFilterEx", "ShiftFrameSmoothSubFilter", "ShiftFrameStaticXorSubFilter", "RandomSubFilter", "BlendWithFrameSubFilter", "AlphaBlendWithFrameSubFilter", "AlphaXorBlendWithFrameSubFilter", "XorBlendSubFilter", "SmoothMedianRotateSubFilter", "XorSubFilter", "XorAlphaSubFilter", "BlurXorAlphaSubFilter", "ImageAlphaXorMedianSubFilter", "ImageSmoothAlphaXorSubFilter", "ImageXorSubFilter", "ImageAlphaXorSubFilter", "BlendWithRainbowSubFilter","BlendWithJetSubFilter", "ColormapBlendSubFilter", "RandomColorMapAlphaBlendSubFilter", "RandomOrderMedianBlendSubFilter", "MirrorOrderSubFilter","FilterStrobeSubFilter", "BlendImageWithSubFilter", "BlendImageWithSubFilterAlpha", "AndImageSubFilterXor", "AlphaBlendImageSubFilterXor", "AlphaBlendImageSubFilterXorRev", "ParticleReleaseSubFilter", "ParticleReleaseImageSubFilter", "ImageEnergySubFilter", "ImageDistortionSubFilter", "ReverseSubFilterBlend", "ReverseSubFilterXor", "ImageReverseSubFilter", "ImageSmoothMedianSubFilter", "MatrixCollectionSubFilter", "MatrixCollectionImageSubFilter", "TrailsSubFilter", "TrailsSubFilter32", "CompareWithSubFilter", "ColorTransitionSubFilter", "CurtainSubFilter", "RandomTrailsSubFilter", "Filter8_SubFilter", "SquareRandomSubFilter", "ColorExpandSubFilter", "RotateImageSubFilter", "FlipStrobeSubFilter", "MirrorSidesSubFilter", "MedianFrameAlphaBlendSubFilter", "MedianSubFilter", "ColorXorScaleSubFilter", "MatrixCollectionShiftSubFilter", "MatrixCollectionImageShiftSubFilter", "MatrixCollectionBlurImageSubFilter", "MatrixCollectionBlurImageSubFilter16", "ImageAlphaBlendSubFilter", "MultipleMatrixCollectionSubFilter", "BlurAlphaSubFilter", "BlurImageSubFilter", "MedianBlendSubFilter", "MedianBlendImageSubFilter", "BlendHalfSubFilter", "BlurImageAlphaBlendSubFilter", "BlurImageAlphaBlendScaleSubFilter", "AlphaBlendWithSubFilter", "AlphaBlendScaleWithSubFilter", "MatrixBlendSubFilter", "SmoothMatrixBlendSubFilter", "BlurSmoothAlphaXorBlendSubFilter", "BlurTwiceSubFilter", "BlurFrameBlendSubFilter", "BlurFrameSubFilter", "MatrixCollection8XorSubFilter", "MatrixCollectionSurroundingPixelsSubFilter", "MatrixCollectionSurroundingPixelsImageSubFilter", "MatrixImageAlphaBlendSubFilter","ImageAlphaBlendWithFrameSubFilter", "ImageFadeBlackInOutSubFilter", "ImageFadeFrameInOutSubFilter", "FadeSubFilter","FadeSubFilterRev","ImageBlendSubFilterMedianBlend","FadeSubFilterXor","BlurXorSubFilter", "NegateBlendSubFilter", "MorphXorWithSubFilter", "MirrorReverseSubFilterAlphaBlend", "SmoothSubFilter64", "SmoothMedian32_SubFilter", "SmoothAlphaMedian_SubFilter", "SmoothImage_SubFilter", "SmoothImageMedian_SubFilter", "SmoothImageAndSubFilter", "SmoothSubFilter90", "SmoothMedianImageSubFilter16", "ImageNegateAlphaBlendSubFilter", "SplitFrameSortSubFilter", "SplitFrameBlendSubFilter", "SmoothChannelSubFilter", "SaturateBlendSubFilter", "ColorTrailsSubFilter"}; + + + void SortFilters() { + std::sort(vzBlend.begin(), vzBlend.end()); + std::sort(svDistort.begin(), svDistort.end()); + std::sort(svPattern.begin(), svPattern.end()); + std::sort(svGradient.begin(), svGradient.end()); + std::sort(svMirror.begin(), svMirror.end()); + std::sort(svStrobe.begin(), svStrobe.end()); + std::sort(svBlur.begin(), svBlur.end()); + std::sort(svImage.begin(), svImage.end()); + std::sort(svOther.begin(), svOther.end()); + std::sort(svOther_Custom.begin(), svOther_Custom.end()); + std::sort(svSquare.begin(), svSquare.end()); + std::sort(vSub.begin(), vSub.end()); + } +} diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/ac-filtercat.h b/windows/Acid.Cam.Qt.Windows.March.2019/ac-filtercat.h new file mode 100755 index 0000000..db4f92a --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/ac-filtercat.h @@ -0,0 +1,90 @@ +/* + * Software written by Jared Bruni https://github.com/lostjared + + This software is dedicated to all the people that experience mental illness. + + Website: http://lostsidedead.com + YouTube: http://youtube.com/LostSideDead + Instagram: http://instagram.com/jaredbruni + Twitter: http://twitter.com/jaredbruni + Facebook: http://facebook.com/LostSideDead0x + + You can use this program free of charge and redistrubute it online as long + as you do not charge anything for this program. This program is meant to be + 100% free. + + BSD 2-Clause License + + Copyright (c) 2019, Jared Bruni + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + */ + +#ifndef __FILTER_CAT_H__ +#define __FILTER_CAT_H__ + +#include +#include +#include +namespace ac { + + class FilterItem { + public: + FilterItem() = default; + std::vector *menu_list; + std::string menu_name; + FilterItem(std::vector &v, std::string name) : menu_list(&v), menu_name(name) {} + FilterItem(const FilterItem &f) : menu_list(f.menu_list), menu_name(f.menu_name) {} + FilterItem &operator=(const FilterItem &f) { + menu_list = f.menu_list; + menu_name = f.menu_name; + return *this; + } + }; + + extern std::vector vzBlend; + extern std::vector svDistort; + extern std::vector svPattern; + extern std::vector svGradient; + extern std::vector svMirror; + extern std::vector svStrobe; + extern std::vector svBlur; + extern std::vector svImage; + extern std::vector svOther; + extern std::vector svOther_Custom; + extern std::vector svSquare; + extern std::vector vSub; + extern std::vector svCustom_Spec; + extern std::vector svAll; + extern std::vector svAllSorted; + extern std::vector svUser; + extern const char *szCustom[]; + extern const char *szCustom_Spec[]; + extern std::unordered_map filter_menu_map; + extern void SortFilters(); + extern void init_filter_menu_map(); +} + +#endif + diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/ac-grid.cpp b/windows/Acid.Cam.Qt.Windows.March.2019/ac-grid.cpp new file mode 100755 index 0000000..39caccd --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/ac-grid.cpp @@ -0,0 +1,285 @@ +/* + * Software written by Jared Bruni https://github.com/lostjared + + This software is dedicated to all the people that experience mental illness. + + Website: http://lostsidedead.com + YouTube: http://youtube.com/LostSideDead + Instagram: http://instagram.com/jaredbruni + Twitter: http://twitter.com/jaredbruni + Facebook: http://facebook.com/LostSideDead0x + + You can use this program free of charge and redistrubute it online as long + as you do not charge anything for this program. This program is meant to be + 100% free. + + BSD 2-Clause License + + Copyright (c) 2019, Jared Bruni + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + */ + +#include "ac.h" + +ac::GridBox::GridBox() : color(rand()%255, rand()%255, rand()%255), on(true) {} +ac::GridBox::GridBox(const Rect &r, const cv::Vec3b &col) : location(r), color(col) {} +ac::GridBox::GridBox(const cv::Vec3b &col) : color(col), on(true) {} +ac::GridBox::GridBox(const ac::GridBox &gb) : location(gb.location),color(gb.color),on(gb.on) {} +ac::GridBox &ac::GridBox::operator=(const ac::GridBox &gb) { + color = gb.color; + location = gb.location; + on = gb.on; + return *this; +} +ac::Grid::Grid() :boxes(0), g_random(false) {} +ac::Grid::~Grid() { + if(boxes != 0) { + cleanBoxes(); + } +} + +bool operator<(const ac::Point &p1, const ac::Point &p2) { + if(p1.x < p2.x && p1.y < p2.y) + return true; + return false; +} + +void ac::Grid::cleanBoxes() { + if(boxes != 0) { + for(int j = 0; j < g_w; ++j) + delete [] boxes[j]; + + delete [] boxes; + boxes = 0; + } +} + +void ac::Grid::createGrid(cv::Mat &frame, int w, int h, int size) { + cleanBoxes(); + g_w = w; + g_h = h; + g_s = size; + boxes = new GridBox*[g_w]; + for(int i = 0; i < g_w; ++i) { + boxes[i] = new GridBox[h]; + } + if(!points.empty()) { + points.erase(points.begin(), points.end()); + } + for(int i = 0; i < g_w; ++i) { + for(int z = 0; z < g_h; ++z) { + cv::Vec3b pixel = frame.at(z*size, i*size); + Point p(i, z); + points.push_back(p); + boxes[i][z] = GridBox(pixel); + if(g_random) + boxes[i][z].on = ((rand()%4) == 0) ? false : true; + + } + } + std::shuffle(points.begin(), points.end(), rng); + current_offset = 0; +} + + +void ac::Grid::fillGrid(cv::Mat &frame) { + if(current_offset < points.size()) + return; + + for(int i = 0; i < g_w; ++i) { + for(int z = 0; z < g_h; ++z) { + cv::Vec3b pixel = frame.at(z*g_s, i*g_s); + boxes[i][z] = GridBox(pixel); + if(g_random) + boxes[i][z].on = ((rand()%4) == 0) ? false : true; + + } + } + current_offset = 0; + std::shuffle(points.begin(), points.end(), rng); +} + +void ac::Grid::updateGrid(int max) { + int iter_max = current_offset+max; + while(current_offset < points.size() && current_offset < iter_max) { + const Point &p = points[current_offset]; + boxes[p.x][p.y].on = false; + current_offset++; + } +} + +void ac::GridFilter8x(cv::Mat &frame) { + static cv::Size s(0, 0); + static const int box_size = 8; + static Grid grid; + if(frame.size() != s) { + grid.createGrid(frame, frame.cols/box_size, frame.rows/box_size, box_size); + s = frame.size(); + } + int num = 0; + if(frame.rows >= 1080) + num = 100; + else if(frame.rows >= 720) + num = 75; + else if(frame.rows >= 400) + num = 50; + else + num = 25; + grid.updateGrid(150+rand()%num); + grid.fillGrid(frame); + for(int z = 0; z < grid.g_h; ++z) { + for(int i = 0; i < grid.g_w; ++i) { + if(grid.boxes[i][z].on) + fillRect(frame, ac::Rect(i*box_size, z*box_size, grid.g_s, grid.g_s), grid.boxes[i][z].color); + } + } +} + +void ac::GridFilter16x(cv::Mat &frame) { + static cv::Size s(0, 0); + static const int box_size = 16; + static Grid grid; + if(frame.size() != s) { + grid.createGrid(frame, frame.cols/box_size, frame.rows/box_size, box_size); + s = frame.size(); + } + int num = 0; + if(frame.rows >= 1080) + num = 50; + else if(frame.rows >= 720) + num = 40; + else if(frame.rows >= 400) + num = 30; + else + num = 20; + grid.updateGrid(75+rand()%num); + grid.fillGrid(frame); + for(int z = 0; z < grid.g_h; ++z) { + for(int i = 0; i < grid.g_w; ++i) { + if(grid.boxes[i][z].on) + fillRect(frame, ac::Rect(i*box_size, z*box_size, grid.g_s, grid.g_s), grid.boxes[i][z].color); + } + } +} + +void ac::GridFilter8xBlend(cv::Mat &frame) { + static cv::Size s(0, 0); + static const int box_size = 8; + static double alpha = 1.0, alpha_max = 8.0; + static Grid grid; + if(frame.size() != s) { + grid.createGrid(frame, frame.cols/box_size, frame.rows/box_size, box_size); + s = frame.size(); + } + int num = 0; + if(frame.rows >= 1080) + num = 100; + else if(frame.rows >= 720) + num = 75; + else if(frame.rows >= 400) + num = 50; + else + num = 25; + grid.updateGrid(150+rand()%num); + grid.fillGrid(frame); + for(int z = 0; z < grid.g_h; ++z) { + for(int i = 0; i < grid.g_w; ++i) { + if(grid.boxes[i][z].on) { + cv::Vec3b pixel = frame.at(z*grid.g_s, i*grid.g_s); + for(int j = 0; j < 3; ++j) { + pixel[j] = static_cast((pixel[j]+grid.boxes[i][z].color[j])/2); + pixel[j] *= static_cast(alpha); + } + fillRect(frame, ac::Rect(i*box_size, z*box_size, grid.g_s, grid.g_s), pixel); + } + } + } + static int direction = 1; + procPos(direction, alpha, alpha_max); +} + +void ac::GridRandom(cv::Mat &frame) { + static cv::Size s(0, 0); + static const int box_size = 16; + static Grid grid; + if(frame.size() != s) { + grid.g_random = true; + grid.createGrid(frame, frame.cols/box_size, frame.rows/box_size, box_size); + s = frame.size(); + } + int num = 0; + if(frame.rows >= 2000) + num = 250; + if(frame.rows >= 1080) + num = 100; + else if(frame.rows >= 720) + num = 40; + else if(frame.rows >= 400) + num = 30; + else + num = 20; + grid.updateGrid(75+rand()%num); + grid.fillGrid(frame); + for(int z = 0; z < grid.g_h; ++z) { + for(int i = 0; i < grid.g_w; ++i) { + if(grid.boxes[i][z].on) + fillRect(frame, ac::Rect(i*box_size, z*box_size, grid.g_s, grid.g_s), grid.boxes[i][z].color); + } + } +} + +void ac::GridRandomPixel(cv::Mat &frame) { + static cv::Size s(0, 0); + static const int box_size = 8; + static Grid grid; + if(frame.size() != s) { + grid.createGrid(frame, frame.cols/box_size, frame.rows/box_size, box_size); + s = frame.size(); + } + int num = 0; + if(frame.rows >= 2000) + num = 400; + if(frame.rows >= 1080) + num = 200; + else if(frame.rows >= 720) + num = 100; + else if(frame.rows >= 400) + num = 50; + else + num = 20; + grid.updateGrid(75+rand()%num); + grid.fillGrid(frame); + for(int z = 0; z < grid.g_h; ++z) { + for(int i = 0; i < grid.g_w; ++i) { + if(grid.boxes[i][z].on) { + cv::Vec3b rpix(rand()%255,rand()%255,rand()%255); + for(int j = 0; j < 3; ++j) + rpix[j] += grid.boxes[i][z].color[j]; + fillRect(frame, ac::Rect(i*box_size, z*box_size, grid.g_s, grid.g_s),rpix); + } + } + } +} + diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/ac-image.cpp b/windows/Acid.Cam.Qt.Windows.March.2019/ac-image.cpp new file mode 100755 index 0000000..ea75644 --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/ac-image.cpp @@ -0,0 +1,614 @@ +/* + * Software written by Jared Bruni https://github.com/lostjared + + This software is dedicated to all the people that experience mental illness. + + Website: http://lostsidedead.com + YouTube: http://youtube.com/LostSideDead + Instagram: http://instagram.com/jaredbruni + Twitter: http://twitter.com/jaredbruni + Facebook: http://facebook.com/LostSideDead0x + + You can use this program free of charge and redistrubute it online as long + as you do not charge anything for this program. This program is meant to be + 100% free. + + BSD 2-Clause License + + Copyright (c) 2019, Jared Bruni + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + */ + +#include"ac.h" + +// Image blend +// cv::Mat as reference +void ac::imageBlend(cv::Mat &frame) { + static double pos = 1.0f;// static pos set to 1 + if(blend_set == true) {// if image is set + int i,z; + for(i = 0; i < frame.cols; ++i) { // top to bottom + for(z = 0; z < frame.rows; ++z) {// left to right + // get resized x,y + int cX = AC_GetFX(blend_image.cols, i, frame.cols); + int cY = AC_GetFZ(blend_image.rows, z, frame.rows); + cv::Vec3b ¤t = frame.at(z, i);// get current pixel + cv::Vec3b im = blend_image.at(cY, cX);// get pixel to blend from resized x,y + // set pixel values + current[0] = static_cast(current[0]+(im[0]*pos)); + current[1] = static_cast(current[1]+(im[1]*pos)); + current[2] = static_cast(current[2]+(im[2]*pos)); + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// invert pixel + } + } + } + static double pos_max = 7.0f;// max pos value + static int direction = 1; + procPos(direction, pos, pos_max); +} +// takes cv::Mat reference +void ac::imageBlendTwo(cv::Mat &frame) { + static double pos = 1.0f; // static pos equal 1.0 + if(blend_set == true) {// if image is set to blend with + int i,z;// loop variables + for(i = 0; i < frame.cols; ++i) { // left to right + for(z = 0; z < frame.rows; ++z) {// top to bottom + // resize x,y + int cX = AC_GetFX(blend_image.cols, i, frame.cols); + int cY = AC_GetFZ(blend_image.rows, z, frame.rows); + // grab pixels + cv::Vec3b ¤t = frame.at(z, i); + cv::Vec3b im = blend_image.at(cY, cX); + // set pixel values + current[0] = static_cast(im[0]+(current[0]*pos)); + current[1] = static_cast(im[1]+(current[1]*pos)); + current[2] = static_cast(im[2]+(current[2]*pos)); + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i); // invert pixel + } + } + } + static double pos_max = 7.0f;// max position set to 7.0 + static int direction = 1; + procPos(direction, pos, pos_max); +} +// blend with Image +// takes cv::Mat reference +void ac::imageBlendThree(cv::Mat &frame) { + if(blend_set == true) { // if blend_set is true (image selected) + static double pos = 1.0f;// static pos equals 1.0 + for(int i = 0; i < frame.cols; ++i) { // from top to bottom + for(int z = 0; z < frame.rows; ++z) {// from left to right + // calculate x,y pixel position + int cX = AC_GetFX(blend_image.cols, i, frame.cols); + int cY = AC_GetFZ(blend_image.rows, z, frame.rows); + // get pixel to manipulate reference + cv::Vec3b &pixel = frame.at(z, i); + // get image pixel from calculated x,y positions + cv::Vec3b im = blend_image.at(cY, cX); + // calculate pixel data + pixel[0] += (pixel[0]^im[0]); + pixel[1] += (pixel[1]^im[1]); + pixel[2] += static_cast((pixel[2]^im[2])*pos); + swapColors(frame, z, i);//swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel + + } + } + // static int directione quals 1 + static int direction = 1; + // static pos_max equals 7.0 + static double pos_max = 7.0f; + if(direction == 1) {// if direction equals 1 + pos += 0.005;// pos plus equal 0.005 + if(pos > pos_max) {// pos greater than pos_max + pos = pos_max;// pos set to pos_max + direction = 0;// direction set to zero + pos_max += 0.5f;// pos_max plus equal 0.5 + } + } else if(direction == 0) {// direction is set to 0 + pos -= 0.005;// pos minus equal 0.005 + if(pos <= 1) {/// pos less than equal 1 + if(pos_max > 15) pos_max = 1.0f;//reset pos_max if greater than 15 + direction = 1;// direction set to 1 + } + } + } +} + +// imageblend4 +void ac::imageBlendFour(cv::Mat &frame) { + if(blend_set == true) { + static int state = 0; + static double pos = 1.0; + int w = frame.cols;// frame width + int h = frame.rows;// frame height + int cw = blend_image.cols; + int ch = blend_image.rows; + for(int z = 3; z < h-3; ++z) {// top to bottom + for(int i = 3; i < w-3; ++i) {// left to right + // current pixel by reference + cv::Vec3b &pixel = frame.at(z, i); + // calculate resized image based x,y positions + int cX = AC_GetFX(blend_image.cols, i, frame.cols); + int cY = AC_GetFZ(blend_image.rows, z, frame.rows); + // grab pixel refernces from blend_image + cv::Vec3b &pr = blend_image.at((ch-cY), (cw-cX)); + cv::Vec3b &pg = blend_image.at((ch-cY), cX); + cv::Vec3b &pb = blend_image.at(cY, (cw-cX)); + // perform operation based on current state variable + switch(state) { + case 0: + pixel[0] += static_cast((pr[0]+pg[1]+pb[2])*pos); + pixel[1] += static_cast((pr[2]+pg[1]+pb[0])*pos); + break; + case 1: + pixel[1] += static_cast((pr[2]+pg[1]+pb[0])*pos); + pixel[2] += static_cast((pr[0]+pg[1]+pb[2])*pos); + break; + case 2: + pixel[2] += static_cast((pr[0]+pg[1]+pb[2])*pos); + pixel[0] += static_cast((pr[2]+pg[1]+pb[0])*pos); + break; + } + + } + + } + ++state;// increase state + if(state > 2) state = 0; // greater than 2 reset state + static int direction = 1; + // static pos_max equals 7.0 + static double pos_max = 3.0f; + if(direction == 1) {// if direction equals 1 + pos += 0.005;// pos plus equal 0.005 + if(pos > pos_max) {// pos greater than pos_max + pos = pos_max;// pos set to pos_max + direction = 0;// direction set to zero + pos_max += 0.5f;// pos_max plus equal 0.5 + } + } else if(direction == 0) {// direction is set to 0 + pos -= 0.005;// pos minus equal 0.005 + if(pos <= 1) {/// pos less than equal 1 + if(pos_max > 3) pos_max = 1.0f;//reset pos_max if greater than 15 + direction = 1;// direction set to 1 + } + } + } +} + +void ac::ImageFile(cv::Mat &frame) { + if(blend_set == true) { + const int w = frame.cols; + const int h = frame.rows; + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + int cX = AC_GetFX(blend_image.cols, i, frame.cols); + int cY = AC_GetFZ(blend_image.rows, z, frame.rows); + cv::Vec3b add_i = blend_image.at(cY, cX); + pixel[0] += add_i[0]; + pixel[1] += add_i[1]; + pixel[1] += add_i[2]; + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i); // invert pixel + } + } + } + +} +void ac::ImageXor(cv::Mat &frame) { + if(blend_set == true) { + const int w = frame.cols; + const int h = frame.rows; + static double alpha = 1.0, alpha_max = 4.0; + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + int cX = AC_GetFX(blend_image.cols, i, frame.cols); + int cY = AC_GetFZ(blend_image.rows, z, frame.rows); + cv::Vec3b add_i = blend_image.at(cY, cX); + for(int j = 0; j < 3; ++j) + pixel[j] = cv::saturate_cast((pixel[j]^add_i[j])*alpha); + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i); // invert pixel + } + } + static int direction = 1; + procPos(direction, alpha, alpha_max); + } +} + +void ac::ImageAlphaBlend(cv::Mat &frame) { + if(blend_set == true) { + const int w = frame.cols; + const int h = frame.rows; + static double alpha = 1.0, alpha_max = 2.0; + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + int cX = AC_GetFX(blend_image.cols, i, frame.cols); + int cY = AC_GetFZ(blend_image.rows, z, frame.rows); + cv::Vec3b add_i = blend_image.at(cY, cX); + for(int j = 0; j < 3; ++j) + pixel[j] = static_cast((pixel[j]*(alpha+1)) + (add_i[j] * alpha)); + + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i); // invert pixel + } + } + static int direction = 1; + procPos(direction, alpha, alpha_max); + } +} + +void ac::ImageInter(cv::Mat &frame) { + if(blend_set == true) { + static int start = 0, restart = 0; + const int w = frame.cols; + const int h = frame.rows; + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + int cX = AC_GetFX(blend_image.cols, i, frame.cols); + int cY = AC_GetFZ(blend_image.rows, z, frame.rows); + cv::Vec3b add_i = blend_image.at(cY, cX); + if(start == 0) { + pixel = add_i; + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i); // invert pixel + } + start = (start == 0) ? 1 : 0; + } + if(restart == 0) { + start = 1; + restart = 1; + } else { + start = 0; + restart = 0; + } + } +} + +// blend with image +void ac::ImageX(cv::Mat &frame) { + if(blend_set == true) { + + if(blend_image.empty()) + return; + + static double alpha = 1.0, alpha_max = 8.0; + static cv::Mat frame_blend = blend_image.clone(); + + for(int i = 1; i < frame.cols-2; ++i) { + for(int z = 1; z < frame.rows-2; ++z) { + int cX = AC_GetFX(frame_blend.cols, i, frame.cols); + int cY = AC_GetFZ(frame_blend.rows, z, frame.rows); + + if(cX >= frame_blend.cols || cY >= frame_blend.rows) + continue; + + cv::Vec3b &pixel = frame_blend.at(cY, cX); + cv::Vec3b pix = frame_blend.at(cY+1, cX+1); + pixel = pix; + cv::Vec3b &pix_value = frame.at(z, i); + for(int j = 0; j < 3; ++j) + pix_value[j] = static_cast(pixel[j]+(pix_value[j]*alpha)); + } + } + static int direction = 1; + procPos(direction, alpha, alpha_max); + } +} + +void ac::SmoothRandomImageBlend(cv::Mat &frame) { + if(blend_set == true) { + + if(testSize(frame) == false) + return; + + static MatrixCollection<8> collection; + int index = 0; + DrawFunction rfunc = getRandomFilter(index); + cv::Mat temp_frame; + cv::resize(blend_image, temp_frame, frame.size()); + rfunc(temp_frame); + collection.shiftFrames(temp_frame); + Smooth(frame, &collection); + } +} + +void ac::SmoothImageAlphaBlend(cv::Mat &frame) { + if(blend_set == true) { + static double alpha = 1.0, alpha_max = 2.0; + static MatrixCollection<8> collection; + cv::Mat temp_frame; + cv::Mat temp_image; + cv::Mat blend_image_scaled; + cv::resize(blend_image, blend_image_scaled, frame.size()); + temp_frame = frame.clone(); + AlphaBlend(temp_frame,blend_image_scaled,frame,alpha); + collection.shiftFrames(frame); + Smooth(temp_frame, &collection); + frame = temp_frame.clone(); + static int direction = 1; + procPos(direction, alpha, alpha_max, 8, 0.05); + } +} + +void ac::BlendImageOnOff(cv::Mat &frame) { + if(blend_set == true) { + static double alpha = 1.0, alpha_max = 4.0; + static int index = 0; + for(int z = 3; z < frame.rows-3; ++z) { + for(int i = 3; i < frame.cols-3; ++i) { + int cX = AC_GetFX(blend_image.cols, i, frame.cols); + int cY = AC_GetFZ(blend_image.rows, z, frame.rows); + cv::Vec3b pix[4]; + pix[0] = blend_image.at(cY, cX); + pix[1] = blend_image.at(cY+1, cX); + pix[2] = blend_image.at(cY, cX+1); + pix[3] = blend_image.at(cY+1, cX+1); + cv::Scalar value; + for(int j = 0; j < 4; ++j) { + for(int q = 0; q < 3; ++q) { + value[q] += pix[j][q]; + } + } + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + value[j] /= 4; + unsigned char val = static_cast(value[j]); + switch(index) { + case 0: + pixel[j] += static_cast(val*alpha); + break; + case 1: + pixel[j] -= static_cast(val*alpha); + break; + } + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } + ++index; + if(index > 1) index = 0; + + static int dir = 1; + procPos(dir, alpha, alpha_max); + } +} + +void ac::XorSelfAlphaImage(cv::Mat &frame) { + if(blend_set == true) { + static double alpha = 1.0, alpha_max = 2.0; + static double alpha_r = 14.0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + int cX = AC_GetFX(blend_image.cols, i, frame.cols); + int cY = AC_GetFZ(blend_image.rows, z, frame.rows); + cv::Vec3b pix = blend_image.at(cY, cX); + for(int j = 0; j < 3; ++j) { + //pixel[j] ^= (1-((pixel[j] + pix[j])) * (2+static_cast(alpha))); + pixel[j] = static_cast((pixel[j] * (1+alpha)) + (pix[j] * alpha_r)); + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } + static int dir = 1, dir_r = 0; + procPos(dir, alpha, alpha_max); + procPos(dir_r, alpha_r, alpha_max); + } +} + +void ac::AlphaBlendImageXor(cv::Mat &frame) { + if(blend_set == true) { + static MatrixCollection<8> collection; + SmoothImageAlphaBlend(frame); + Bitwise_XOR(frame); + collection.shiftFrames(frame); + Smooth(frame, &collection); + } +} + +void ac::ImageShiftUpLeft(cv::Mat &frame) { + if(blend_set) { + static double alpha = 1.0, alpha_max = 3.0; + static cv::Mat image = blend_image.clone(); + if(reset_filter == true) { + reset_filter = false; + image = blend_image.clone(); + } + for(int i = 0; i < image.cols-1; ++i) { + for(int z = 0; z < image.rows-1; ++z) { + cv::Vec3b val = image.at(z+1, i+1); + cv::Vec3b &target = image.at(z, i); + target = val; + } + } + for(int i = 0; i < frame.cols; ++i) { + for(int z = 0; z < frame.rows; ++z) { + int cX = AC_GetFX(image.cols, i, frame.cols); + int cY = AC_GetFZ(image.rows, z, frame.rows); + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b src_pixel = image.at(cY, cX); + for(int j = 0; j < 3; ++j) + pixel[j] = static_cast((alpha * pixel[j])) ^ src_pixel[j]; + + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max); + } +} + +void ac::ExactImage(cv::Mat &frame) { + if(blend_set == true) { + const int w = frame.cols; + const int h = frame.rows; + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + int cX = AC_GetFX(blend_image.cols, i, frame.cols); + int cY = AC_GetFZ(blend_image.rows, z, frame.rows); + cv::Vec3b add_i = blend_image.at(cY, cX); + pixel = add_i; + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i); // invert pixel + } + } + } +} + +// Use this with other filters like MedianBlend +void ac::BlendImageXor(cv::Mat &frame) { + if(blend_set == true) { + static double alpha = 1.0, alpha_max = 7.0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + int cX = AC_GetFX(blend_image.cols, i, frame.cols); + int cY = AC_GetFZ(blend_image.rows, z, frame.rows); + cv::Vec3b add_i = blend_image.at(cY, cX); + for(int j = 0; j < 3; ++j) { + pixel[j] = static_cast((pixel[j]^add_i[j])*alpha); + } + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 8, 0.01); + DarkenFilter(frame); + DarkenFilter(frame); + } +} + +void ac::BlendImageAround_Median(cv::Mat &frame) { + if(blend_set == true) { + static double alpha = 1.0, alpha_max = 7.0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b pixel_data[4]; + pixel_data[0] = pixel; + pixel_data[1] = frame.at(frame.rows-z-1, i); + pixel_data[2] = frame.at(z, frame.cols-i-1); + pixel_data[3] = frame.at(frame.rows-z-1, frame.cols-i-1); + int cX = AC_GetFX(blend_image.cols, i, frame.cols); + int cY = AC_GetFZ(blend_image.rows, z, frame.rows); + cv::Vec3b add_i = blend_image.at(cY, cX); + cv::Scalar val; + for(int j = 0; j < 4; ++j) { + for(int q = 0; q < 3; ++q) + val[q] += pixel_data[j][q]; + } + val[0] /= 4; + val[1] /= 4; + val[2] /= 4; + for(int j = 0; j < 3; ++j) { + pixel[j] = pixel[j] ^ add_i[j] ^ static_cast(val[j]); + } + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 8, 0.01); + DarkenFilter(frame); + DarkenFilter(frame); + MedianBlend(frame); + } +} + +void ac::ImageBlendTransform(cv::Mat &frame) { + + if(blend_set == true) { + static double alpha = 1.0, alpha_max = 4.0, speed = 0.1; + static MatrixCollection<8> collection; + collection.shiftFrames(frame); + + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b orig_pix = pixel; + int cX = AC_GetFX(blend_image.cols, i, frame.cols); + int cY = AC_GetFZ(blend_image.rows, z, frame.rows); + cv::Vec3b add_i = blend_image.at(cY, cX); + for(int j = 0; j < collection.size(); ++j) { + cv::Vec3b color_v = collection.frames[j].at(z, i); + for(int q = 0; q < 3; ++q) { + pixel[q] ^= color_v[q]; + } + } + for(int q = 0; q < 3; ++q) { + pixel[q] ^= static_cast((orig_pix[q] * alpha) + (add_i[q] * alpha)); + } + } + } + static int dir = 1; + if(dir == 1) { + alpha += speed; + if(alpha > alpha_max) { + dir = 0; + speed += 0.1; + } + } else { + alpha -= speed; + if(alpha <= 0.1) { + dir = 1; + speed += 0.1; + } + } + if(speed > 4) speed = 0.1; + + DarkenFilter(frame); + DarkenFilter(frame); + MedianBlend(frame); + GaussianBlur(frame); + GaussianBlur(frame); + } +} + +void ac::MirrorAlphaBlendedImage(cv::Mat &frame) { + if(blend_set == true) { + cv::Mat resized, frame_copy, new_copy; + cv::resize(blend_image, resized, frame.size()); + frame_copy = frame.clone(); + static double alpha = 1.0, alpha_max = 2.0; + AlphaXorBlend(resized, frame_copy, new_copy, alpha); + AlphaBlend(new_copy, frame_copy, frame, alpha); + static int dir = 1; + procPos(dir, alpha, alpha_max, 2.1, 0.05); + } +} + + + + + diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/ac-obj.cpp b/windows/Acid.Cam.Qt.Windows.March.2019/ac-obj.cpp new file mode 100755 index 0000000..d87f2ab --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/ac-obj.cpp @@ -0,0 +1,173 @@ +/* + * Software written by Jared Bruni https://github.com/lostjared + + This software is dedicated to all the people that experience mental illness. + + Website: http://lostsidedead.com + YouTube: http://youtube.com/LostSideDead + Instagram: http://instagram.com/jaredbruni + Twitter: http://twitter.com/jaredbruni + Facebook: http://facebook.com/LostSideDead0x + + You can use this program free of charge and redistrubute it online as long + as you do not charge anything for this program. This program is meant to be + 100% free. + + BSD 2-Clause License + + Copyright (c) 2019, Jared Bruni + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + */ + +#include "ac.h" + +ac::Point::Point() : x(0), y(0) {} +ac::Point::Point(const ac::Point &p) : x(p.x), y(p.y) {} +ac::Point::Point(int xx, int yy) : x(xx), y(yy) {} + +ac::Point &ac::Point::operator=(const ac::Point &p) { + x = p.x; + y = p.y; + return *this; +} + +void ac::Point::setPoint(int xx, int yy) { + x = xx; + y = yy; +} + +ac::Rect::Rect() : x(0), y(0), w(0), h(0) {} +ac::Rect::Rect(const ac::Rect &r) : x(r.x), y(r.y), w(r.w), h(r.h) {} +ac::Rect::Rect(int xx, int yy, int ww, int hh) : x(xx), y(yy), w(ww), h(hh) {} +ac::Rect::Rect(int xx, int yy) : x(xx), y(yy), w(0), h(0) {} +ac::Rect::Rect(int xx, int yy, cv::Size s) : x(xx), y(yy), w(s.width), h(s.height) {} +ac::Rect::Rect(Point pt, int ww, int hh) : x(pt.x), y(pt.y), w(ww), h(hh) {} +ac::Rect::Rect(Point pt, cv::Size s) : x(pt.x), y(pt.y), w(s.width), h(s.height){} + +ac::Rect &ac::Rect::operator=(const ac::Rect &r) { + x = r.x; + y = r.y; + w = r.w; + h = r.h; + return *this; +} + +void ac::Rect::setRect(int xx, int yy, int ww, int hh) { + x = xx; + y = yy; + w = ww; + h = hh; +} + +std::vector ac::all_objects; +bool ac::frames_released = false; + +void ac::release_all_objects() { + for(int i = 0; i < all_objects.size(); ++i) { + cv::Mat *m = reinterpret_cast(all_objects[i]); + if(m != 0 && !m->empty()) { + m->release(); + } + } + frames_released = true; +} + +ac::HLine::HLine() : w(0), h(0) { + +} + +void ac::HLine::createLines(int size, int width, int height) { + w = width; + h = height; + for(int i = 0; i < size; ++i) { + int rand_y = ((rand()%height)/8); + LineObject l; + l.line_size = ac::Rect(0,rand_y,width,3); + l.on = true; + l.dir = ((rand()%2) == 1) ? 1 : 0; + lines.push_back(l); + } +} + +void ac::HLine::drawLines(cv::Mat &frame) { + for(int l = 0; l < lines.size(); ++l) { + ac::Rect rc = lines[l].line_size; + int num = rand()%50, skip = rand()%20; + int count = 0, skip_count = 0; + for(int x = rc.x; x < rc.x+rc.w; ++x) { + if(count < num) { + if(rc.y >= 0 && rc.y < frame.rows && x >= 0 && x < frame.cols) { + cv::Vec3b &pixel = frame.at(rc.y, x); + pixel[0] = pixel[1] = pixel[2] = 255; + ++count; + } + } else { + if(skip_count >= skip) { + skip_count = 0; + count = 0; + num = rand()%50; + skip = rand()%20; + } else { + ++skip_count; + } + } + if(lines[l].dir == 1) { + ++lines[l].line_size.y; + if(lines[l].line_size.y > frame.rows) { + lines[l].line_size.y = rand()%frame.rows; + lines[l].dir = ((rand()%2) == 1) ? 1 : 0; + } + + } else if(lines[l].dir == 0) { + --lines[l].line_size.y; + if(lines[l].line_size.y <= 0) { + lines[l].line_size.y = rand()%frame.rows; + lines[l].dir = ((rand()%2) == 1) ? 1 : 0; + + } + } + } + } +} + +void ac::HLine::clearLines() { + if(!lines.empty()) { + lines.erase(lines.begin(), lines.end()); + } +} + + + + + + + + + + + + + + diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/ac-particle.cpp b/windows/Acid.Cam.Qt.Windows.March.2019/ac-particle.cpp new file mode 100755 index 0000000..284e7a7 --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/ac-particle.cpp @@ -0,0 +1,336 @@ +/* + * Software written by Jared Bruni https://github.com/lostjared + + This software is dedicated to all the people that experience mental illness. + + Website: http://lostsidedead.com + YouTube: http://youtube.com/LostSideDead + Instagram: http://instagram.com/jaredbruni + Twitter: http://twitter.com/jaredbruni + Facebook: http://facebook.com/LostSideDead0x + + You can use this program free of charge and redistrubute it online as long + as you do not charge anything for this program. This program is meant to be + 100% free. + + BSD 2-Clause License + + Copyright (c) 2019, Jared Bruni + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + */ + +#include"ac.h" + +// initalize to null +ac::ParticleEmiter::ParticleEmiter() : part(0), w(0), h(0), speed(1){} + +// clean up after done +ac::ParticleEmiter::~ParticleEmiter() { + if(part != 0) { + for(int i = 0; i < w; ++i) + delete [] part[i]; + delete [] part; + part = 0; + } +} + +void ac::ParticleEmiter::reset() { + w = 0; + h = 0; +} + +// set frame pixel values +void ac::ParticleEmiter::set(cv::Mat &frame) { + if(static_cast(frame.cols) != w || static_cast(frame.rows) != h) { + if(part != 0) { + for(int i = 0; i < w; ++i) + delete [] part[i]; + delete [] part; + } + w = frame.cols; + h = frame.rows; + part = new Particle*[w]; + for(int i = 0; i < w; ++i) { + part[i] = new Particle[h]; + for(int z = 0; z < h; ++z) { + part[i][z].x = i; + part[i][z].y = z; + part[i][z].dir = rand()%8; + } + } + } + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b pixel = frame.at(z, i); + part[i][z].pixel = pixel; + } + } +} + +// draw pixel values to frame +void ac::ParticleEmiter::draw(cv::Mat &frame) { + speed = 1; + movePixels();//move values before drawing + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + int x_pos = part[i][z].x; + int y_pos = part[i][z].y; + if(x_pos > 0 && x_pos < frame.cols && y_pos > 0 && y_pos < frame.rows) { + cv::Vec3b &pixel = frame.at(y_pos, x_pos); + pixel = part[i][z].pixel; + } + } + } +} + +void ac::ParticleEmiter::draw_blend(cv::Mat &frame) { + speed = 5; + DarkenFilter(frame); + movePixels();//move values before drawing + static double alpha = 1.0, alpha_max = 5.0; + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + int x_pos = part[i][z].x; + int y_pos = part[i][z].y; + if(x_pos > 0 && x_pos < frame.cols && y_pos > 0 && y_pos < frame.rows) { + cv::Vec3b &pixel = frame.at(y_pos, x_pos); + for(int j = 0; j < 3; ++j) + pixel[j] = pixel[j]+(part[i][z].pixel[j]^static_cast(alpha)); + } + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 10, 0.1); +} + +void ac::ParticleEmiter::draw_flash(cv::Mat &frame) { + speed = 10; + static int flash_index = 0; + static cv::Vec3b black(0,0,0); + cv::Vec3b color(rand()%255, rand()%255, rand()%255); + movePixels();//move values before drawing + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + int x_pos = part[i][z].x; + int y_pos = part[i][z].y; + if(x_pos > 0 && x_pos < frame.cols && y_pos > 0 && y_pos < frame.rows) { + cv::Vec3b &pixel = frame.at(y_pos, x_pos); + switch(flash_index) { + case 0: + pixel = part[i][z].pixel; + break; + case 1: + pixel = black; + break; + case 2: + pixel = color; + break; + } + ++flash_index; + if(flash_index > 2) + flash_index = 0; + } + } + } +} + +void ac::ParticleEmiter::draw_alpha(cv::Mat &frame) { + speed = 20; + movePixels();//move values before drawing + static double alpha = 1.0, alpha_max = 10; + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + int x_pos = part[i][z].x; + int y_pos = part[i][z].y; + if(x_pos > 0 && x_pos < frame.cols && y_pos > 0 && y_pos < frame.rows) { + cv::Vec3b &pixel = frame.at(y_pos, x_pos); + for(int j = 0; j < 3; ++j) + pixel[j] += part[i][z].pixel[j]*static_cast(alpha); + + } + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max, 15, 0.01); +} + +// draw movement fast +void ac::ParticleEmiter::draw_move(cv::Mat &frame) { + speed = 50; + movePixels();//move values before drawing + static double alpha = 1.0, alpha_max = 6.0; + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + int x_pos = part[i][z].x; + int y_pos = part[i][z].y; + if(x_pos > 0 && x_pos < frame.cols && y_pos > 0 && y_pos < frame.rows) { + cv::Vec3b &pixel = frame.at(y_pos, x_pos); + pixel = part[i][z].pixel; + } + } + } + static int dir = 1; + procPos(dir, alpha, alpha_max); +} + +void ac::ParticleEmiter::draw_op(cv::Mat &frame) { + speed = 1; + movePixels(); + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + int x_pos = part[i][z].x; + int y_pos = part[i][z].y; + if(x_pos > 0 && x_pos < frame.cols && y_pos > 0 && y_pos < frame.rows) { + cv::Vec3b &pixel = frame.at(y_pos, x_pos); + for(int j = 0; j < 3; ++j) + pixel[j] = part[i][z].pixel[j]^pixel[j]; + } + } + } +} + + +// move pixel coordinates around +void ac::ParticleEmiter::movePixels() { + for(int i = 0; i < w; ++i) { + for(int z = 0; z < h; ++z) { + Particle &p = part[i][z]; + p.m_count ++; + if(p.m_count > 250) { + p.m_count = 0; + p.dir = rand()%4; + continue; + } + switch(p.dir) { + case DIR_UP: + if(p.y > 0) { + p.y -= speed; + } else { + p.dir = rand()%8; + } + break; + case DIR_UP_LEFT: + + if(p.y > 0 && p.x > 0) { + p.y -= speed; + p.x -= speed; + } else { + p.dir = rand()%8; + } + + break; + case DIR_UP_RIGHT: + + if(p.y > 0 && p.x < w-1) { + p.y -= speed; + p.x += speed; + } else { + p.dir = rand()%8; + } + + break; + case DIR_DOWN_LEFT: + + if(p.y < h-1 && p.x > 0) { + p.y += speed; + p.x -= speed; + } else { + p.dir = rand()%8; + } + break; + case DIR_DOWN_RIGHT: + if(p.y < h-1 && p.x < w-1) { + p.y += speed; + p.x += speed; + } else { + p.dir = rand()*8; + } + break; + case DIR_DOWN: + if(p.y < h-1) { + p.y += speed; + } else { + p.dir = rand()%8; + } + break; + case DIR_LEFT: + if(p.x > 0) { + p.x -= speed; + } else { + p.dir = rand()%8; + } + break; + case DIR_RIGHT: + if(p.x < w-1) { + p.x += speed; + } else { + p.dir = rand()%8; + } + break; + default: + p.dir = rand()%8; + } + } + } +} + +ac::ParticleEmiter emiter; // initialize + +// Particle Filter +void ac::ParticleRelease(cv::Mat &frame) { + emiter.set(frame);// set values each frame + emiter.draw(frame); // draw values each frame +} + +void ac::ParticleBlend(cv::Mat &frame) { + emiter.set(frame); + emiter.draw_blend(frame); +} + +void ac::ParticleFlash(cv::Mat &frame) { + emiter.set(frame); + emiter.draw_flash(frame); +} + +void ac::ParticleAlpha(cv::Mat &frame) { + emiter.set(frame); + emiter.draw_alpha(frame); +} + +void ac::ParticleFast(cv::Mat &frame) { + static ParticleEmiter emiter; + if(frames_released == true || reset_alpha == true) { + emiter.reset(); + } + emiter.set(frame); + emiter.draw_move(frame); +} + +void ac::ParticleSnow(cv::Mat &frame) { + emiter.set(frame); + emiter.draw_op(frame); +} + + diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/ac-square.cpp b/windows/Acid.Cam.Qt.Windows.March.2019/ac-square.cpp new file mode 100755 index 0000000..5edf257 --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/ac-square.cpp @@ -0,0 +1,309 @@ +/* + * Software written by Jared Bruni https://github.com/lostjared + + This software is dedicated to all the people that experience mental illness. + + Website: http://lostsidedead.com + YouTube: http://youtube.com/LostSideDead + Instagram: http://instagram.com/jaredbruni + Twitter: http://twitter.com/jaredbruni + Facebook: http://facebook.com/LostSideDead0x + + You can use this program free of charge and redistrubute it online as long + as you do not charge anything for this program. This program is meant to be + 100% free. + + BSD 2-Clause License + + Copyright (c) 2019, Jared Bruni + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + */ + + +#include "ac.h" + +void ac::Square::setSize(const int &xx, const int &yy, const int &w, const int &h) { + x = xx; + y = yy; + if(width != w || height != h) { + width = w; + height = h; + image.create(cvSize(w, h), CV_8UC3); + } +} +void ac::Square::setPos(const int &p) { + pos = p; +} +void ac::Square::copyImage(const cv::Mat &f) { + for(int i = 0, src_x = x; i < width; ++i, ++src_x) { + for(int z = 0, src_y = y; z < height; ++z, ++src_y) { + cv::Vec3b &pixel = image.at(z, i); + cv::Vec3b src = f.at(src_y, src_x); + pixel = src; + } + } +} +void ac::Square::copyImageToTarget(int xx, int yy, cv::Mat &f) { + for(int i = 0, dst_x = xx; i < width; ++i, ++dst_x) { + for(int z = 0, dst_y = yy; z < height; ++z, ++dst_y) { + cv::Vec3b &pixel = f.at(dst_y, dst_x); + cv::Vec3b src = image.at(z, i); + pixel = src; + } + } +} + +void Square_Swap(ac::Square *squares, int num_w, int num_h, cv::Mat &frame, bool random = false) { + const int w = frame.cols;// frame width + const int h = frame.rows;// frame height + int square_w=(w/num_w), square_h=(h/num_h); + int pos = 0; + ac::Point *points = new ac::Point[num_w*num_h]; + std::vector square_vec; + for(int rx = 0; rx < num_w; ++rx) { + for(int ry = 0; ry < num_h; ++ry) { + int cx = rx*square_w; + int cy = ry*square_h; + points[pos].x = cx; + points[pos].y = cy; + squares[pos].setPos(pos); + squares[pos].setSize(cx, cy, square_w, square_h); + squares[pos].copyImage(frame); + square_vec.push_back(&squares[pos]); + ++pos; + } + } + + static auto rng = std::default_random_engine {}; + // shuffle instead of randomize + if(random == false) std::shuffle(square_vec.begin(), square_vec.end(),rng); + for(int i = 0; i < pos; ++i) { + if(random == false) + // use shuffled + square_vec[i]->copyImageToTarget(points[i].x, points[i].y,frame); + else + // use random + square_vec[rand()%pos]->copyImageToTarget(points[i].x, points[i].y,frame); + } + delete [] points; +} + + +// SquareSwap +void ac::SquareSwap(cv::Mat &frame) { + static int cnt = 0; + switch(cnt) { + case 0: + SquareSwap4x2(frame); + break; + case 1: + SquareSwap8x4(frame); + break; + case 2: + SquareSwap16x8(frame); + break; + case 3: + SquareSwap64x32(frame); + break; + } + ++cnt; + if(cnt > 3) cnt = 0; +} + +void ac::SquareSwap4x2(cv::Mat &frame) { + const int num_w = 4, num_h = 2; + static Square squares[num_w*num_h]; + Square_Swap(squares, num_w, num_h, frame); +} + +void ac::SquareSwap8x4(cv::Mat &frame) { + const int num_w = 8, num_h = 4; + static Square squares[num_w*num_h]; + Square_Swap(squares, num_w, num_h, frame); +} + +void ac::SquareSwap16x8(cv::Mat &frame) { + const int num_w = 16, num_h = 8; + static Square squares[num_w*num_h]; + Square_Swap(squares, num_w, num_h, frame); +} + +void ac::SquareSwap64x32(cv::Mat &) { + //const int num_w = 64, num_h = 32; + //static Square squares[num_w*num_h]; + //Square_Swap(squares, num_w, num_h, frame); +} + +void ac::SquareBars(cv::Mat &frame) { + static const int num_w = 16, num_h = 1; + static Square squares[num_w*num_h]; + Square_Swap(squares, num_w, num_h, frame); +} + +void ac::SquareBars8(cv::Mat &frame) { + static const int num_w = 8, num_h = 1; + static Square squares[num_w*num_h]; + Square_Swap(squares, num_w, num_h, frame); +} + +void ac::SquareSwapRand16x8(cv::Mat &frame) { + static const int num_w = 16, num_h = 8; + static Square squares[num_w*num_h]; + Square_Swap(squares, num_w, num_h, frame, true); +} + +void ac::SquareVertical8(cv::Mat &frame) { + static const int num_w = 1, num_h = 8; + static Square squares[num_w*num_h]; + Square_Swap(squares, num_w, num_h, frame); +} + +void ac::SquareVertical16(cv::Mat &frame) { + static const int num_w = 1, num_h = 16; + static Square squares[num_w*num_h]; + Square_Swap(squares, num_w, num_h, frame); +} + + +void ShiftSquares(std::vector &s, int pos, bool direction=true) { + if(direction == true) { + for(int i = 0; i < s.size(); ++i) { + int p = s[i]->getPos(); + if(p+1 > (int)s.size()-1) { + s[i]->setPos(0); + } else { + ++p; + s[i]->setPos(p); + } + } + } else { + for(int i = 0; i < pos; ++i) { + int p = s[i]->getPos(); + --p; + s[i]->setPos(p); + if(p < 0) { + s[i]->setPos(pos-1); + } + } + } +} + +void SquareVertical(const int num_w, const int num_h, ac::Square *squares, cv::Mat &frame, bool direction=true) { + int w = frame.cols;// frame width + int h = frame.rows;// frame height + + if(w <= 25 || h <= 25) + return; + + int square_w=(w/num_w), square_h=(h/num_h); + int pos = 0; + ac::Point *points = new ac::Point[num_w*num_h]; + std::vector square_vec; + for(int rx = 0; rx < (int)num_w; ++rx) { + for(int ry = 0; ry < (int)num_h; ++ry) { + int cx = rx*square_w; + int cy = ry*square_h; + points[pos].x = cx; + points[pos].y = cy; + squares[pos].setSize(cx, cy, square_w, square_h); + squares[pos].copyImage(frame); + square_vec.push_back(&squares[pos]); + ++pos; + } + } + ShiftSquares(square_vec,pos,direction); + for(int i = 0; i < pos; ++i) { + const int p = square_vec[i]->getPos(); + square_vec[i]->copyImageToTarget(points[p].x, points[p].y, frame); + } + delete [] points; +} + +void ac::SquareVertical_Roll(cv::Mat &frame) { + const int num_w = 1, num_h = 20; + static Square squares[num_w*num_h]; + static int lazy = 0; + if(lazy == 0) { + int cpos = 0; + for(int cx = 0; cx < num_w; ++cx) + for(int cy = 0; cy < num_h; ++cy) { + squares[cpos].setPos(cpos); + ++cpos; + } + lazy = 1; + } + SquareVertical(num_w, num_h, squares, frame); +} + +void ac::SquareSwapSort_Roll(cv::Mat &frame) { + const int num_w = 16, num_h = 8; + static Square squares[num_w*num_h]; + static int lazy = 0; + if(lazy == 0) { + int cpos = 0; + for(int cx = 0; cx < num_w; ++cx) + for(int cy = 0; cy < num_h; ++cy) { + squares[cpos].setPos(cpos); + ++cpos; + } + lazy = 1; + } + SquareVertical(num_w, num_h, squares, frame); +} + +void ac::SquareVertical_RollReverse(cv::Mat &frame) { + const int num_w = 1, num_h = 20; + static Square squares[num_w*num_h]; + static int lazy = 0; + if(lazy == 0) { + int cpos = 0; + for(int cx = 0; cx < num_w; ++cx) + for(int cy = 0; cy < num_h; ++cy) { + squares[cpos].setPos(cpos); + cpos++; + + } + lazy = 1; + } + SquareVertical(num_w, num_h, squares, frame, false); +} + +void ac::SquareSwapSort_RollReverse(cv::Mat &frame) { + const int num_w = 16, num_h = 8; + static Square squares[num_w*num_h]; + static int lazy = 0; + if(lazy == 0) { + int cpos = 0; + for(int cx = 0; cx < num_w; ++cx) + for(int cy = 0; cy < num_h; ++cy) { + ++cpos; + squares[cpos].setPos(cpos); + } + lazy = 1; + } + SquareVertical(num_w, num_h, squares, frame,false); +} + + diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/ac-util.cpp b/windows/Acid.Cam.Qt.Windows.March.2019/ac-util.cpp new file mode 100755 index 0000000..73c4675 --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/ac-util.cpp @@ -0,0 +1,716 @@ +/* + * Software written by Jared Bruni https://github.com/lostjared + + This software is dedicated to all the people that experience mental illness. + + Website: http://lostsidedead.com + YouTube: http://youtube.com/LostSideDead + Instagram: http://instagram.com/jaredbruni + Twitter: http://twitter.com/jaredbruni + Facebook: http://facebook.com/LostSideDead0x + + You can use this program free of charge and redistrubute it online as long + as you do not charge anything for this program. This program is meant to be + 100% free. + + BSD 2-Clause License + + Copyright (c) 2019, Jared Bruni + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + */ + + +#include "ac.h" + + +cv::Vec3b range_low(40, 40, 40), range_high(40, 40, 40); +cv::Vec3b gray_color(100, 100, 100); +std::vector blocked_colors; + +// Apply color map to cv::Mat +void ac::ApplyColorMap(cv::Mat &frame) { + if(set_color_map > 0 && set_color_map < 13) { + cv::Mat output_f1 = frame.clone(); + cv::applyColorMap(output_f1, frame, (int)set_color_map-1); + const int w = frame.cols; + const int h = frame.rows; + color_map_set = true; + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + ac::swapColors(frame, z, i); + if(isNegative) ac::invert(frame, z, i); + } + } + color_map_set = false; + } +} + +void ac::setColorMap(int map, cv::Mat &frame) { + cv::Mat output_f1 = frame.clone(); + cv::applyColorMap(output_f1, frame, (int)map); +} + +// set cv::Mat brightness +void ac::setBrightness(cv::Mat &frame, double alpha, int beta) { + cv::Mat c = frame.clone(); + c.convertTo(frame, -1, alpha, beta); +} + +// set cv::Mat gamma +void ac::setGamma(cv::Mat &frame, cv::Mat &outframe, const double gamma) { + cv::Mat lookUpTable(1, 256, CV_8U); + uchar* p = lookUpTable.ptr(); + for(int i = 0; i < 256; ++i) { + p[i] = cv::saturate_cast(pow(i / 255.0, gamma) * 255.0); + } + cv::Mat res = frame.clone(); + LUT(frame, lookUpTable, outframe); +} + +// set cv::Mat saturation +void ac::setSaturation(cv::Mat &frame, int saturation) { + cv::Mat image; + cv::cvtColor(frame, image, CV_BGR2HSV); + const int w = frame.cols; + const int h = frame.rows; + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = image.at(z, i); + pixel[1] = static_cast(saturation); + } + } + cv::cvtColor(image, frame, CV_HSV2BGR); +} + +void ac::Negate(cv::Mat &frame) { + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] = ~pixel[j]; + } + } +} + +void ac::Add(cv::Mat &src, cv::Mat &add, bool sat) { + if(src.size() != add.size()) + return; + if(src.empty() || add.empty()) + return; + + for(int z = 0; z < src.rows; ++z) { + for(int i = 0; i < src.cols; ++i) { + cv::Vec3b &pixel = src.at(z, i); + cv::Vec3b pix = add.at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] = (sat == true) ? cv::saturate_cast(pixel[j]+pix[j]) : static_cast(pixel[j]+pix[j]); + } + } +} + +void ac::Sub(cv::Mat &src, cv::Mat &sub, bool sat) { + if(src.size() != sub.size()) + return; + if(src.empty() || sub.empty()) + return; + + for(int z = 0; z < src.rows; ++z) { + for(int i = 0; i < src.cols; ++i) { + cv::Vec3b &pixel = src.at(z, i); + cv::Vec3b pix = sub.at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] = (sat == true) ? cv::saturate_cast(pixel[j]-pix[j]) : static_cast(pixel[j]-pix[j]); + } + } +} + + + +void ac::ScalarAverage(const cv::Mat &frame, cv::Scalar &s) { + s = cv::Scalar(); + if(frame.empty()) return; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b col = frame.at(z, i); + for(int j = 0; j < 3; ++j) + s[j] += col[j]; + } + } + unsigned long total_pixels = frame.rows * frame.cols; + for(int j = 0; j < 3; ++j) + s[j] /= total_pixels; +} + +void ac::TotalAverageOffset(cv::Mat &frame, unsigned long &value) { + if(frame.empty()) return; + value = 0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + value += (pixel[0]+pixel[1]+pixel[2]); + } + } + value /= (frame.rows * frame.cols); +} + +void ac::setColorKeyRange(cv::Vec3b low, cv::Vec3b high) { + range_low = low; + range_high = high; +} + +void ac::setBlockedColorKeys(std::vector &blocked) { + blocked_colors = blocked; +} + + +bool ac::colorBounds(const cv::Vec3b &color, const cv::Vec3b &pixel, const cv::Vec3b &range_passed_low, const cv::Vec3b &range_passed_high) { + bool result = true; + for(int i = 0; i < 3; ++i) { + if(!(color[i] <= cv::saturate_cast(pixel[i]+range_passed_low[i]) && color[i] >= cv::saturate_cast(pixel[i]-range_passed_high[i]))) { + result = false; + break; + } + } + return result; +} + + +bool ac::compareColor(const cv::Vec3b &color, const cv::Vec3b &low,const cv::Vec3b &high) { + if(color[0] >= low[0] && color[0] <= high[0] && color[1] >= low[1] && color[1] <= high[1] && color[2] >= low[2] && color[2] <= high[2]) + return true; + return false; +} + + +ac::SearchType ac::searchColors(const cv::Vec3b &color) { + for(int i = 0; i < blocked_colors.size(); ++i) { + if(compareColor(color, blocked_colors[i].low, blocked_colors[i].high) == true) { + if(blocked_colors[i].spill == true) { + return SEARCH_GRAY; + } + else { + return SEARCH_PIXEL; + } + } + } + return SEARCH_NOTFOUND; +} + +void ac::setGrayColor(const cv::Vec3b &color) { + gray_color = color; +} + +void ac::filterColorKeyed(const cv::Vec3b &color, const cv::Mat &orig, const cv::Mat &filtered, cv::Mat &output) { + if(orig.size()!=filtered.size()) { + std::cerr << "filterColorKeyed: Error not same size...\n"; + return; + } + output = orig.clone(); + for(int z = 0; z < orig.rows; ++z) { + for(int i = 0; i < orig.cols; ++i) { + if(colorkey_filter == true) { + cv::Vec3b &dst = output.at(z, i); + cv::Vec3b pixel = orig.at(z, i); + cv::Vec3b fcolor = filtered.at(z, i); + SearchType srch = searchColors(pixel); + if(colorBounds(color,pixel,range_low, range_high) || srch == SEARCH_PIXEL) { + dst = fcolor; + } + else if(srch == SEARCH_GRAY) { + dst = gray_color; + } + else { + dst = pixel; + } + } else if(colorkey_set == true && !color_image.empty()) { + int cX = AC_GetFX(color_image.cols, i, orig.cols); + int cY = AC_GetFZ(color_image.rows, z, orig.rows); + cv::Vec3b add_i = color_image.at(cY, cX); + if(add_i == color) { + cv::Vec3b pixel = filtered.at(z, i); + cv::Vec3b &dst = output.at(z, i); + dst = pixel; + } + } else if(colorkey_bg == true && !color_bg_image.empty()) { + int cX = AC_GetFX(color_bg_image.cols, i, orig.cols); + int cY = AC_GetFZ(color_bg_image.rows, z, orig.rows); + cv::Vec3b add_i = color_bg_image.at(cY, cX); + cv::Vec3b &dst = output.at(z, i); + cv::Vec3b pixel = filtered.at(z, i); + if(add_i == color) + dst = pixel; + else + dst = add_i; + } else if(colorkey_replace == true && !color_replace_image.empty()) { + int cX = AC_GetFX(color_replace_image.cols, i, orig.cols); + int cY = AC_GetFZ(color_replace_image.rows, z, orig.rows); + cv::Vec3b add_i = color_replace_image.at(cY, cX); + cv::Vec3b &dst = output.at(z, i); + cv::Vec3b pixel = orig.at(z, i); + cv::Vec3b fcolor = filtered.at(z, i); + SearchType srch = searchColors(pixel); + if(colorBounds(color, pixel, range_low, range_high) || srch == SEARCH_PIXEL) { + dst = add_i; + } + else if(srch == SEARCH_GRAY) { + dst = gray_color; + } else { + dst = fcolor; + } + } + } + } +} +// Alpha Blend function +void ac::AlphaBlend(const cv::Mat &one, const cv::Mat &two, cv::Mat &output,double alpha) { + if(one.size() != two.size()) { + return; + } + + if(output.empty() || output.size() != one.size()) + output.create(one.size(), CV_8UC3); + + for(int z = 0; z < one.rows; ++z) { + for(int i = 0; i < one.cols; ++i) { + cv::Vec3b pix[2]; + cv::Vec3b &pixel = output.at(z, i); + pix[0] = one.at(z, i); + pix[1] = two.at(z, i); + pixel[0] = static_cast((pix[0][0] * alpha) + (pix[1][0] * alpha)); + pixel[1] = static_cast((pix[0][1] * alpha) + (pix[1][1] * alpha)); + pixel[2] = static_cast((pix[0][2] * alpha) + (pix[1][2] * alpha)); + } + } +} + +void ac::AlphaBlendDouble(const cv::Mat &one, const cv::Mat &two, cv::Mat &output, double alpha1, double alpha2) { + if(one.size() != two.size()) { + return; + } + if(output.empty() || output.size() != one.size()) + output.create(one.size(), CV_8UC3); + + for(int z = 0; z < one.rows; ++z) { + for(int i = 0; i < one.cols; ++i) { + cv::Vec3b pix[2]; + cv::Vec3b &pixel = output.at(z, i); + pix[0] = one.at(z, i); + pix[1] = two.at(z, i); + pixel[0] = static_cast((pix[0][0] * alpha1) + (pix[1][0] * alpha2)); + pixel[1] = static_cast((pix[0][1] * alpha1) + (pix[1][1] * alpha2)); + pixel[2] = static_cast((pix[0][2] * alpha1) + (pix[1][2] * alpha2)); + } + } +} + +void ac::RealAlphaBlend(const cv::Mat &one, const cv::Mat &two, cv::Mat &output, double alpha) { + if(one.size() != two.size()) { + return; + } + AlphaBlendDouble(one, two, output, alpha, 1-alpha); +} + +void ac::AlphaXorBlend(const cv::Mat &one, const cv::Mat &two, cv::Mat &output, double alpha) { + if(one.size() != two.size()) { + return; + } + + if(alpha <= 1) + alpha = 1; + + if(output.empty() || output.size() != one.size()) + output.create(one.size(), CV_8UC3); + + for(int z = 0; z < one.rows; ++z) { + for(int i = 0; i < one.cols; ++i) { + cv::Vec3b pix[2]; + cv::Vec3b &pixel = output.at(z, i); + pix[0] = one.at(z, i); + pix[1] = two.at(z, i); + pixel[0] = static_cast((pix[0][0] * static_cast(alpha)) ^ (pix[1][0] * static_cast(alpha))); + pixel[1] = static_cast((pix[0][1] * static_cast(alpha)) ^ (pix[1][1] * static_cast(alpha))); + pixel[2] = static_cast((pix[0][2] * static_cast(alpha)) ^ (pix[1][2] * static_cast(alpha))); + } + } + +} + +void ac::Xor(cv::Mat &dst, const cv::Mat &add) { + if(dst.size() != add.size()) return; + for(int z = 0; z < dst.rows; ++z) { + for(int i = 0; i < dst.cols; ++i) { + cv::Vec3b &pixel = dst.at(z, i); + cv::Vec3b other = add.at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] = pixel[j]^other[j]; + } + } +} + +void ac::Xor(const cv::Mat &input, const cv::Mat &add, cv::Mat &output) { + if(input.size() != add.size()) + return; + + if(output.empty() || output.size() != input.size()) + output.create(input.size(), CV_8UC3); + + for(int z = 0; z < output.rows; ++z) { + for(int i = 0; i < output.cols; ++i) { + cv::Vec3b &pixel = output.at(z, i); + cv::Vec3b src = input.at(z, i); + cv::Vec3b other = add.at(z, i); + for(int j = 0; j < 3; ++j) + pixel[j] = src[j]^other[j]; + } + } +} + + +bool ac::reset_alpha = false; + +void ac::resetAlpha(int &dir, double &alpha) { + if(reset_alpha == true) { + alpha = 1.0; + dir = 1; + } +} + +void ac::resetAlpha(double &alpha) { + if(reset_alpha == true) { + alpha = 1.0; + } +} + +void ac::AddInvert(cv::Mat &frame) { + if(in_custom == true) return; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel */ + } + } +} + +// Make two copies of the current frame, apply filter1 to one, filter2 to the other +// then Alpha Blend them together +void ac::filterFade(cv::Mat &frame, int filter1, int filter2, double alpha) { + const int h = frame.rows; // frame height + const int w = frame.cols;// framew idth + // make copies of original frame + cv::Mat frame1 = frame.clone(), frame2 = frame.clone(); + // apply filters on two copies of original frame + CallFilter(filter1, frame1); + CallFilter(filter2, frame2); + // loop through image setting each pixel with alphablended pixel + for(int z = 0; z < h; ++z) { + for(int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); // target pixel + cv::Vec3b frame1_pix = frame1.at(z, i); // frame1 pixel + cv::Vec3b frame2_pix = frame2.at(z, i); // frame2 pixel + // loop through pixel components and set target pixel to alpha blended pixel of two frames + for(int q = 0; q < 3; ++q) + pixel[q] = static_cast(frame2_pix[q]+(frame1_pix[q]*alpha)); + } + } +} + +void ac::copyMat(const cv::Mat &src, const Rect &srcrc, cv::Mat &target, const Rect &rc) { + for(int i = 0; i < rc.w; ++i) { + for(int z = 0; z < rc.h; ++z) { + cv::Vec3b &dst = target.at(rc.y+z, rc.x+i); + cv::Vec3b srcp = src.at(srcrc.y+z, srcrc.x+i); + dst = srcp; + } + } +} + + + +// Copy cv::Mat +void ac::copyMat(const cv::Mat &src,int src_x, int src_y ,cv::Mat &target, const ac::Rect &rc) { + for(int i = 0; i < rc.w; ++i) { + for(int z = 0; z < rc.h; ++z) { + if(src_y+z < src.rows && src_x+i < src.cols && rc.y+z < target.rows && rc.x+i < target.cols) { + ASSERT(src_y+z < src.rows && src_x+i < src.cols && rc.y+z < target.rows && rc.x+i < target.cols); + cv::Vec3b &pixel = target.at(rc.y+z, rc.x+i); + cv::Vec3b src_pixel = src.at(src_y+z, src_x+i); + pixel = src_pixel; + } + } + } +} + +void ac::copyMat(const cv::Mat &src, const Point &p, cv::Mat &target, const ac::Rect &rc) { + copyMat(src, p.x, p.y, target, rc); +} + +void ac::copyMat(const cv::Mat &src, int x, int y, cv::Mat &target, int rx, int ry, int rw, int rh) { + copyMat(src, x,y,target,Rect(rx,ry,rw,rh)); +} + +void ac::fillRect(cv::Mat &m, const Rect &r, cv::Vec3b pixel) { + for(int i = r.x; i < r.x+r.w; ++i) { + for(int z = r.y; z < r.y+r.h; ++z) { + ASSERT(i < m.cols && z < m.rows); + cv::Vec3b &pix = m.at(z, i); + pix = pixel; + } + } +} +// set custom callback +void ac::setCustom(DrawFunction f) { + custom_callback = f; +} + +// call custom fitler defined elsewhere +void ac::custom(cv::Mat &frame) { + if(custom_callback != 0) + custom_callback(frame); +} + +void ac::setPlugin(DrawFunction f) { + plugin_func = f; +} + +void ac::plugin(cv::Mat &frame) { + if(plugin_func != 0) { + plugin_func(frame); + } +} + +ac::DrawFunction ac::getFilter(std::string name) { + if(filter_map_str.find(name) != filter_map_str.end()) + return filter_map_str[name].second; + return filter_map_str["MedianBlend"].second; +} + +bool ac::testSize(cv::Mat &frame) { + if(frame.cols < frame.cols/64 || frame.rows < frame.rows/64) + return false; + + return true; +} + +ac::DrawFunction ac::getRandomFilter(int &index) { + static std::string values[] = {"ShuffleAlpha", "ShuffleSelf", "ShuffleMedian", "ShuffleRGB"}; + int r = rand()%4; + index = filter_map[values[r]]; + return filter_map_str[values[r]].second; +} + +int ac::subfilter = -1; + +void ac::setSubFilter(int value) { + subfilter = value; +} + +void ac::clearSubFilter() { + subfilter = -1; +} + +void ac::DarkenImage(cv::Mat &frame, unsigned int size) { + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] /= size; + } + } + } +} + +void ac::SwapColors(cv::Vec3b &cur) { + cv::Vec3b temp = cur; + int color_order = rand()%5; + switch(color_order) { + case 1: cur[0] = temp[2]; + cur[1] = temp[1]; + cur[2] = temp[0]; + break; + case 2: + cur[0] = temp[1]; + cur[1] = temp[0]; + break; + case 3: + cur[1] = temp[2]; + cur[2] = temp[1]; + break; + case 4: + cur[0] = temp[1]; + cur[1] = temp[2]; + cur[2] = temp[0]; + break; + } +} + +void ac::FillRow(cv::Mat &frame, unsigned int row, unsigned char value) { + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + pixel[row] = value; + } + } +} + +void ac::Shuffle(int &index, cv::Mat &frame, std::vector &filter_array) { + static auto rng = std::default_random_engine{}; + CallFilter(filter_array[index], frame); + ++index; + if(index > filter_array.size()-1) { + index = 0; + std::shuffle(filter_array.begin(), filter_array.end(),rng); + } +} + +void ac::AddMatVector(cv::Mat &frame, std::vector &v) { + for(int i = 0; i < v.size(); ++i) + Add(frame, v[i]); +} + +unsigned char ac::size_cast(long val) { + if(val >= 255) return 255; + if(val < 0) return 0; + return val; +} + +unsigned char ac::size_reset(long val) { + if(val >= 255 || val <= 0) return rand()%255; + return val; +} + +void ac::blendFilterWithColorMap(int filter, int map, cv::Mat &frame) { + cv::Mat copyf = frame.clone(), copyi = frame.clone(); + setColorMap(map, copyf); + CallFilter(filter, copyf); + AlphaBlend(copyf, copyi, frame, 0.5); +} + +void ac::SwitchOrder(cv::Vec3b &cur, int color_order) { + cv::Vec3b temp = cur; + switch(color_order) { + case 1: // RGB + cur[0] = temp[2]; + cur[1] = temp[1]; + cur[2] = temp[0]; + break; + case 2:// GBR + cur[0] = temp[1]; + cur[1] = temp[0]; + break; + case 3:// BRG + cur[1] = temp[2]; + cur[2] = temp[1]; + break; + case 4: // GRB + cur[0] = temp[1]; + cur[1] = temp[2]; + cur[2] = temp[0]; + break; + } +} + +std::vector subfilters; + +void ac::pushSubFilter(int newsub) { + subfilters.push_back(subfilter); + subfilter = newsub; +} + +void ac::popSubFilter() { + auto subsize = subfilters.size(); + if(subsize > 0) { + subfilter = subfilters[subsize-1]; + subfilters.pop_back(); + } +} + +void ac::AlphaMovement(double *alpha, int *dir, double inc) { + if(alpha_increase != 0) inc = alpha_increase; + for(int i = 0; i < 2; ++i) { + if(dir[i] == 0) { + alpha[i] -= inc; + if(alpha[i] <= 0.1) + dir[i] = 1; + } else { + alpha[i] += inc; + if(alpha[i] >= 1.0) + dir[i] = 0; + } + resetAlpha(dir[i], alpha[i]); + } +} + +void ac::AlphaMovementMaxMin(double &alpha, int &dir, double speed, double max, double min) { + if(alpha_increase != 0) speed = alpha_increase; + if(dir == 1) { + alpha += speed; + if(alpha > max) { + alpha = max; + dir = 0; + } + } else { + alpha -= speed; + if(alpha < min) { + alpha = min; + dir = 1; + } + } + resetAlpha(dir, alpha); +} + +void ac::AlphaXorBlendDouble(const cv::Mat &one, const cv::Mat &two, cv::Mat &output, double alpha1, double alpha2) { + if(one.size() != two.size()) { + return; + } + if(alpha1 <= 1) + alpha1 = 1; + if(alpha2 <= 1) + alpha2 = 1; + if(output.empty() || output.size() != one.size()) + output.create(one.size(), CV_8UC3); + + for(int z = 0; z < one.rows; ++z) { + for(int i = 0; i < one.cols; ++i) { + cv::Vec3b pix[2]; + cv::Vec3b &pixel = output.at(z, i); + pix[0] = one.at(z, i); + pix[1] = two.at(z, i); + pixel[0] = static_cast((pix[0][0] * static_cast(alpha1)) ^ (pix[1][0] * static_cast(alpha2))); + pixel[1] = static_cast((pix[0][1] * static_cast(alpha1)) ^ (pix[1][1] * static_cast(alpha2))); + pixel[2] = static_cast((pix[0][2] * static_cast(alpha1)) ^ (pix[1][2] * static_cast(alpha2))); + } + } +} + +void ac::PixelScaleAlpha(cv::Mat &frame, double amt) { + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + pixel[j] = pixel[j]*amt; + } + } + } +} diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/ac.h b/windows/Acid.Cam.Qt.Windows.March.2019/ac.h new file mode 100755 index 0000000..408f17a --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/ac.h @@ -0,0 +1,1543 @@ +/* + * Acid Cam Functions for OpenCV + * written by Jared Bruni https://github.com/lostjared + + This software is dedicated to all the people that experience mental illness. + + Website: http://lostsidedead.com + YouTube: http://youtube.com/LostSideDead + Instagram: http://instagram.com/jaredbruni + Twitter: http://twitter.com/jaredbruni + Facebook: http://facebook.com/LostSideDead0x + + You can use this program free of charge and redistrubute it online as long + as you do not charge anything for this program. This program is meant to be + 100% free. + + BSD 2-Clause License + + Copyright (c) 2019, Jared Bruni + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __AC_H__ +#define __AC_H__ +#ifdef __APPLE__ +#include +#include +#include +#else +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include"ac-filtercat.h" +//#define ASSERT_CHECK +// Macro for assert testing +#ifdef ASSERT_CHECK +#define ASSERT(X) assert(X) +#else +#define ASSERT(X) +#endif +/* + * + * Be sure to call fill_filter_map + * to use set appropriate variables, call the function + * + * ac::SelfAlphaBlend(mat); + * + * or use CallFilter + * + * CallFilter(function_index, mat); + * + * then just use function_index to point to whatever filter + * + * for text of the filter use the following array of strings + * + * ac::draw_strings[function_index]; + * + */ +// exernal variables +extern int current_filterx, bytesPerSample, bytesPerRow, width, height, red, green, blue, offset, randomNumber, reverse; +extern bool negate, blend_set, colorkey_set,colorkey_bg, colorkey_replace, colorkey_filter; +extern cv::Mat blend_image,color_image,color_bg_image, color_replace_image, color_filter; + +int AC_GetFX(int oldw,int x, int nw); +int AC_GetFZ(int oldh, int y, int nh); + +// acid cam namespace +namespace ac { + // get version string + extern std::string getVersion(); + // version string + extern const std::string version; + extern double translation_variable, pass2_alpha; + extern double alpha, tr; + extern bool isNegative, noRecord,iRev; + extern int color_order; + extern double fps; + extern int draw_offset; + extern int subfilter; + extern std::string fileName; + extern cv::Mat orig_frame; + extern cv::Mat blendW_frame; + extern cv::Mat image_files[4]; + extern bool images_Enabled,fps_force; + extern int snapshot_Type; + extern bool in_custom; + extern int swapColor_r, swapColor_g, swapColor_b; + extern cv::Size resolution; + extern bool strobe_It; + extern int set_color_map; + extern bool color_map_set; + extern int GetFX(cv::Mat &frame, int x, int nw); + extern int GetFY(cv::Mat &frame, int y, int nh); + extern bool reset_alpha; + void invert(cv::Mat &frame, int x, int y); + /* filter typedef */ + typedef void (*DrawFunction)(cv::Mat &frame); + typedef std::pair FilterType; + extern DrawFunction custom_callback; + extern DrawFunction plugin_func; + // ror/rol tempaltes + template + inline T ror(T x, int m){ + return (x >> m) | (x << (sizeof(T)*8 - m)); + } + template + inline T rol(T x, int m) { + return (x << m) | (x >> (sizeof(T)*8 -m)); + } + enum class KeyValueType { KEY_RANGE, KEY_TOLERANCE }; + class Keys { + public: + cv::Vec3b low, high; + KeyValueType key_type; + bool spill; + Keys() : key_type(KeyValueType::KEY_RANGE), spill(false) {} + }; + + enum SearchType { SEARCH_NOTFOUND=0, SEARCH_PIXEL, SEARCH_GRAY }; + // be sure to call this when the application starts + void fill_filter_map(); + // draw functions + DrawFunction getRandomFilter(int &index); + void DrawFilter(const std::string &name, const cv::Mat &frame, cv::Mat &outframe); + void DrawFilter(int index, const cv::Mat &frame, cv::Mat &outframe); + void DrawFilter(int index, cv::Mat &frame); + void DrawFilter(const std::string &name, cv::Mat &frame); + void DrawFilterUnordered(const std::string &name, cv::Mat &frame); + DrawFunction getFilter(std::string name); + FilterType filterByIndex(const int &num); + FilterType filterByString(const std::string &num); + bool CallFilter(int index, cv::Mat &frame); + bool CallFilter(const std::string &name, cv::Mat &frame); + // Acid Cam Filter Function prototypes + void SelfAlphaBlend(cv::Mat &frame); + void SelfScale(cv::Mat &frame); + void StrobeEffect(cv::Mat &frame); + void Blend3(cv::Mat &frame); + void NegParadox(cv::Mat &frame); + void ThoughtMode(cv::Mat &frame); + void Pass2Blend(cv::Mat &frame); + void RandTriBlend(cv::Mat &frame); + void Blank(cv::Mat &frame); + void Tri(cv::Mat &frame); + void Distort(cv::Mat &frame); + void CDraw(cv::Mat &frame); + void Type(cv::Mat &frame); + void NewOne(cv::Mat &frame); + void blendWithImage(cv::Mat &frame); + void triBlendWithImage(cv::Mat &frame); + void imageStrobe(cv::Mat &frame); + void imageDistraction(cv::Mat &frame); + void blendFractal(cv::Mat &frame); + void blendFractalMood(cv::Mat &frame); + void cossinMultiply(cv::Mat &frame); + void colorAccumulate1(cv::Mat &frame); + void colorAccumulate2(cv::Mat &frame); + void colorAccumulate3(cv::Mat &frame); + void filter8(cv::Mat &frame); + void filter3(cv::Mat &frame); + void rainbowBlend(cv::Mat &frame); + void randBlend(cv::Mat &frame); + void newBlend(cv::Mat &frame); + void alphaFlame(cv::Mat &frame); + void custom(cv::Mat &frame); + void pixelScale(cv::Mat &frame); + void glitchSort(cv::Mat &frame); + void pixelSort(cv::Mat &frame); + void randomFilter(cv::Mat &frame); + void randomFlash(cv::Mat &frame); + void imageBlend(cv::Mat &frame); + void imageBlendTwo(cv::Mat &frame); + void imageBlendThree(cv::Mat &frame); + void imageBlendFour(cv::Mat &frame); + void GaussianBlur(cv::Mat &frame); + void MedianBlur(cv::Mat &frame); + void BlurDistortion(cv::Mat &frame); + void DiamondPattern(cv::Mat &frame); + void MirrorBlend(cv::Mat &frame); + void Pulse(cv::Mat &frame); + void SidewaysMirror(cv:: Mat &frame); + void MirrorNoBlend(cv::Mat &frame); + void SortFuzz(cv::Mat &frame); + void Fuzz(cv::Mat &frame); + void DoubleVision(cv::Mat &frame); + void RGBShift(cv::Mat &frame); + void RGBSep(cv::Mat &frame); + void GradientRainbow(cv::Mat &frame); + void GradientRainbowFlash(cv::Mat &frame); + void Reverse(cv::Mat &frame); + void Scanlines(cv::Mat &frame); + void TVStatic(cv::Mat &frame); + void MirrorAverage(cv::Mat &frame); + void MirrorAverageMix(cv::Mat &frame); + void Mean(cv::Mat &frame); + void Laplacian(cv::Mat &frame); + void Bitwise_XOR(cv::Mat &frame); + void Bitwise_AND(cv::Mat &frame); + void Bitwise_OR(cv::Mat &frame); + void Equalize(cv::Mat &frame); + void ChannelSort(cv::Mat &frame); + void Reverse_XOR(cv::Mat &frame); + void CombinePixels(cv::Mat &frame); + void FlipTrip(cv::Mat &frame); + void Canny(cv::Mat &frame); + void Boxes(cv::Mat &frame); + void BoxesFade(cv::Mat &frame); + void FlashBlack(cv::Mat &frame); + void SlideRGB(cv::Mat &frame); + void Side2Side(cv::Mat &frame); + void Top2Bottom(cv::Mat &frame); + void StrobeRedGreenBlue(cv::Mat &frame); + void Outward(cv::Mat &frame); + void OutwardSquare(cv::Mat &frame); + void Blend_Angle(cv::Mat &frame); + void ShiftPixels(cv::Mat &frame); + void ShiftPixelsDown(cv::Mat &frame); + void XorMultiBlend(cv::Mat &frame); + void BitwiseRotate(cv::Mat &frame); + void BitwiseRotateDiff(cv::Mat &frame); + void HPPD(cv::Mat &frame); + void FuzzyLines(cv::Mat &frame); + void GradientLines(cv::Mat &frame); + void GradientSelf(cv::Mat &frame); + void GradientDown(cv::Mat &frame); + void GraidentHorizontal(cv::Mat &frame); + void GradientSelfVertical(cv::Mat &frame); + void GradientRGB(cv::Mat &frame); + void Inter(cv::Mat &frame); + void UpDown(cv::Mat &frame); + void LeftRight(cv::Mat &frame); + void StrobeScan(cv::Mat &frame); + void BlendedScanLines(cv::Mat &frame); + void GradientStripes(cv::Mat &frame); + void XorSine(cv::Mat &frame); + void SquareSwap(cv::Mat &frame); + void SquareSwap4x2(cv::Mat &frame); + void SquareSwap8x4(cv::Mat &frame); + void SquareSwap16x8(cv::Mat &frame); + void SquareSwap64x32(cv::Mat &frame); + void SquareBars(cv::Mat &frame); + void SquareBars8(cv::Mat &frame); + void SquareVertical8(cv::Mat &frame); + void SquareVertical16(cv::Mat &frame); + void SquareVertical_Roll(cv::Mat &frame); + void SquareSwapRand16x8(cv::Mat &frame); + void SquareSwapSort_Roll(cv::Mat &frame); + void SquareVertical_RollReverse(cv::Mat &frame); + void SquareSwapSort_RollReverse(cv::Mat &frame); + void Circular(cv::Mat &frame); + void WhitePixel(cv::Mat &frame); + void FrameBlend(cv::Mat &frame); + void FrameBlendRGB(cv::Mat &frame); + void TrailsFilter(cv::Mat &frame); + void TrailsFilterIntense(cv::Mat &frame); + void TrailsFilterSelfAlpha(cv::Mat &frame); + void TrailsFilterXor(cv::Mat &frame); + void ColorTrails(cv::Mat &frame); + void MoveRed(cv::Mat &frame); + void MoveRGB(cv::Mat &frame); + void MoveRedGreenBlue(cv::Mat &frame); + void BlurSim(cv::Mat &frame); + void Block(cv::Mat &frame); + void BlockXor(cv::Mat &frame); + void BlockScale(cv::Mat &frame); + void BlockStrobe(cv::Mat &frame); + void PrevFrameBlend(cv::Mat &frame); + void Wave(cv::Mat &frame); + void HighWave(cv::Mat &frame); + void VerticalSort(cv::Mat &frame); + void VerticalChannelSort(cv::Mat &frame); + void HorizontalBlend(cv::Mat &frame); + void VerticalBlend(cv::Mat &frame); + void OppositeBlend(cv::Mat &frame); + void DiagonalLines(cv::Mat &frame); + void HorizontalLines(cv::Mat &frame); + void InvertedScanlines(cv::Mat &frame); + void Soft_Mirror(cv::Mat &frame); + void KanapaTrip(cv::Mat &frame); + void ColorMorphing(cv::Mat &frame); + void ScanSwitch(cv::Mat &frame); + void ScanAlphaSwitch(cv::Mat &frame); + void NegativeStrobe(cv::Mat &frame); + void XorAddMul(cv::Mat &frame); + void ParticleRelease(cv::Mat &frame); + void BlendSwitch(cv::Mat &frame); + void AllRed(cv::Mat &frame); + void AllGreen(cv::Mat &frame); + void AllBlue(cv::Mat &frame); + void LineRGB(cv::Mat &frame); + void PixelRGB(cv::Mat &frame); + void BoxedRGB(cv::Mat &frame); + void KruegerSweater(cv::Mat &frame); + void RGBFlash(cv::Mat &frame); + void IncreaseBlendHorizontal(cv::Mat &frame); + void BlendIncrease(cv::Mat &frame); + void GradientReverse(cv::Mat &frame); + void GradientReverseVertical(cv::Mat &frame); + void GradientReverseBox(cv::Mat &frame); + void GradientNewFilter(cv::Mat &frame); + void ReinterpretDouble(cv::Mat &frame); + void ReinterpSelfScale(cv::Mat &frame); + void AverageLines(cv::Mat &frame); + void ImageFile(cv::Mat &frame); + void ImageXor(cv::Mat &frame); + void ImageAlphaBlend(cv::Mat &frame); + void ColorRange(cv::Mat &frame); + void ImageInter(cv::Mat &frame); + void TrailsInter(cv::Mat &frame); + void TrailsBlend(cv::Mat &frame); + void TrailsNegate(cv::Mat &frame); + void InterReverse(cv::Mat &frame); + void InterMirror(cv::Mat &frame); + void InterFullMirror(cv::Mat &frame); + void MirrorRGB(cv::Mat &frame); + void RGBStatic1(cv::Mat &frame); + void RGBStatic2(cv::Mat &frame); + void VectorIncrease(cv::Mat &frame); + void LineByLineReverse(cv::Mat &frame); + void RandomIntertwine(cv::Mat &frame); + void RandomFour(cv::Mat &frame); + void BlendThree(cv::Mat &frame); + void AcidTrails(cv::Mat &frame); + void RandomTwo(cv::Mat &frame); + void HorizontalTrailsInter(cv::Mat &frame); + void Trails(cv::Mat &frame); + void BlendTrails(cv::Mat &frame); + void RandomFilteredSquare(cv::Mat &frame); + void ImageX(cv::Mat &frame); + void RandomQuads(cv::Mat &frame); + void QuadCosSinMultiply(cv::Mat &frame); + void QuadRandomFilter(cv::Mat &frame); + void RollRandom(cv::Mat &frame); + void AverageRandom(cv::Mat &frame); + void HorizontalStripes(cv::Mat &frame); + void DiamondStrobe(cv::Mat &frame); + void SmoothTrails(cv::Mat &frame); + void GridFilter8x(cv::Mat &frame); + void GridFilter16x(cv::Mat &frame); + void GridFilter8xBlend(cv::Mat &frame); + void GridRandom(cv::Mat &frame); + void GridRandomPixel(cv::Mat &frame); + void Dual_SelfAlphaRainbow(cv::Mat &frame); + void Dual_SelfAlphaBlur(cv::Mat &frame); + void SurroundPixelXor(cv::Mat &frame); + void Darken(cv::Mat &frame); + void WeakBlend(cv::Mat &frame); + void AverageVertical(cv::Mat &frame); + void RandomCollectionAverage(cv::Mat &frame); + void RandomCollectionAverageMax(cv::Mat &frame); + void SmoothTrailsSelfAlphaBlend(cv::Mat &frame); + void SmoothTrailsRainbowBlend(cv::Mat &frame); + void MedianBlend(cv::Mat &frame); + void SmoothRandomImageBlend(cv::Mat &frame); + void SmoothImageAlphaBlend(cv::Mat &frame); + void RandomAlphaBlend(cv::Mat &frame); + void RandomTwoFilterAlphaBlend(cv::Mat &frame); + void PixelatedSquare(cv::Mat &frame); + void AlphaBlendPosition(cv::Mat &frame); + void BlendRowAlpha(cv::Mat &frame); + void BlendRow(cv::Mat &frame); + void BlendRowByVar(cv::Mat &frame); + void BlendRowByDirection(cv::Mat &frame); + void BlendAlphaXor(cv::Mat &frame); + void SelfXorScale(cv::Mat &frame); + void BitwiseXorScale(cv::Mat &frame); + void XorTrails(cv::Mat &frame); + void RainbowTrails(cv::Mat &frame); + void NegativeTrails(cv::Mat &frame); + void IntenseTrails(cv::Mat &frame); + void SelfAlphaRGB(cv::Mat &frame); + void BlendImageOnOff(cv::Mat &frame); + void XorSelfAlphaImage(cv::Mat &frame); + void BitwiseXorStrobe(cv::Mat &frame); + void AlphaBlendRandom(cv::Mat &frame); + void ChannelSortAlphaBlend(cv::Mat &frame); + void XorChannelSort(cv::Mat &frame); + void GradientColors(cv::Mat &frame); + void GradientColorsVertical(cv::Mat &frame); + void Bitwise_XOR_Average(cv::Mat &frame); + void NotEqual(cv::Mat &frame); + void ImageShiftUpLeft(cv::Mat &frame); + void GradientXorSelfScale(cv::Mat &frame); + void SmoothSourcePixel(cv::Mat &frame); + void StrobeBlend(cv::Mat &frame); + void FrameBars(cv::Mat &frame); + void Sort_Vertical_Horizontal(cv::Mat &frame); + void Sort_Vertical_Horizontal_Bitwise_XOR(cv::Mat &frame); + void Scalar_Average_Multiply(cv::Mat &frame); + void Scalar_Average(cv::Mat &frame); + void Total_Average(cv::Mat &frame); + void AlphaBlendImageXor(cv::Mat &frame); + void FlashWhite(cv::Mat &frame); + void FlashBlackAndWhite(cv::Mat &frame); + void GaussianBlend(cv::Mat &frame); + void RandomXor(cv::Mat &frame); + void RandomXorFlash(cv::Mat &frame); + void RandomAmountMedianBlur(cv::Mat &frame); + void SoftXor(cv::Mat &frame); + void SelfXorBlend(cv::Mat &frame); + void SelfXorDoubleFlash(cv::Mat &frame); + void SelfOrDoubleFlash(cv::Mat &frame); + void BlendRowCurvedSqrt(cv::Mat &frame); + void CycleShiftRGB(cv::Mat &frame); + void CycleShiftRandomRGB(cv::Mat &frame); + void CycleShiftRandomRGB_XorBlend(cv::Mat &frame); + void CycleShiftRandomAlphaBlend(cv::Mat &frame); + void VerticalColorBars(cv::Mat &frame); + void GradientLeftRight(cv::Mat &frame); + void GraidentUpDown(cv::Mat &frame); + void GradientLeftRightInOut(cv::Mat &frame); + void GradientUpDownInOut(cv::Mat &frame); + void Lines(cv::Mat &frame); + void ColorLines(cv::Mat &frame); + void WhiteLines(cv::Mat &frame); + void ThickWhiteLines(cv::Mat &frame); + void UseLineObject(cv::Mat &frame); + void TanAlphaGrid(cv::Mat &frame); + void MedianBlendAnimation(cv::Mat &frame); + void FibFlash(cv::Mat &frame); + void ScaleFlash(cv::Mat &frame); + void LeftLines(cv::Mat &frame); + void Curtain(cv::Mat &frame); + void RandomCurtain(cv::Mat &frame); + void CurtainVertical(cv::Mat &frame); + void RandomCurtainVertical(cv::Mat &frame); + void inOrder(cv::Mat &frame); + void inOrderBySecond(cv::Mat &frame); + void DarkenFilter(cv::Mat &frame); + void RandomFilterBySecond(cv::Mat &frame); + void ThreeRandom(cv::Mat &frame); + void inOrderAlpha(cv::Mat &frame); + void inOrderAlphaXor(cv::Mat &frame); + void SlideFilterXor(cv::Mat &frame); + void SlideFilter(cv::Mat &frame); + void RandomSlideFilter(cv::Mat &frame); + void SlideUpDown(cv::Mat &frame); + void SlideUpDownXor(cv::Mat &frame); + void SlideUpDownRandom(cv::Mat &frame); + void SlideSubFilter(cv::Mat &frame); + void SlideSubUpDownFilter(cv::Mat &frame); + void ParticleBlend(cv::Mat &frame); + void ParticleFlash(cv::Mat &frame); + void ExactImage(cv::Mat &frame); + void ParticleAlpha(cv::Mat &frame); + void BlendInAndOut(cv::Mat &frame); + void BlendScaleInAndOut(cv::Mat &frame); + void AcidGlitch(cv::Mat &frame); + void XorBackwards(cv::Mat &frame); + void LiquidFilter(cv::Mat &frame); + void MatrixXorAnd(cv::Mat &frame); + void XorAlpha(cv::Mat &frame); + void AlphaAcidTrails(cv::Mat &frame); + void SelfXorAverage(cv::Mat &frame); + void RandomXorBlend(cv::Mat &frame); + void RGBVerticalXor(cv::Mat &frame); + void RGBVerticalXorScale(cv::Mat &frame); + void RGBHorizontalXor(cv::Mat &frame); + void RGBHorizontalXorScale(cv::Mat &frame); + void FadeStrobe(cv::Mat &frame); + void RGBMirror(cv::Mat &frame); + void MirrorStrobe(cv::Mat &frame); + void AndStrobe(cv::Mat &frame); + void AndStrobeScale(cv::Mat &frame); + void AndPixelStrobe(cv::Mat &frame); + void AndOrXorStrobe(cv::Mat &frame); + void AndOrXorStrobeScale(cv::Mat &frame); + void FadeInAndOut(cv::Mat &frame); + void BrightStrobe(cv::Mat &frame); + void DarkStrobe(cv::Mat &frame); + void ParticleFast(cv::Mat &frame); + void RandomXorOpposite(cv::Mat &frame); + void StrobeTransform(cv::Mat &frame); + void InitBlend(cv::Mat &frame); + void MoveUpLeft(cv::Mat &frame); + void RandomStrobe(cv::Mat &frame); + void RandomBlur(cv::Mat &frame); + void Stuck(cv::Mat &frame); + void StuckStrobe(cv::Mat &frame); + void OrStrobe(cv::Mat &frame); + void LagBlend(cv::Mat &frame); + void SubFilter(cv::Mat &frame); + void AddFilter(cv::Mat &frame); + void BlendImageXor(cv::Mat &frame); + void BlendImageAround_Median(cv::Mat &frame); + void ImageBlendTransform(cv::Mat &frame); + void RGBTrails(cv::Mat &frame); + void RGBTrailsDark(cv::Mat &frame); + void RGBTrailsAlpha(cv::Mat &frame); + void RGBTrailsNegativeAlpha(cv::Mat &frame); + void MovementRGBTrails(cv::Mat &frame); + void RGBTrailsXor(cv::Mat &frame); + void DifferenceStrobe(cv::Mat &frame); + void BlackAndWhiteDifferenceStrobe(cv::Mat &frame); + void DifferenceXor(cv::Mat &frame); + void DifferenceRand(cv::Mat &frame); + void DifferenceBrightStrobe(cv::Mat &frame); + void PsycheTrails(cv::Mat &frame); + void FourSquare(cv::Mat &frame); + void EightSquare(cv::Mat &frame); + void DiagonalSquare(cv::Mat &frame); + void DiagonalSquareRandom(cv::Mat &frame); + void SquareStretchDown(cv::Mat &frame); + void SquareStretchRight(cv::Mat &frame); + void SquareStretchUp(cv::Mat &frame); + void SquareStretchLeft(cv::Mat &frame); + void DarkTrails(cv::Mat &frame); + void SoftFeedback(cv::Mat &frame); + void SoftFeedbackFrames(cv::Mat &frame); + void ResizeSoftFeedback(cv::Mat &frame); + void SoftFeedback8(cv::Mat &frame); + void SoftFeedbackFrames8(cv::Mat &frame); + void ResizeSoftFeedback8(cv::Mat &frame); + void ResizeSoftFeedbackSubFilter(cv::Mat &frame); + void SoftFeedbackRandFilter(cv::Mat &frame); + void SoftFeedback32(cv::Mat &frame); + void SoftFeedbackFrames32(cv::Mat &frame); + void ResizeSoftFeedback32(cv::Mat &frame); + void SoftFeedbackRandFilter32(cv::Mat &frame); + void SoftFeedbackSubFilter(cv::Mat &frame); + void SoftFeedbackResize64(cv::Mat &frame); + void SoftFeedbackResizeSubFilter(cv::Mat &frame); + void SoftFeedbackResizeSubFilter64(cv::Mat &frame); + void SoftFeedbackReszieSubFilter64_Negate(cv::Mat &frame); + void SoftFeedbackReszieSubFilter64_Mirror(cv::Mat &frame); + void HalfNegateStrobe(cv::Mat &frame); + void MedianBlurXor(cv::Mat &frame); + void NegateTrails(cv::Mat &frame); + void RandomGradient(cv::Mat &frame); + void RandomStrobeFlash(cv::Mat &frame); + void RandomMirror(cv::Mat &frame); + void RandomOther(cv::Mat &frame); + void RandomXorFilter(cv::Mat &frame); + void RandomMirrorBlend(cv::Mat &frame); + void RandomMirrorAlphaBlend(cv::Mat &frame); + void Bitwise_XOR_AlphaSubFilter(cv::Mat &frame); + void AlphaBlendSubFilter(cv::Mat &frame); + void GradientSubFilterXor(cv::Mat &frame); + void XorBlend_SubFilter(cv::Mat &frame); + void SmoothSubFilterAlphaBlend(cv::Mat &frame); + void SmoothSubFilterXorBlend(cv::Mat &frame); + void IntertwineSubFilter(cv::Mat &frame); + void RandBlend(cv::Mat &frame); + void EveryOther(cv::Mat &frame); + void EveryOtherSubFilter(cv::Mat &frame); + void SmoothRandomFilter(cv::Mat &frame); + void RandomFilterRandomTimes(cv::Mat &frame); + void RandomSubFilterRandomTimes(cv::Mat &frame); + void AddToFrameSubFilter(cv::Mat &frame); + void MirrorXor(cv::Mat &frame); + void MirrorXorAll(cv::Mat &frame); + void MirrorXorScale(cv::Mat &frame); + void EnergyMirror(cv::Mat &frame); + void SmoothSubFilter(cv::Mat &frame); + void SmoothSubFilter16(cv::Mat &frame); + void EnergizeSubFilter(cv::Mat &frame); + void EnergizeSubFilter16(cv::Mat &frame); + void EnergizeSubFilter32(cv::Mat &frame); + void SmoothSubFilter32(cv::Mat &frame); + void HalfAddSubFilter(cv::Mat &frame); + void HalfXorSubFilter(cv::Mat &frame); + void StaticXorBlend(cv::Mat &frame); + void PsycheSort(cv::Mat &frame); + void XorScale(cv::Mat &frame); + void ChannelMedianSubFilter(cv::Mat &frame); + void GaussianStrobe(cv::Mat &frame); + void StrobeSort(cv::Mat &frame); + void GlitchSortStrobe(cv::Mat &frame); + void Bitwise_XOR_Blend(cv::Mat &frame); + void Bitwise_XOR_Sort(cv::Mat &frame); + void Bitwise_OR_Blend(cv::Mat &frame); + void Bitwise_AND_Blend(cv::Mat &frame); + void BitwiseColorMatrix(cv::Mat &frame); + void PixelReverseXor(cv::Mat &frame); + void PixelatedSubFilterSort(cv::Mat &frame); + void SilverBlend(cv::Mat &frame); + void RandomPixelOrderSort(cv::Mat &frame); + void ImageXorAlpha(cv::Mat &frame); + void ImageAverageXor(cv::Mat &frame); + void PixelXorBlend(cv::Mat &frame); + void SelfAlphaScale(cv::Mat &frame); + void SelfScaleAlpha(cv::Mat &frame); + void RainbowXorBlend(cv::Mat &frame); + void FrameDifference(cv::Mat &frame); + void SmallDiffference(cv::Mat &frame); + void FadeBlend(cv::Mat &frame); + void FilteredDifferenceSubFilter(cv::Mat &frame); + void ExpandSquareSubFilter(cv::Mat &frame); + void ExpandSquareBlendSubFilter(cv::Mat &frame); + void ExpandSquareVerticalSubFilter(cv::Mat &frame); + void DarkImageMedianBlend(cv::Mat &frame); + void GammaDarken5(cv::Mat &frame); + void GammaDarken10(cv::Mat &frame); + void SelfAlphaScaleBlend(cv::Mat &frame); + void FadeBars(cv::Mat &frame); + void MirrorXorAlpha(cv::Mat &frame); + void MirrorEnergizeSubFilter(cv::Mat &frame); + void StrobeXor(cv::Mat &frame); + void IntertwinedMirror(cv::Mat &frame); + void BlurredMirror(cv::Mat &frame); + void ShadeRGB(cv::Mat &frame); + void InterRGB_SubFilter(cv::Mat &frame); + void InterSmoothSubFilter(cv::Mat &frame); + void InterRGB_Bars_XY(cv::Mat &frame); + void InterRGB_Bars_X(cv::Mat &frame); + void InterRGB_Bars_Y(cv::Mat &frame); + void StoredFramesAlphaBlend_SubFilter(cv::Mat &frame); + void BlendSubFilter(cv::Mat &frame); + void BlendAlphaSubFilter(cv::Mat &frame); + void ReverseFrameBlend(cv::Mat &frame); + void ReverseFrameBlendSwitch(cv::Mat &frame); + void DoubleRandomMirror(cv::Mat &frame); + void Blend_AlphaSubFilter(cv::Mat &frame); + void RandomBlendFilter(cv::Mat &frame); + void DoubleRandomBlendFilter(cv::Mat &frame); + void FlipBlendWH(cv::Mat &frame); + void FlipBlendW(cv::Mat &frame); + void FlipBlendH(cv::Mat &frame); + void FlipBlendAll(cv::Mat &frame); + void FrameMedianBlendSubFilter(cv::Mat &frame); + void FrameBlurSubFilter(cv::Mat &frame); + void ImageBlendSubFilter(cv::Mat &frame); + void ImageBlendXorSubFilter(cv::Mat &frame); + void ImageCollectionSubFilter(cv::Mat &frame); + void SelfScaleXorIncrease(cv::Mat &frame); + void Blend_RedGreenBlue(cv::Mat &frame); + void XorBlend_RedGreenBlue(cv::Mat &frame); + void BlendIncrease_RedGreenBlue(cv::Mat &frame); + void Blend_RedReenBlue_Dark(cv::Mat &frame); + void DarkModBlend(cv::Mat &frame); + void PictureBuzz(cv::Mat &frame); + void IncDifference(cv::Mat &frame); + void IncDifferenceAlpha(cv::Mat &frame); + void MirrorMedianBlend(cv::Mat &frame); + void SubFilterMedianBlend(cv::Mat &frame); + void DarkenBlend(cv::Mat &frame); + void DarkCollectionSubFilter(cv::Mat &frame); + void ChannelSort_NoBlend_Descending(cv::Mat &frame); + void ChannelSort_NoBlend_Ascending(cv::Mat &frame); + void Headrush(cv::Mat &frame); + void DarkSmooth_Filter(cv::Mat &frame); + void DarkSelfAlpha(cv::Mat &frame); + void FlipMedian(cv::Mat &frame); + void FlipMedianSubFilter(cv::Mat &frame); + void FlipMirror(cv::Mat &frame); + void FlipMirrorAverage(cv::Mat &frame); + void FlipMirrorSubFilter(cv::Mat &frame); + void ShuffleMedian(cv::Mat &frame); + void ShuffleRGB(cv::Mat &frame); + void ParticleSnow(cv::Mat &frame); + void RandomPixels(cv::Mat &frame); + void DarkRandomPixels(cv::Mat &frame); + void MedianBlurSubFilter(cv::Mat &frame); + void Bars(cv::Mat &frame); + void ShuffleAlpha(cv::Mat &frame); + void AlphaMorph(cv::Mat &frame); + void ShuffleSelf(cv::Mat &frame); + void PixelatedHorizontalLines(cv::Mat &frame); + void PixelatedVerticalLines(cv::Mat &frame); + void StrobeShuffle(cv::Mat &frame); + void BlendBurred(cv::Mat &frame); + void BlendCombinedValues(cv::Mat &frame); + void RGBColorTrails(cv::Mat &frame); + void BlendCombinedValueSubFilter(cv::Mat &frame); + void BlendSubFilterAlpha(cv::Mat &frame); + void GradientXorPixels(cv::Mat &frame); + void PurpleRain(cv::Mat &frame); + void PixelByPixelXor(cv::Mat &frame); + void CopyXorAlpha(cv::Mat &frame); + void AveragePixelsXor(cv::Mat &frame); + void AveragePixelAlpha(cv::Mat &frame); + void NegativeByRow(cv::Mat &frame); + void AveragePixelCollection(cv::Mat &frame); + void IncorrectLine(cv::Mat &frame); + void XorShift(cv::Mat &frame); + void StrobeXorAndOr(cv::Mat &frame); + void XorWithSource(cv::Mat &frame); + void AlphaBlendWithSource(cv::Mat &frame); + void RGBSep1x(cv::Mat &frame); + void RGBMedianBlend(cv::Mat &frame); + void RGBMirror1(cv::Mat &frame); + void RGBMirror1Median(cv::Mat &frame); + void FlashMirror(cv::Mat &frame); + void CollectionXorSourceSubFilter(cv::Mat &frame); + void ReverseMirrorX(cv::Mat &frame); + void MirrorXorAll_Reverse(cv::Mat &frame); + void MirrorRGBReverse(cv::Mat &frame); + void MirrorRGBReverseBlend(cv::Mat &frame); + void BlendReverseSubFilter(cv::Mat &frame); + void MirrorBitwiseXor(cv::Mat &frame); + void SmoothBlendReverseSubFilter(cv::Mat &frame); + void RandomIncrease(cv::Mat &frame); + void MedianBlend16(cv::Mat &frame); + void MedianBlendBufferSubFilter(cv::Mat &frame); + void BGRBlend(cv::Mat &frame); + void RGBBlend(cv::Mat &frame); + void RGBBlendSubFilter(cv::Mat &frame); + void DivideAndIncH(cv::Mat &frame); + void DivideAndIncW(cv::Mat &frame); + void XorOppositeSubFilter(cv::Mat &frame); + void BlendSmoothSubFilter(cv::Mat &frame); + void BlurSmooth(cv::Mat &frame); + void BlurSmoothMedian(cv::Mat &frame); + void BlurSmoothSubFilter(cv::Mat &frame); + void BlurFlip(cv::Mat &frame); + void BlurFlipSubFilter(cv::Mat &frame); + void BlurMirrorGamma(cv::Mat &frame); + void MedianBlendDark(cv::Mat &frame); + void MedianBlendSubFilterEx(cv::Mat &frame); + void EnergyMirrorDark(cv::Mat &frame); + void AlphaBlendMirror(cv::Mat &frame); + void MirrorAlphaBlendedImage(cv::Mat &frame); + void AlphaBlendXorImage(cv::Mat &frame); + void ShiftFrameSmoothSubFilter(cv::Mat &frame); + void ShiftFrameStaticXorSubFilter(cv::Mat &frame); + void IncreaseDecreaseGamma(cv::Mat &frame); + void GammaIncDecIncrease(cv::Mat &frame); + void RandomSubFilter(cv::Mat &frame); + void TwistedVision(cv::Mat &frame); + void TwistedMirror(cv::Mat &frame); + void SelfScaleSortBlend(cv::Mat &frame); + void FlashMedianBlend(cv::Mat &frame); + void BlendWithFrameSubFilter(cv::Mat &frame); + void AlphaBlendWithFrameSubFilter(cv::Mat &frame); + void AlphaXorBlendWithFrameSubFilter(cv::Mat &frame); + void XorBlendSubFilter(cv::Mat &frame); + void FlipAlphaBlend(cv::Mat &frame); + void RandomFlipFilter(cv::Mat &frame); + void MirrorMedian(cv::Mat &frame); + void FlipMatrixCollection(cv::Mat &frame); + void MirrorMatrixCollection(cv::Mat &frame); + void MirrorMatrixSource(cv::Mat &frame); + void SelfScaleByFrame(cv::Mat &frame); + void SmoothMedianRotateSubFilter(cv::Mat &frame); + void SmoothCollectionAlphaBlend(cv::Mat &frame); + void XorSubFilter(cv::Mat &frame); + void XorAlphaSubFilter(cv::Mat &frame); + void BlurXorAlphaSubFilter(cv::Mat &frame); + void ImageXorFrame(cv::Mat &frame); + void ImageXorFunction(cv::Mat &frame); + void ImageXorAlphaBlend(cv::Mat &frame); + void ImageAlphaXorMedianSubFilter(cv::Mat &frame); + void ImageSmoothAlphaXorSubFilter(cv::Mat &frame); + void ImageXorMirrorFilter(cv::Mat &frame); + void ImageXorSubFilter(cv::Mat &frame); + void ImageAlphaXorSubFilter(cv::Mat &frame); + void SmoothTrailsBlend(cv::Mat &frame); + void MatrixCollectionRGBXor(cv::Mat &frame); + void RainbowGlitch(cv::Mat &frame); + void RainbowGlichStrobe(cv::Mat &frame); + void NegateSwitchStrobe(cv::Mat &frame); + void StrobeAlphaShuffle(cv::Mat &frame); + void ShuffleAlphaWithRGB(cv::Mat &frame); + void ShuffleAlphaSubFilter(cv::Mat &frame); + void ShuffleColorMap(cv::Mat &frame); + void BlendWithRainbowSubFilter(cv::Mat &frame); + void BlendWithJetSubFilter(cv::Mat &frame); + void ColormapBlendSubFilter(cv::Mat &frame); + void RandomColorMap(cv::Mat &frame); + void SmoothMirrorBlurFlip(cv::Mat &frame); + void RandomColorMapAlphaBlendSubFilter(cv::Mat &frame); + void RandomOrder(cv::Mat &frame); + void RandomOrderMedianBlendSubFilter(cv::Mat &frame); + void MirrorOrder(cv::Mat &frame); + void MirrorOrderSubFilter(cv::Mat &frame); + void BlurMirrorOrder(cv::Mat &frame); + void AveragePixelMirror(cv::Mat &frames); + void ShuffleAlphaMedianBlend(cv::Mat &frame); + void MirrorOrderAlpha(cv::Mat &frame); + void FilterStrobeSubFilter(cv::Mat &frame); + void ImageSubtractMedianBlend(cv::Mat &frame); + void ImageDarkBlend(cv::Mat &frame); + void ImageAverageDark(cv::Mat &frame); + void ImageRemainderPixel(cv::Mat &frame); + void AverageLinesBlend(cv::Mat &frame); + void SoftFeedbackMirror(cv::Mat &frame); + void AverageVerticalLinesBlend(cv::Mat &frame); + void LinesMedianBlend(cv::Mat &frame); + void XorSquare(cv::Mat &frame); + void PixelValuesPlusOne(cv::Mat &frame); + void AverageHorizontalFilter(cv::Mat &frame); + void AverageVerticalFilter(cv::Mat &frame); + void GradientAlphaXorHorizontal(cv::Mat &frame); + void GradientAlphaXorVertical(cv::Mat &frame); + void BlendImageWithSubFilter(cv::Mat &frame); + void BlendImageWithSubFilterAlpha(cv::Mat &frame); + void MedianBlendSoft(cv::Mat &frame); + void AndImageSubFilterXor(cv::Mat &frame); + void AlphaBlendImageSubFilterXor(cv::Mat &frame); + void AlphaBlendImageSubFilterXorRev(cv::Mat &frame); + void ParticleReleaseXor(cv::Mat &frame); + void ParticleReleaseXorVec(cv::Mat &frame); + void ParticleReleaseAlphaBlend(cv::Mat &frame); + void ParticleReleaseWithImage(cv::Mat &frame); + void ParticleReleaseSubFilter(cv::Mat &frame); + void ParticleReleaseImageSubFilter(cv::Mat &frame); + void ImageEnergy(cv::Mat &frame); + void ImageEnergySubFilter(cv::Mat &frame); + void ImageDistortion(cv::Mat &frame); + void ImageDistortionSubFilter(cv::Mat &frame); + void SmoothExactImageXorAlpha(cv::Mat &frame); + void FeedbackColormap(cv::Mat &frame); + void SmoothImageAlphaBlendMedian(cv::Mat &frame); + void ImageDarkenSmoothMedian(cv::Mat &frame); + void XorReverseImageSmooth(cv::Mat &frame); + void ReverseSubFilterBlend(cv::Mat &frame); + void ReverseSubFilterXor(cv::Mat &frame); + void ImageReverseSubFilter(cv::Mat &frame); + void SmoothRainbowMedian(cv::Mat &frame); + void MirrorAlphaBlend(cv::Mat &frame); + void ImageSmoothMedianBlend(cv::Mat &frame); + void ImageSmoothMedianSubFilter(cv::Mat &frame); + void ImageAlphaXorMedianBlend(cv::Mat &frame); + void MatrixCollectionBlend(cv::Mat &frame); + void MatrixCollectionSubFilter(cv::Mat &frame); + void MatrixCollectionImageSubFilter(cv::Mat &frame); + void MatrixCollectionBlurAlpha(cv::Mat &frame); + void MatrixCollectionXor(cv::Mat &frame); + void MatrixCollectionXor32(cv::Mat &frame); + void MatrixCollectionRandomColorMap(cv::Mat &frame); + void MatrixCollectionDarkXor(cv::Mat &frame); + void MatrixCollectionRGB(cv::Mat &frame); + void TrailsSubFilter(cv::Mat &frame); + void TrailsSubFilter32(cv::Mat &frame); + void CompareWithSubFilter(cv::Mat &frame); + void MedianTrails(cv::Mat &frame); + void SmoothMedianBlend(cv::Mat &frame); + void ColorTransition(cv::Mat &frame); + void ColorTransitionMedian(cv::Mat &frame); + void ColorTransitionRandom(cv::Mat &frame); + void ColorTransitionRandomMedian(cv::Mat &frame); + void ColorTransitionSubFilter(cv::Mat &frame); + void ColorTransitionImageSubFilter(cv::Mat &frame); + void CurtainSubFilter(cv::Mat &frame); + void RandomTrails(cv::Mat &frame); + void RandomTrailsSubFilter(cv::Mat &frame); + void CosSinMedianBlend(cv::Mat &frame); + void TrailsRGB(cv::Mat &frame); + void MatrixTrailsXorRandom(cv::Mat &frame); + void CosSinMultiplyCollectionXor(cv::Mat &frame); + void Filter8_Blend(cv::Mat &frame); + void Filter8_SubFilter(cv::Mat &frame); + void RandomSmoothAlphaMedian(cv::Mat &frame); + void RandomAlphaBlendFilter(cv::Mat &frame); + void RandomMirrorBitwiseXor(cv::Mat &frame); + void SquareDivideSubFilter(cv::Mat &frame); + void SquareSubFilter(cv::Mat &frame); + void SquareSubFilter8(cv::Mat &frame); + void SquareRandomFilter(cv::Mat &frame); + void SquareRandomSubFilter(cv::Mat &frame); + void ColorExpand(cv::Mat &frame); + void ColorExpandSubFilter(cv::Mat &frame); + void RotateImage(cv::Mat &frame); + void RotateBlendImage(cv::Mat &frame); + void RotateImageSubFilter(cv::Mat &frame); + void RotateAlphaBlendImage(cv::Mat &frame); + void FlipShuffle(cv::Mat &frame); + void FlipRandom(cv::Mat &frame); + void FlipOrder(cv::Mat &frame); + void FlipStrobeSubFilter(cv::Mat &frame); + void MirrorBlendFrame(cv::Mat &frame); + void MirrorBlendVertical(cv::Mat &frame); + void MirrorVerticalAndHorizontal(cv::Mat &frame); + void BlendFor360(cv::Mat &frame); + void MirrorSidesMedian(cv::Mat &frame); + void MirrorSidesSubFilter(cv::Mat &frame); + void MedianFrameAlphaBlendSubFilter(cv::Mat &frame); + void MedianSubFilter(cv::Mat &frame); + void ColorXorScale(cv::Mat &frame); + void ColorXorScaleSubFilter(cv::Mat &frame); + void ImageXorScale(cv::Mat &frame); + void MatrixCollectionShiftSubFilter(cv::Mat &frame); + void MatrixCollectionImageShiftSubFilter(cv::Mat &frame); + void MatrixCollectionSmoothAlphaBlend(cv::Mat &frame); + void MatrixCollectionBlurImageXorAlpha(cv::Mat &frame); + void MatrixCollectionBlurImageSubFilter(cv::Mat &frame); + void MatrixCollectionBlurImageSubFilter16(cv::Mat &frame); + void ImageAlphaBlendSubFilter(cv::Mat &frame); + void MultipleMatrixCollectionSubFilter(cv::Mat &frame); + void BlurAlphaSubFilter(cv::Mat &frame); + void BlurImageSubFilter(cv::Mat &frame); + void MedianBlendSubFilter(cv::Mat &frame); + void MedianBlendImageSubFilter(cv::Mat &frame); + void MedianBlendSelfBlend(cv::Mat &frame); + void BlendHalfSubFilter(cv::Mat &frame); + void BlurImageAlphaBlend(cv::Mat &frame); + void BlurImageAlphaBlendSubFilter(cv::Mat &frame); + void BlurImageAlphaBlendScaleSubFilter(cv::Mat &frame); + void RandomAmountOfMedianBlur(cv::Mat &frame); + void Bitwise_XOR_BlendFrame(cv::Mat &frame); + void AlphaBlendWithSubFilter(cv::Mat &frame); + void AlphaBlendScaleWithSubFilter(cv::Mat &frame); + void GaussianBlendEx(cv::Mat &frame); + void SimpleMatrixBlend(cv::Mat &frame); + void MatrixBlendSubFilter(cv::Mat &frame); + void SmoothMatrixBlendSubFilter(cv::Mat &frame); + void BlurSmoothSubFilterAlphaBlend(cv::Mat &frame); + void BlurSmoothAlphaXorBlendSubFilter(cv::Mat &frame); + void BlurTwiceSubFilter(cv::Mat &frame); + void BlurFrameBlendSubFilter(cv::Mat &frame); + void BlurFrameSubFilter(cv::Mat &frame); + void BlurSmoothMatrix(cv::Mat &frame); + void MedianBlurInc(cv::Mat &frame); + void GaussianBlurInc(cv::Mat &frame); + void BlurSmoothMedianInc(cv::Mat &frame); + void BlurSmoothGaussianInc(cv::Mat &frame); + void BlurMatrixCollectionXor(cv::Mat &frame); + void MatrixCollection8XorSubFilter(cv::Mat &frame); + void BlurSmoothRevFilter(cv::Mat &frame); + void SurroundingPixels(cv::Mat &frame); + void SurroundingPixelsAlpha(cv::Mat &frame); + void MatrixCollectionSurroundingPixels(cv::Mat &frame); + void MatrixCollectionSurroundingPixelsSubFilter(cv::Mat &frame); + void MatrixCollectionSurroundingPixelsImage(cv::Mat &frame); + void MatrixCollectionSurroundingPixelsImageSubFilter(cv::Mat &frame); + void ImageTransparent(cv::Mat &frame); + void MatrixImageAlphaBlendSubFilter(cv::Mat &frame); + void ImageAlphaCollectionSmoothBlend(cv::Mat &frame); + void ImageRandomColormap(cv::Mat &frame); + void ImageRandomColormapAlphaBlend(cv::Mat &frame); + void ImageRandomColormapAlphaScale(cv::Mat &frame); + void ImageRandomColormapSubFilter(cv::Mat &frame); + void ImageShuffle(cv::Mat &frame); + void ImageSubFilter(cv::Mat &frame); + void ImageAlphaBlendWithFrameSubFilter(cv::Mat &frame); + void ImageFadeInOut(cv::Mat &frame); + void ImageFadeBlackInOut(cv::Mat &frame); + void ImageFadeBlackInOutSubFilter(cv::Mat &frame); + void ImageFadeFrameInOut(cv::Mat &frame); + void ImageFadeFrameInOutSubFilter(cv::Mat &frame); + void ImageFadeDouble(cv::Mat &frame); + void BlendSubFilterAndImage(cv::Mat &frame); + void FadeSubFilter(cv::Mat &frame); + void FadeSubFilterRev(cv::Mat &frame); + void ImageBlendSubFilterMedianBlend(cv::Mat &frame); + void FadeSubFilterXor(cv::Mat &frame); + void BlurXorSubFilter(cv::Mat &frame); + void ColorFlashIncrease(cv::Mat &frame); + void ScaleFilter(cv::Mat &frame); + void NegativeDarkenXor(cv::Mat &frame); + void ImageXor_SubFilter(cv::Mat &frame); + void NegateBlendSubFilter(cv::Mat &frame); + void StrobeNegatePixel(cv::Mat &frame); + void StrobeNegateInOut(cv::Mat &frame); + void ImageStrobeOnOff(cv::Mat &frame); + void AlphaStrobeBlend(cv::Mat &frame); + void CannyRandomPixels(cv::Mat &frame); + void FrameImageFadeInOut(cv::Mat &frame); + void FrameImageFadeInOutDouble(cv::Mat &frame); + void ChangeEachSecond(cv::Mat &frame); + void ShuffleImage(cv::Mat &frame); + void ChangeImageEachSecond(cv::Mat &frame); + void ChangeImageFilterOnOff(cv::Mat &frame); + void ChangeXorEachSecond(cv::Mat &frame); + void MorphXor(cv::Mat &frame); + void MorphXorWithSubFilter(cv::Mat &frame); + void MirrorEachSecond(cv::Mat &frame); + void MirrorReverseSubFilter(cv::Mat &frame); + void MirrorReverseSubFilterAlphaBlend(cv::Mat &frame); + void Mirror_Xor_Combined(cv::Mat &frame); + void MirrorFrameShuffle(cv::Mat &frame); + void MirrorShuffleSmooth(cv::Mat &frame); + void Mirror_Xor_Smooth(cv::Mat &frame); + void XorFrameShuffle(cv::Mat &frame); + void XorMirrorBlendFrame(cv::Mat &frame); + void ImageXorSmooth(cv::Mat &frame); + void SmoothSubFilter64(cv::Mat &frame); + void SmoothMedian64(cv::Mat &frame); + void SmoothMedian32_SubFilter(cv::Mat &frame); + void SmoothAlphaMedian_SubFilter(cv::Mat &frame); + void SmoothImage_SubFilter(cv::Mat &frame); + void SmoothImageMedian_SubFilter(cv::Mat &frame); + void SmoothImageAndSubFilter(cv::Mat &frame); + void SmoothSubFilter90(cv::Mat &frame); + void SmoothMedianImageSubFilter16(cv::Mat &frame); + void ImageNegate(cv::Mat &frame); + void ImageNegateAlphaBlend(cv::Mat &frame); + void ImageNegateAlphaBlendSubFilter(cv::Mat &frame); + void FrameNegateAlphaBlendImage(cv::Mat &frame); + void DarkTrailsEffect(cv::Mat &frame); + void DarkNegate(cv::Mat &frame); + void ChannelSortMedianBlend(cv::Mat &frame); + void MatrixCollectionMirrorDirection(cv::Mat &frame); + void StrobeRandomChannel(cv::Mat &frame); + void SplitFramesSort(cv::Mat &frame); + void SplitFrameSortSubFilter(cv::Mat &frame); + void MedianBlend64(cv::Mat &frame); + void SplitFrameFilter(cv::Mat &frame); + void SplitFrameBlend(cv::Mat &frame); + void SplitFrameBlendSubFilter(cv::Mat &frame); + void SplitFrameCollection(cv::Mat &frame); + void SplitFrameMirror(cv::Mat &frame); + void RandomChannels(cv::Mat &frame); + void SmoothRandomChannels(cv::Mat &frame); + void SmoothChannelSubFilter(cv::Mat &frame); + void IncreaseRGB(cv::Mat &frame); + void IncreaseColor(cv::Mat &frame); + void SaturateBlend(cv::Mat &frame); + void SaturateBlendSubFilter(cv::Mat &frame); + void MaxRGB(cv::Mat &frame); + void XorDifferenceFilter(cv::Mat &frame); + void AlphaBlendChannelSort(cv::Mat &frame); + void ColorTrailsFilter(cv::Mat &frame); + void ColorTrailsSubFilter(cv::Mat &frame); + void DarkNegateRainbowMedian(cv::Mat &frame); + void IncreaseQuick(cv::Mat &frame); + void IncreaseRandomIndex(cv::Mat &frame); + void ImageChannelSubFilter(cv::Mat &frame); + // No filter (do nothing) + void NoFilter(cv::Mat &frame); + // Alpha blend with original image + void BlendWithSource(cv::Mat &frame); + // plugin must be implemented in project + void plugin(cv::Mat &frame); + // set Custom Filter callback function + void setCustom(DrawFunction f); + void setPlugin(DrawFunction f); + void setProcMode(int value); + void setSubFilter(int value); + void clearSubFilter(); + // color maps + void Negate(cv::Mat &frame); + void ApplyColorMap(cv::Mat &frame); + void AddInvert(cv::Mat &frame); + // color correction + void setBlendPercentage(const double &value); + void setBrightness(cv::Mat &frame, double alpha, int beta); + void setGamma(cv::Mat &frame, cv::Mat &outframe, double gamma); + void setSaturation(cv::Mat &frame, int saturation); + void AlphaBlend(const cv::Mat &one, const cv::Mat &two, cv::Mat &output, double alpha); + void RealAlphaBlend(const cv::Mat &one, const cv::Mat &two, cv::Mat &output, double alpha); + void AlphaBlendDouble(const cv::Mat &one, const cv::Mat &two, cv::Mat &output, double alpha1, double alpha2); + void AlphaXorBlend(const cv::Mat &one, const cv::Mat &two, cv::Mat &output, double alpha); + void AlphaXorBlendDouble(const cv::Mat &one, const cv::Mat &two, cv::Mat &output, double alpha1, double alpha2); + void AlphaMovement(double *alpha, int *dir, double inc); + void AlphaMovementMaxMin(double &alpha, int &dir, double speed, double max, double min); + void PixelScaleAlpha(cv::Mat &frame, double amt); + void DarkenImage(cv::Mat &frame, unsigned int size); + void Add(cv::Mat &src, cv::Mat &add, bool sat = false); + void Sub(cv::Mat &src, cv::Mat &sub, bool sat = false); + void Xor(cv::Mat &dst, const cv::Mat &add); + void Xor(const cv::Mat &input, const cv::Mat &add, cv::Mat &out); + void ScalarAverage(const cv::Mat &frame, cv::Scalar &s); + void TotalAverageOffset(cv::Mat &frame, unsigned long &value); + void swapColors(cv::Mat &frame, int x, int y); + void swapColors_(cv::Mat &frame, int x, int y); + void procPos(int &direction, double &pos, double &pos_max, const double max_size = 15, double iter = 0.05); + void setColorKeyRange(cv::Vec3b low, cv::Vec3b high); + void setBlockedColorKeys(std::vector &blocked); + bool colorBounds(const cv::Vec3b &color, const cv::Vec3b &pixel, const cv::Vec3b &range_low, const cv::Vec3b &range_high); + SearchType searchColors(const cv::Vec3b &color); + bool compareColor(const cv::Vec3b &color, const cv::Vec3b &low, const cv::Vec3b &high); + void setGrayColor(const cv::Vec3b &color); + unsigned char size_cast(long val); + unsigned char size_reset(long val); + // Alpha Blend two filters and set to frame by alpha variable + void filterFade(cv::Mat &frame, int filter1, int filter2, double alpha); + void filterColorKeyed(const cv::Vec3b &color, const cv::Mat &orig, const cv::Mat &filtered, cv::Mat &output); + void resetAlpha(int &dir, double &alpha); + void resetAlpha(double &alpha); + void SwapColors(cv::Vec3b &v); + void FillRow(cv::Mat &frame, unsigned int row, unsigned char value); + void Shuffle(int &index, cv::Mat &frame, std::vector &filter_array); + void AddMatVector(cv::Mat &frame, std::vector &v); + void setColorMap(int map, cv::Mat &frame); + void blendFilterWithColorMap(int filter, int map, cv::Mat &frame); + void SwitchOrder(cv::Vec3b &frame, int order); + void pushSubFilter(int newsub); + void popSubFilter(); + // draw functions / strings + extern std::string *draw_strings; + extern DrawFunction plugin_func; + extern DrawFunction *draw_func; + extern FilterType *filter_array; + extern int draw_max; + extern bool snapShot; + extern bool reset_filter; + extern double alpha_increase; + extern std::unordered_map filter_map; + extern std::unordered_map filter_map_str; + + extern bool frames_released; + extern std::vector all_objects; + // Matrix Collection template + template + class MatrixCollection { + public: + static constexpr int ArraySize = Size; + MatrixCollection() : w(0), h(0) { + for(int i = 0; i < Size; ++i) + all_objects.push_back(&frames[i]); + } + cv::Mat frames[Size+4]; + int w, h; + void shiftFrames(cv::Mat &frame) { + if(resetFrame(frame)) { + for(int i = Size-1; i > 0; --i) { + frames[i] = frames[i-1]; + } + frames[0] = frame.clone(); + } + } + + bool resetFrame(cv::Mat &frame) { + int wx = frame.cols; + int wh = frame.rows; + // check if any frames were released. + bool check_released = false; + for(int i = 0; i < Size; ++i) { + if(frames[i].empty()) { + check_released = true; + break; + } + } + if(check_released == true || (w != wx || h != wh) || reset_filter == true || frames_released == true) { + for(int i = 0; i < Size; ++i) + frames[i] = frame.clone(); + w = wx; + h = wh; + reset_filter = false; + return false; + } + return true; + } + + int size() const { return ArraySize; } + }; + extern void release_all_objects(); + extern bool testSize(cv::Mat &frame); + // Trails function + template + void Smooth(cv::Mat &frame, MatrixCollection *collection, bool addframe = true) { + if(addframe == true) + collection->shiftFrames(frame); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Scalar test; + for(int q = 0; q < collection->size()-1; ++q) { + cv::Mat &framev = collection->frames[q]; + cv::Vec3b pix = framev.at(z, i); + for(int j = 0; j < 3; ++j) { + test[j] += pix[j]; + } + } + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + test[j] /= (collection->size()-1); + pixel[j] = cv::saturate_cast(test[j]); + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel + } + } + } + + template + void DarkSmooth(cv::Mat &frame, MatrixCollection *collection, int dark) { + collection->shiftFrames(frame); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Scalar test; + for(int q = 1; q < collection->size(); ++q) { + cv::Mat &framev = collection->frames[q]; + cv::Vec3b pix = framev.at(z, i); + for(int j = 0; j < 3; ++j) { + test[j] += pix[j]; + } + } + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + test[j] /= (collection->size()); + test[j] /= dark; + pixel[j] /= dark; + pixel[j] = pixel[j]^static_cast(test[j]); + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel + } + } + } + // Trails function + template + void StaticXor(cv::Mat &frame, MatrixCollection *collection, cv::Vec3b r) { + collection->shiftFrames(frame); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Scalar test; + for(int q = 0; q < collection->size()-1; ++q) { + cv::Mat &framev = collection->frames[q]; + cv::Vec3b pix = framev.at(z, i); + for(int j = 0; j < 3; ++j) { + test[j] += pix[j]; + } + } + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + test[j] /= (collection->size()); + pixel[j] = static_cast(test[j])^r[j]; + } + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel + } + } + } + // Trails function + template + void SmoothRGB(cv::Mat &frame, MatrixCollection *collection) { + collection->shiftFrames(frame); + static int index = 0; + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Scalar test; + for(int q = 0; q < collection->size()-1; ++q) { + cv::Mat &framev = collection->frames[q]; + cv::Vec3b pix = framev.at(z, i); + for(int j = 0; j < 3; ++j) { + test[j] += pix[j]; + } + } + cv::Vec3b &pixel = frame.at(z, i); + test[index] /= (collection->size()-1); + pixel[index] = cv::saturate_cast(test[index]); + swapColors(frame, z, i);// swap colors + if(isNegative) invert(frame, z, i);// if isNegative invert pixel + } + } + ++index; + if(index > 2) + index = 0; + } + + template + void ImageDifference(cv::Mat &frame, MatrixCollection *collection, Func func_call, int range = 30) { + collection->shiftFrames(frame); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Scalar values; + for(int q = 0; q < collection->size(); ++q) { + cv::Mat &pix_val = collection->frames[q]; + cv::Vec3b pix = pix_val.at(z, i); + for(int j = 0; j < 3; ++j) { + values[j] += pix[j]; + } + } + cv::Vec3b &pixel = frame.at(z, i); + bool found = false; + for(int j = 0; j < 3; ++j) { + values[j] /= collection->size(); + unsigned char val = static_cast(values[j]); + if(pixel[j] > val+range || pixel[j] < val-range) { + found = true; + break; + } + } + if(found == true) { + func_call(pixel); + } + } + } + } + template + void ImageCopyDifference(cv::Mat &frame,cv::Mat &filtered, MatrixCollection *collection, int range = 5) { + if(frame.size() != filtered.size()) + return; + collection->shiftFrames(frame); + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Scalar values; + for(int q = 0; q < collection->size(); ++q) { + cv::Mat &pix_val = collection->frames[q]; + cv::Vec3b pix = pix_val.at(z, i); + for(int j = 0; j < 3; ++j) { + values[j] += pix[j]; + } + } + cv::Vec3b &pixel = frame.at(z, i); + cv::Vec3b copypix = filtered.at(z, i); + bool found = false; + for(int j = 0; j < 3; ++j) { + values[j] /= collection->size(); + unsigned char val = static_cast(values[j]); + if(pixel[j] > val+range || pixel[j] < val-range) { + found = true; + break; + } + } + if(found == true) { + pixel = copypix; + } + } + } + } + + template + void MatrixBlend(cv::Mat &frame, MatrixCollection *collection) { + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + cv::Scalar value; + for(int j = 0; j < collection->size(); ++j) { + cv::Mat &frame1 = collection->frames[j]; + cv::Vec3b pixel = frame1.at(z, i); + for(int q = 0; q < 3; ++q) { + value[q] += pixel[q]; + } + } + cv::Vec3b &pixel = frame.at(z, i); + for(int j = 0; j < 3; ++j) { + int val = 1+static_cast(value[j]); + pixel[j] = static_cast(pixel[j] ^ val); + } + } + } + } + + // bound long values to size of a byte + template + T size_type_cast(const long &val) { + if(val >= 255) return 255; + if(val <= 0) return 0; + return static_cast(val); + } + // point class + class Point { + public: + Point(); + Point(const Point &p); + Point(int xx, int yy); + int x, y; + void setPoint(int xx, int yy); + Point &operator=(const Point &p); + }; + // Rectangle class + class Rect { + public: + Rect(); + Rect(const Rect &r); + Rect(int xx, int yy, int ww, int hh); + Rect(int xx, int yy); + Rect(int xx, int yy, cv::Size s); + Rect(Point pt, int ww, int hh); + Rect(Point pt, cv::Size s); + void setRect(int xx, int yy, int ww, int hh); + Rect &operator=(const Rect &r); + int x,y,w,h; + }; + // classes to be used by the filter + // Square class to hold broken up cv::Mat + class Square { + public: + // constructor init's vars + Square() : pos(0), width(0), height(0), x(0), y(0) {} + // change the size of a square + void setSize(const int &xx, const int &yy, const int &w, const int &h); + // set position + void setPos(const int &p); + // copy image from cv::Mat + void copyImage(const cv::Mat &f); + // copy Image to Target Matrix + void copyImageToTarget(int xx, int yy, cv::Mat &f); + // get position + int getPos() const { return pos; } + // get square width + int getWidth() const { return width; } + // get square height + int getHeight() const { return height; } + protected: + // protected vars + int pos,width,height,x,y; + cv::Mat image; + }; + // Particle movement directions + enum { DIR_UP=0, DIR_UP_LEFT, DIR_UP_RIGHT, DIR_DOWN, DIR_DOWN_LEFT, DIR_DOWN_RIGHT, DIR_LEFT, DIR_RIGHT }; + // contains info for each pixel + class Particle { + public: + Particle() : x(0), y(0), dir(0), m_count(0) {} + cv::Vec3b pixel;// color + int x, y, dir; // position/direction + int m_count; // counter + }; + // class to process the pixel + class ParticleEmiter { + public: + // initalize to null + ParticleEmiter(); + // clean up after done + ~ParticleEmiter(); + // set frame pixel values + void set(cv::Mat &frame); + // draw pixel values to frame + void draw(cv::Mat &frame); + void draw_blend(cv::Mat &frame); + void draw_flash(cv::Mat &frame); + void draw_alpha(cv::Mat &frame); + void draw_move(cv::Mat &frame); + void draw_op(cv::Mat &frame); + + // move pixel coordinates around + void movePixels(); + // reset + void reset(); + private: + Particle **part; // array of pointers for Particles + int w, h; // frame width/height + int speed; + }; + extern int colors[3]; + // class to use for random growing filtered rects. + class Box { + public: + Box() : x(0), y(0), w(0), h(0), steps(0), index(0), frame_index(0) {} + void initBox(int w, int h); + void drawBox(cv::Mat &frame); + void sizeBox(); + int x,y,w,h,steps,index,frame_index; + static int frame_width, frame_height; // current resolution + }; + + class GridBox { + public: + GridBox(); + GridBox(const GridBox &gb); + GridBox(const Rect &r, const cv::Vec3b &col); + GridBox(const cv::Vec3b &col); + Rect location; + cv::Vec3b color; + bool on; + GridBox &operator=(const GridBox &gb); + }; + + class Grid { + public: + GridBox **boxes; + Grid(); + ~Grid(); + void createGrid(cv::Mat &frame, int w, int h, int size); + void updateGrid(int max); + void Release(); + void cleanBoxes(); + void fillGrid(cv::Mat &frame); + int g_w, g_h, g_s; + std::vector points; + std::default_random_engine rng; + int current_offset; + bool g_random; + }; + + class LineObject { + public: + ac::Rect line_size; + cv::Vec3b color; + bool on; + int dir; + }; + + class HLine { + public: + HLine(); + void drawLines(cv::Mat &frame); + void createLines(int size, int width, int height); + void clearLines(); + bool empty() const { return lines.empty(); } + protected: + int w, h; + std::vector lines; + }; + + bool operator<(const Point &p1, const Point &p2); + + // slow copy functions + void copyMat(const cv::Mat &src,int src_x, int src_y, cv::Mat &target, const Rect &rc); + void copyMat(const cv::Mat &src, const Point &p, cv::Mat &target, const Rect &rc); + void copyMat(const cv::Mat &src, int x, int y, cv::Mat &target, int rx, int ry, int rw, int rh); + void copyMat(const cv::Mat &src, const Rect &srcrc, cv::Mat &target, const Rect &dst); + void fillRect(cv::Mat &m, const Rect &r, cv::Vec3b pixel); + + // Transform Template + template + void Transform(const cv::Mat &source, cv::Mat &output, Func func) { + if(output.empty() || output.size() != source.size()) + output.create(source.size(), CV_8UC3); + + for(int z = 0; z < source.rows; ++z) { + for(int i = 0; i < source.cols; ++i) { + cv::Vec3b &pixel = output.at(z, i); + cv::Vec3b value = source.at(z, i); + func(value, i, z); + pixel = value; + swapColors(output, z, i); + if(isNegative) invert(output, z, i); + } + } + } + + template + void transformMat(cv::Mat &src, const Rect &rc,F func) { + for(int z = rc.y; z < rc.y+rc.h && z < src.rows; ++z) { + for(int i = rc.x; i < rc.x+rc.w && i < src.cols; ++i) { + cv::Vec3b &pixel = src.at(z, i); + func(pixel, i, z); + } + } + } + +} + +extern ac::ParticleEmiter emiter; +void changePixel(cv::Mat &full_buffer, int i, int z, cv::Vec3b &buffer, double pos, double *count); + +#endif diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/acidcam.ifp b/windows/Acid.Cam.Qt.Windows.March.2019/acidcam.ifp new file mode 100755 index 0000000000000000000000000000000000000000..0e863486a10c7886b15c6e6ee90d8eb8d702f6e6 GIT binary patch literal 3747 zcmb7H{cqYx8or;A_#a+XI%#{N1ZcXgvU`<`ZHV^>P}?NU!D%(v1I*UgmOW0ITkZdT z&pS2*((3l^m*AOsznsvz zvJgovwk^b-Qn8m1up$+cE%rv=96TJAANt+Fhi<>!x>ISKJ(e`+^?K0hJ@0&;pRWU1 zK%WKQo*&$*Qj7DgXW0+u2k+09e0mZ@pF=oVAI0!A||yLTekP}Ua0hAyH%&?n{6)zB}wu|MM%|4onV(e(nPFfQoA{%pwv$Z+lJ@Q zdGNega^5)xFO8Bamh?}RZ?FYXr0aRX0>-V-Tp_v8JB~CjGEP2glpj|=12q$dFOlb5 zDIZtumR0FU9Z)Y)Roj8f+ecB=exA8}4x~CrqApC_M^$XF!=@6C+u(GfBAG@Kwwo`C zl}NH}Z2(wPRqk*ah(c2ndmVu<*IA~C0aV&}1bp|ajIbhSGP$b7&@86d0lmS&Ofbsk z#45JcUZ%Q)e7of&oCXAjv=kb)m}x6XvPT`&1`h{EM!!qp62;0uawh+1gMA>%X|-RQ zhzD3KgFF%CE{F;#Q#kXQngZsmN@EjEs7wnF5OgA*4*O6xk<~_*!%8JF3~+s5%f4E1 z%XiW8U30V&SVm(1rtbFMn^Nj3@5-+dK`ioEfW-sY+GHO;$GT{@2Fn|~{ic`N zt;^HJyVC`?YwZAO7U{OCy9V+5Rmy3=`SH8qh%*@{NwZoW)R@Y;11=m@@T$QHn4k1B z;)g-^lkR@~@e+wnF9a)PNj*OQOyN1jC)xh=#~OslJFPO=ft19ZRa?Bi~R`%c1W1+N`DXpLA7g5NVh6NhX zq@%=a+bX@Q);!hBnEQ=I*g(5Q%}=;fC6(DmKjMt=jX|g)R6$HSBg`w(J4w0Ba@3RF z2~DLgs_ho5M;Iq=8j+Anl2n#u_uP0hAFdAN@p9BQ()U>vR%>|_d&(+}wF&!lcsJr^ zqH#MP6--a_j!`iv*UZBKBO*mvAH{XO{=V=?L_AZz9HlqS#y8>gzMi8642ncbRmn_& z%EP4Eps6X_5T_V7g+Ml$2!Ywy}m42%tEllqcIk=Lsg$Ep4*m%y^ef z1`n>_wcqRgwJ|k<;}tYWjWA{o z8L1LjN`3~!FFg4*LHeG(q8JTbEJQx^B7A`QWIR1;ZogK zr3O5WdmRoC@j82uuzMf~3Bt|QF$rl*CrGQw^@(#JKaUK#j}n1#UcBJ!+lb)#grh@5 zfE`z$@V^Ar#A6Ea{|t(A#FpbMGMA!ZzOjciULZpm&I{V}ZGj8UlzN>9GZc(6*LRcr z7bwGP4>N8y3hyl6C4A5Q*{$ce4h`=qymrZ+&F_70d>zvDY~r|nK-Sd3?lknh;Ub)2 zY`x;iPp*Qiud*g59g;Vx5f-{TemLGcdVq*C;U-+J{1=rSO@?Df1`x(Zeiy*Dx#H~F6rQ`Xo9WtEfFB{AuzDb9Ixodm; z;eK|(f#u(K8k>RpX#pV|l4IRiV>h55{)7_b#9sLB4aW=~g2gZhy>Jn_G@i{ILv-N! zx1Q|=Khb2y)Q@NpxE**1E#nv_KoyPwY`6$KLz*`YUEg2KLvJ>Hjr`t$7T~s^>KJxs zQ~a1ZnECf?lsPcucj)fgMSUQ})0!!Z$p}ytHs|vw27f4$@B|}G-SNa5yHnfcXl88X z&I{bv$d!l4#%z+^-dXU83V~m)L_}48o>VOOMJCA`k>%XNhI0@`?gOu>6GNGO-O$}M z050>t9N!LZ%I~zLk0%5=<%z#<1-fZnKkS!*%@3PE2~Y<9eaG^ qJ->KfY?%k%|DbmM?%|iIH=6(2#9BXR&FicAJe=6sevi?>NB;qQpqM)V literal 0 HcmV?d00001 diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/chroma_window.cpp b/windows/Acid.Cam.Qt.Windows.March.2019/chroma_window.cpp new file mode 100755 index 0000000..2e80518 --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/chroma_window.cpp @@ -0,0 +1,458 @@ + +#include "chroma_window.h" +#include +#include + +ChromaWindow::ChromaWindow(QWidget *parent) : QDialog(parent) { + setFixedSize(400, 300); + setWindowTitle(tr("Chroma Key")); + setWindowIcon(QPixmap(":/images/icon.png")); + color1_set = false; + color2_set = false; + createControls(); +} + +bool ChromaWindow::checkEdit(QLineEdit *edit) { + QString text = edit->text(); + std::string chk_value; + chk_value = text.toStdString(); + for(unsigned int i = 0; i < chk_value.length(); ++i) { + if(!(chk_value[i] >= '0' && chk_value[i] <= '9')) + return false; + } + return true; +} + +bool ChromaWindow::checkInput(cv::Vec3b &low, cv::Vec3b &high) { + double lo_b, lo_g, lo_r; + double hi_b, hi_g, hi_r; + lo_b = atof(low_b->text().toStdString().c_str()); + lo_g = atof(low_g->text().toStdString().c_str()); + lo_r = atof(low_r->text().toStdString().c_str()); + hi_b = atof(high_b->text().toStdString().c_str()); + hi_g = atof(high_g->text().toStdString().c_str()); + hi_r = atof(high_r->text().toStdString().c_str()); + low[0] = lo_b; + low[1] = lo_g; + low[2] = lo_r; + high[0] = hi_b; + high[1] = hi_g; + high[2] = hi_r; + + if(button_select_range->isChecked() && (lo_b > hi_b || lo_g > hi_g || lo_r > hi_r)) + return false; + + if(lo_b >= 0 && lo_b <= 255 && lo_g >= 0 && lo_g <= 255 && lo_r >= 0 && lo_r <= 255 && hi_b >= 0 && hi_b <= 255 && hi_g >= 0 && hi_g <= 255 && hi_b >= 0 && hi_b <= 255) + return true; + return false; +} + +void ChromaWindow::createControls() { + button_select_range = new QRadioButton(tr("Color Range"), this); + button_select_range->setGeometry(75, 25, 120, 20); + connect(button_select_range, SIGNAL(clicked()), this, SLOT(openColorSelectRange())); + button_select_tolerance = new QRadioButton(tr("Select Color Tolerance"), this); + button_select_tolerance->setGeometry(75+120+10, 25, 150, 20); + connect(button_select_tolerance, SIGNAL(clicked()), this, SLOT(openColorSelectTolerance())); + low_b = new QLineEdit("0", this); + low_g = new QLineEdit("0", this); + low_r = new QLineEdit("0", this); + high_b = new QLineEdit("0", this); + high_g = new QLineEdit("0", this); + high_r = new QLineEdit("0", this); + low_b->setGeometry(95, 65, 50, 20); + low_g->setGeometry(170, 65, 50, 20); + low_r->setGeometry(245, 65, 50, 20); + high_b->setGeometry(95, 90, 50, 20); + high_g->setGeometry(170, 90, 50, 20); + high_r->setGeometry(245, 90, 50, 20); + string_low = new QLabel("BGR Low: ", this); + string_high = new QLabel("BGR High: ", this); + string_low->setGeometry(15, 65, 75, 20); + string_high->setGeometry(15, 90, 75, 20); + button_select_range->setChecked(true); + color_keys = new QListWidget(this); + color_keys->setGeometry(15, 130, 320-30, 100); + color_add = new QPushButton(tr("Add Key"), this); + color_add->setGeometry(320-10, 130, 75, 20); + color_remove = new QPushButton(tr("Remove"), this); + color_remove->setGeometry(320-10, 155, 75, 20); + color_okay = new QPushButton(tr("Set Keys"), this); + color_okay->setGeometry(320-10,210, 75, 20); + + connect(low_b, SIGNAL(textChanged(const QString &)), this, SLOT(editSetLowB(const QString &))); + connect(low_g, SIGNAL(textChanged(const QString &)), this, SLOT(editSetLowG(const QString &))); + connect(low_r, SIGNAL(textChanged(const QString &)), this, SLOT(editSetLowR(const QString &))); + + + connect(high_b, SIGNAL(textChanged(const QString &)), this, SLOT(editSetHighB(const QString &))); + connect(high_g, SIGNAL(textChanged(const QString &)), this, SLOT(editSetHighG(const QString &))); + connect(high_r, SIGNAL(textChanged(const QString &)), this, SLOT(editSetHighR(const QString &))); + + + lowColor = new QLabel("", this); + highColor = new QLabel("", this); + + lowColor->setGeometry(330, 65, 25, 20); + highColor->setGeometry(330, 90, 25, 20); + + lowButton = new QPushButton("Set", this); + lowButton->setGeometry(300, 65, 25, 20); + highButton = new QPushButton("Set", this); + highButton->setGeometry(300, 90, 25, 20); + + select_mode = new QComboBox(this); + select_mode->setGeometry(10, 235, 295, 25); + + select_mode->addItem("Replace with Filter"); + select_mode->addItem("Replace with Image"); + + select_setimage = new QPushButton("Image", this); + select_setimage->setGeometry(15, 265, 60, 20); + + select_image_path = new QLabel("Test Path", this); + select_image_path->setGeometry(85, 265, 400-85-25, 20); + + keys_enabled = new QCheckBox("Enable", this); + keys_enabled->setGeometry(315, 240, 80, 20); + + connect(select_setimage, SIGNAL(clicked()), this, SLOT(setImage())); + connect(color_add, SIGNAL(clicked()), this, SLOT(colorAdd())); + connect(color_remove, SIGNAL(clicked()), this, SLOT(colorRemove())); + connect(color_okay, SIGNAL(clicked()), this, SLOT(colorSet())); + connect(lowButton, SIGNAL(clicked()), this, SLOT(setColorLow())); + connect(highButton, SIGNAL(clicked()), this, SLOT(setColorHigh())); + connect(keys_enabled, SIGNAL(clicked()), this, SLOT(toggleKey())); +} + + +void ChromaWindow::setImage() { + QString fileName = QFileDialog::getOpenFileName(this,tr("Open Image"),".", tr("Image Files (*.png *.jpg *.bmp *.tiff)")); + if(fileName != "") { + color_replace_image = cv::imread(fileName.toStdString()); + if(color_replace_image.empty()) { + QMessageBox::information(this, "Error", "Could not open image file..."); + } else { + select_image_path->setText(fileName); + } + } +} + +void ChromaWindow::openColorSelectRange() { + // set to use range + string_low->setText(tr("BGR Low: ")); + string_high->setText(tr("BGR High:")); + highColor->show(); + highButton->show(); +} + +void ChromaWindow::openColorSelectTolerance() { + // set to use tolerance + string_low->setText(tr("Tolerance -")); + string_high->setText(tr("Tolerance +")); + highColor->hide(); + highButton->hide(); +} + +void ChromaWindow::colorAdd() { + + cv::Vec3b low, high; + QLineEdit *array[] = { low_r, low_g, low_b, high_r, high_g, high_b, 0 }; + for(int i = 0; array[i] != 0; ++i) { + if(checkEdit(array[i])==false) { + QMessageBox::information(this, "Invalid Value", "Values must be between 0-255 no characters"); + return; + } + } + + if(button_select_range->isChecked() == false && color1_set == false) { + QMessageBox::information(this, "Please Set a Color", "Please Select a Color with Set Button"); + return; + } + + if(checkInput(low, high)==false) { + QMessageBox::information(this,"Error ","Error Color Values must be between 0-255 and a valid range"); + return; + } + ac::Keys key_id; + key_id.low = low; + key_id.high = high; + if(button_select_range->isChecked()) { + key_id.key_type = ac::KeyValueType::KEY_RANGE; + } + else { + key_id.key_type = ac::KeyValueType::KEY_TOLERANCE; + int low_color[] = { set_low_color.blue()-low[0], set_low_color.green()-low[1], set_low_color.red()-low[2]}; + for(int i = 0; i < 3; ++i) { + if(low_color[i] < 0) + low_color[i] = 0; + key_id.low[i] = low_color[i]; + } + int high_color[] = { set_low_color.blue()+high[0], set_low_color.green()+high[1], set_low_color.red()+high[2]}; + for(int i = 0; i < 3; ++i) { + if(high_color[i] > 255) + high_color[i] = 255; + key_id.high[i] = high_color[i]; + } + low = key_id.low; + high = key_id.high; + } + colorkeys_vec.push_back(key_id); + QString text; + QTextStream stream(&text); + QString type_key = ((key_id.key_type == ac::KeyValueType::KEY_RANGE) ? "Range" : "Tolerance"); + + stream << "Added Chroma Key " << type_key << "\n" << colorkeys_vec.size() << " Keys set.\n"; + QMessageBox::information(this, "Key Added", text); + text = ""; + stream << type_key << " BGR(" << low[0] << "," << low[1] << "," << low[2] << ") - BGR(" << high[0] << "," << high[1] << "," << high[2] << ")\n"; + color_keys->addItem(text); +} +void ChromaWindow::colorRemove() { + int index = color_keys->currentRow(); + if(index >= 0) { + /*QListWidgetItem *i = */color_keys->takeItem(index); + auto in = colorkeys_vec.begin()+index; + if(!colorkeys_vec.empty()) { + colorkeys_vec.erase(in); + } + } +} +void ChromaWindow::colorSet() { + QString text; + QTextStream stream(&text); + stream << "Set " << colorkeys_vec.size() << " Chroma Keys.\n"; + QMessageBox::information(this, "Set Key Values", text); + ac::setBlockedColorKeys(colorkeys_vec); +} + +void ChromaWindow::setEditFromColor(int val, QColor color) { + if(val == 0) { + QString text; + QTextStream stream(&text); + stream << color.blue(); + low_b->setText(text); + text = ""; + stream << color.green(); + low_g->setText(text); + text = ""; + stream << color.red(); + low_r->setText(text); + text = ""; + } else if(val == 1) { + QString text; + QTextStream stream(&text); + stream << color.blue(); + high_b->setText(text); + text = ""; + stream << color.green(); + high_g->setText(text); + text = ""; + stream << color.red(); + high_r->setText(text); + text = ""; + } +} + +void ChromaWindow::setColorLow() { + QColorDialog *dialog = new QColorDialog(this); + QColor color= dialog->getColor(); + QVariant variant = color; + QString color_var = variant.toString(); + set_low_color = color; + lowColor->setStyleSheet("QLabel { background-color :" + color_var + " ; }"); + lowColor->setText(""); + color1_set = true; + if(button_select_range->isChecked()) { + setEditFromColor(0, color); + } +} + +void ChromaWindow::setColorHigh() { + QColorDialog *dialog = new QColorDialog(this); + QColor color = dialog->getColor(); + QVariant variant = color; + QString color_var = variant.toString(); + set_high_color = color; + highColor->setStyleSheet("QLabel { background-color :" + color_var + " ;}"); + highColor->setText(""); + color2_set = false; + if(button_select_range->isChecked()) { + setEditFromColor(1, color); + } +} + +void ChromaWindow::enableKey(bool op) { + if(op) { + if(colorkeys_vec.size()==0) { + QMessageBox::information(this, "Needs a Key", "Please set a key to enable this feature"); + keys_enabled->setChecked(false); + return; + } + + int row = select_mode->currentIndex(); + if(row >= 0) { + QString keys_text; + QTextStream stream(&keys_text); + switch(row) { + case 0: + colorkey_filter = true; + colorkey_set = false; + colorkey_bg = false; + colorkey_replace = false; + stream << "Enabled " << colorkeys_vec.size() << " keys in filter mode"; + QMessageBox::information(this, "Enabled Keys", keys_text); + break; + case 1: + if(color_replace_image.empty()) { + QMessageBox::information(this, "Need to Set Image", "Please Select a image to replace key with"); + return; + } + colorkey_filter = false; + colorkey_set = false; + colorkey_bg = false; + colorkey_replace = true; + stream << "Enabled Key replace with: " << select_image_path->text() << "\n"; + QMessageBox::information(this, "Key Replaced", keys_text); + break; + } + } + } else { + colorkey_filter = false; + colorkey_set = false; + colorkey_bg = false; + colorkey_replace = false; + } +} + +void ChromaWindow::toggleKey() { + if(keys_enabled->isChecked()) { + enableKey(true); + } else { + enableKey(false); + } +} + +void ChromaWindow::editSetLowB(const QString &text) { + if(button_select_range->isChecked()==false) + return; + + cv::Vec3b low; + double lo_b, lo_g, lo_r; + lo_b = atof(text.toStdString().c_str()); + lo_g = atof(low_g->text().toStdString().c_str()); + lo_r = atof(low_r->text().toStdString().c_str()); + low[0] = cv::saturate_cast(lo_b); + low[1] = cv::saturate_cast(lo_g); + low[2] = cv::saturate_cast(lo_r); + QColor color_value(low[2], low[1], low[0]); + QVariant variant = color_value; + QString color_var = variant.toString(); + set_low_color = color_value; + lowColor->setStyleSheet("QLabel { background-color :" + color_var + " ; }"); + lowColor->setText(""); + color1_set = true; +} + +void ChromaWindow::editSetLowG(const QString &text) { + if(button_select_range->isChecked()==false) + return; + + cv::Vec3b low; + double lo_b, lo_g, lo_r; + lo_b = atof(low_b->text().toStdString().c_str()); + lo_g = atof(text.toStdString().c_str()); + lo_r = atof(low_r->text().toStdString().c_str()); + low[0] = cv::saturate_cast(lo_b); + low[1] = cv::saturate_cast(lo_g); + low[2] = cv::saturate_cast(lo_r); + QColor color_value(low[2], low[1], low[0]); + QVariant variant = color_value; + QString color_var = variant.toString(); + set_low_color = color_value; + lowColor->setStyleSheet("QLabel { background-color :" + color_var + " ; }"); + lowColor->setText(""); + color1_set = true; +} +void ChromaWindow::editSetLowR(const QString &text) { + if(button_select_range->isChecked()==false) + return; + + cv::Vec3b low; + double lo_b, lo_g, lo_r; + lo_b = atof(low_b->text().toStdString().c_str()); + lo_g = atof(low_g->text().toStdString().c_str()); + lo_r = atof(text.toStdString().c_str()); + low[0] = cv::saturate_cast(lo_b); + low[1] = cv::saturate_cast(lo_g); + low[2] = cv::saturate_cast(lo_r); + QColor color_value(low[2], low[1], low[0]); + QVariant variant = color_value; + QString color_var = variant.toString(); + set_low_color = color_value; + lowColor->setStyleSheet("QLabel { background-color :" + color_var + " ; }"); + lowColor->setText(""); + color1_set = true; +} + +void ChromaWindow::editSetHighB(const QString &text) { + if(button_select_range->isChecked()==false) + return; + + cv::Vec3b low; + double lo_b, lo_g, lo_r; + lo_b = atof(text.toStdString().c_str()); + lo_g = atof(high_g->text().toStdString().c_str()); + lo_r = atof(high_r->text().toStdString().c_str()); + low[0] = cv::saturate_cast(lo_b); + low[1] = cv::saturate_cast(lo_g); + low[2] = cv::saturate_cast(lo_r); + QColor color_value(low[2], low[1], low[0]); + QVariant variant = color_value; + QString color_var = variant.toString(); + set_high_color = color_value; + highColor->setStyleSheet("QLabel { background-color :" + color_var + " ; }"); + highColor->setText(""); + color2_set = true; +} +void ChromaWindow::editSetHighG(const QString &text) { + if(button_select_range->isChecked()==false) + return; + + cv::Vec3b low; + double lo_b, lo_g, lo_r; + lo_b = atof(high_b->text().toStdString().c_str()); + lo_g = atof(text.toStdString().c_str()); + lo_r = atof(high_r->text().toStdString().c_str()); + low[0] = cv::saturate_cast(lo_b); + low[1] = cv::saturate_cast(lo_g); + low[2] = cv::saturate_cast(lo_r); + QColor color_value(low[2], low[1], low[0]); + QVariant variant = color_value; + QString color_var = variant.toString(); + set_high_color = color_value; + highColor->setStyleSheet("QLabel { background-color :" + color_var + " ; }"); + highColor->setText(""); + color2_set = true; +} +void ChromaWindow::editSetHighR(const QString &text) { + if(button_select_range->isChecked()==false) + return; + + cv::Vec3b low; + double lo_b, lo_g, lo_r; + lo_b = atof(high_b->text().toStdString().c_str()); + lo_g = atof(high_g->text().toStdString().c_str()); + lo_r = atof(text.toStdString().c_str()); + low[0] = cv::saturate_cast(lo_b); + low[1] = cv::saturate_cast(lo_g); + low[2] = cv::saturate_cast(lo_r); + QColor color_value(low[2], low[1], low[0]); + QVariant variant = color_value; + QString color_var = variant.toString(); + set_high_color = color_value; + highColor->setStyleSheet("QLabel { background-color :" + color_var + " ; }"); + highColor->setText(""); + color2_set = true; +} + diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/chroma_window.h b/windows/Acid.Cam.Qt.Windows.March.2019/chroma_window.h new file mode 100755 index 0000000..79c993b --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/chroma_window.h @@ -0,0 +1,51 @@ +#ifndef __CHROMAKEY__H_ +#define __CHROMAKEY__H_ + +#include "qtheaders.h" + + +class ChromaWindow : public QDialog { + Q_OBJECT +public: + ChromaWindow(QWidget *parent); + bool checkInput(cv::Vec3b &low, cv::Vec3b &high); + bool checkEdit(QLineEdit *edit); + void setEditFromColor(int val, QColor color); + void enableKey(bool op); +public slots: + void openColorSelectRange(); + void openColorSelectTolerance(); + void colorAdd(); + void colorRemove(); + void colorSet(); + void setColorLow(); + void setColorHigh(); + void setImage(); + void toggleKey(); + void editSetLowB(const QString &text); + void editSetLowG(const QString &text); + void editSetLowR(const QString &text); + void editSetHighB(const QString &text); + void editSetHighG(const QString &text); + void editSetHighR(const QString &text); +private: + void createControls(); + QRadioButton *button_select_range, *button_select_tolerance; + QLineEdit *low_b, *low_g, *low_r, *high_b, *high_g, *high_r; + QLabel *string_low, *string_high; + QListWidget *color_keys; + QPushButton *color_add, *color_remove, *color_okay; + QLabel *lowColor, *highColor; + std::vector colorkeys_vec; + QPushButton *lowButton, *highButton; + QColor set_low_color, set_high_color; + QComboBox *select_mode; + QPushButton *select_setimage; + QLabel *select_image_path; + QCheckBox *keys_enabled; + bool color1_set, color2_set; +}; + + +#endif + diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/display_window.cpp b/windows/Acid.Cam.Qt.Windows.March.2019/display_window.cpp new file mode 100755 index 0000000..cbd4715 --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/display_window.cpp @@ -0,0 +1,42 @@ + +/* + * Acid Cam v2 - Qt/OpenCV Edition + * written by Jared Bruni ( http://lostsidedead.com ) + * (C) 2017 GPL + */ + +#include"display_window.h" + +DisplayWindow::DisplayWindow(QWidget *parent) : QDialog(parent) { + createControls(); + setGeometry(950, 200, 640, 480); + setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::CustomizeWindowHint | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint); + setWindowTitle(tr("Acid Cam v2 - Display Window")); + hide(); +} +void DisplayWindow::createControls() { + img_label = new QLabel(this); + img_label->setGeometry(0,0,640, 480); +} +void DisplayWindow::displayImage(const QImage &img) { + QRect src(QPoint(0, 0), size()); + QPixmap p = QPixmap::fromImage(img).scaled(size(),Qt::KeepAspectRatio, Qt::FastTransformation); + QRect dst(QPoint(0,0),p.size()); + dst.moveCenter(src.center()); + img_label->setGeometry(dst); + img_label->setPixmap(p); +} + + +void DisplayWindow::paintEvent(QPaintEvent *) { + QPainter painter(this); + painter.fillRect(QRect(QPoint(0, 0), size()), QColor(0,0,0)); +} + +void DisplayWindow::keyPressEvent(QKeyEvent *) { + +} + +void DisplayWindow::keyReleaseEvent(QKeyEvent *) { + +} diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/display_window.h b/windows/Acid.Cam.Qt.Windows.March.2019/display_window.h new file mode 100755 index 0000000..ace1252 --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/display_window.h @@ -0,0 +1,26 @@ +/* + * Acid Cam v2 - Qt/OpenCV Edition + * written by Jared Bruni ( http://lostsidedead.com ) + * (C) 2017 GPL + */ + + +#ifndef __DISPLAY_WINDOW_H__ +#define __DISPLAY_WINDOW_H__ + +#include"qtheaders.h" + +class DisplayWindow : public QDialog { + Q_OBJECT +public: + DisplayWindow(QWidget *parent = 0); + void createControls(); + void displayImage(const QImage &img); + void paintEvent(QPaintEvent *paint); + void keyPressEvent(QKeyEvent *ke); + void keyReleaseEvent(QKeyEvent *ke); +private: + QLabel *img_label; +}; + +#endif diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/fractal.cpp b/windows/Acid.Cam.Qt.Windows.March.2019/fractal.cpp new file mode 100755 index 0000000..38f4e96 --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/fractal.cpp @@ -0,0 +1,157 @@ +/* + * Software written by Jared Bruni https://github.com/lostjared + + This software is dedicated to all the people that experience mental illness. + + Website: http://lostsidedead.com + YouTube: http://youtube.com/LostSideDead + Instagram: http://instagram.com/jaredbruni + Twitter: http://twitter.com/jaredbruni + Facebook: http://facebook.com/LostSideDead0x + + You can use this program free of charge and redistrubute it online as long + as you do not charge anything for this program. This program is meant to be + 100% free. + + BSD 2-Clause License + + Copyright (c) 2019, Jared Bruni + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + */ + +#include "fractal.h" + +namespace frac { + double paramA = -1.0;//0.519; + double paramB = 0.2; + float zoom_x = 1.5, zoom_y = 1.5, zoom_w = 0.5, zoom_h = 0.5; + double red_color = 6; + double green_color = 25; + double blue_color = 50; + float mod_x = 0.5; + float mod_y = 0.5; + float radius = 180.0f; + int dir = 1; + long max_iter = 40; +} + +void frac::FractalLogic() { + static double alpha_r = 1.0; + alpha_r += 0.05; + red_color += alpha_r; + green_color += alpha_r; + blue_color += alpha_r; + if(alpha_r > 255) alpha_r = 1.0; + if(red_color > 255) red_color = rand()%255; + if(green_color > 255) green_color = rand()%255; + if(blue_color > 255) blue_color = rand()%255; + + switch(dir) { + case 1: { + paramA += 0.005; + if(paramA >= 1.0) { + dir = 2; + paramB += 0.05; + if(paramB >= 1.0) { + dir = 3; + + } + } + } + break; + case 2: { + paramA -= 0.005; + if(paramA <= -1) { + paramB += 0.05; + dir = 1; + if(paramB >= 1.0) { + dir = 4; + } + } + } + break; + case 3: { + paramB -= 0.005; + if(paramB <= -1.0) { + dir = 3; + paramA -= 0.05; + if(paramA <= -1) { + dir = 1; + } + } + + } + break; + case 4: { + paramB += 0.005; + if(paramB >= 1) { + paramA += 0.05; + dir = 3; + if(paramA >= 1) { + dir = 2; + } + + } + } + + break; + } + // std::cout << paramA << ": " << paramB << " :" << " dir: " << dir << "\n"; +} + +void frac::DrawFractal(cv::Mat &frame, bool) +{ + float x1=mod_x-1.0f*zoom_x; + float x2=mod_x+1.0f*zoom_w; + float y1=mod_y-1.0f*zoom_y; + float y2=mod_y+1.0f*zoom_h; + int width=frame.cols, height=frame.rows; + std::complex C (paramA, paramB); + std::complex Z; + int i = 0; + for (int x = 0; x < width; ++x) + { + for (int y = 0; y < height; ++y) + { + //C=std::complex((double)(x*(x2-x1)/width+x1), (double)(y*(y2-y1)/height+y1)); + Z=std::complex((double)(x*(x2-x1)/width+x1), (double)(y*(y2-y1)/height+y1)); + //Z=std::complex(0, 0); + for (i = 0; i < max_iter && std::abs(Z) < 2; i++) + { + Z=Z*Z+C; + } + cv::Vec3b &cf = frame.at(y, x); + if(i == max_iter) { + + } else { + cf[2] += static_cast(sin(i*red_color/100)*255); + cf[1] += static_cast(sin(i*green_color/100)*255); + cf[0] += static_cast(sin(i*blue_color/100)*255); + } + } + if(x > frame.size().width) break; + } +} + diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/fractal.h b/windows/Acid.Cam.Qt.Windows.March.2019/fractal.h new file mode 100755 index 0000000..534c90a --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/fractal.h @@ -0,0 +1,61 @@ +/* + * Software written by Jared Bruni https://github.com/lostjared + + This software is dedicated to all the people that experience mental illness. + + Website: http://lostsidedead.com + YouTube: http://youtube.com/LostSideDead + Instagram: http://instagram.com/jaredbruni + Twitter: http://twitter.com/jaredbruni + Facebook: http://facebook.com/LostSideDead0x + + You can use this program free of charge and redistrubute it online as long + as you do not charge anything for this program. This program is meant to be + 100% free. + + BSD 2-Clause License + + Copyright (c) 2019, Jared Bruni + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + */ + +#ifndef __FRACTAL__H_ +#define __FRACTAL__H_ +#include +#include +#include + +namespace frac { + extern double paramA,paramB; + extern float radius; + extern float zoom_x, zoom_y, zoom_w, zoom_h; + extern long max_iter; + extern double red_color, green_color, blue_color; + void FractalLogic(); + void DrawFractal(cv::Mat &frame, bool neg=false); +} + +#endif + diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/goto_window.cpp b/windows/Acid.Cam.Qt.Windows.March.2019/goto_window.cpp new file mode 100755 index 0000000..101ae83 --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/goto_window.cpp @@ -0,0 +1,98 @@ +#include "goto_window.h" +#include "main_window.h" + + +GotoWindow::GotoWindow(QWidget *parent) : QDialog(parent) { + createControls(); + setFixedSize(400, 70); + setWindowTitle(tr("Jump to Frame")); + setGeometry(300, 50, 400, 70); +} + +void GotoWindow::setPlayback(Playback *playback) { + playback_thread = playback; +} + +void GotoWindow::setVideoCapture(cv::VideoCapture *cap) { + capture_device = cap; +} +void GotoWindow::setDisplayWindow(DisplayWindow *win) { + disp_window = win; +} + +void GotoWindow::createControls() { + goto_pos = new QSlider(Qt::Horizontal, this); + goto_pos->setGeometry(10, 10, 380, 20); + goto_pos->setMaximum(1); + goto_pos->setMinimum(0); + goto_pos->setTickInterval(0); + + QLabel *lbl_sec = new QLabel(tr("Second: "), this); + QLabel *lbl_frame = new QLabel(tr("Frame: "), this); + lbl_sec->setGeometry(10, 30, 50, 20); + lbl_frame->setGeometry(180, 30, 50, 20); + goto_sec = new QLineEdit("0", this); + goto_sec->setGeometry(70,30,100, 20); + goto_frame = new QLineEdit("0", this); + goto_frame->setGeometry(230,30,100,20); + goto_jump = new QPushButton("Go", this); + goto_jump->setGeometry(340, 30, 45, 20); + + connect(goto_jump, SIGNAL(clicked()), this, SLOT(pressedGo())); + connect(goto_pos, SIGNAL(valueChanged(int)), this, SLOT(slideChanged(int))); + +} + +void GotoWindow::setFrameIndex(int i) { + if(i < goto_pos->minimum() || i > goto_pos->maximum()) { + QMessageBox::information(this, tr("Error"), tr("Index out of range")); + return; + } + frame_index = i; + QString frame_string; + QTextStream frame_stream(&frame_string); + frame_stream << "(Current/Total Frames/Seconds) - (" << frame_index << "/" << goto_pos->maximum() << "/" << (unsigned long)(goto_pos->minimum()/goto_pos->maximum()) << ") "; + main_window->setFrameIndex(frame_index); + main_window->statusBar()->showMessage(frame_string); +} + +void GotoWindow::setMainWindow(AC_MainWindow *window) { + main_window = window; +} + +void GotoWindow::showImage() { + QImage img; + if(playback_thread->getFrame(img, frame_index)) { + disp_window->displayImage(img); + } +} + +void GotoWindow::showWindow(int frame_index, int min, int max) { + goto_pos->setMaximum(min); + goto_pos->setMaximum(max); + goto_pos->setSliderPosition(frame_index); + slideChanged(frame_index); + show(); + pressedGo(); +} + +void GotoWindow::pressedGo() { + QString fpos = goto_frame->text(); + int f_pos = atoi(fpos.toStdString().c_str()); + if(f_pos != goto_pos->sliderPosition()) { + goto_pos->setSliderPosition(f_pos); + } + setFrameIndex(f_pos); + showImage(); +} + +void GotoWindow::slideChanged(int pos) { + QString text; + QTextStream stream(&text); + stream << static_cast(pos/ac::fps); + goto_sec->setText(text); + text = ""; + stream << (pos); + goto_frame->setText(text); + +} diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/goto_window.h b/windows/Acid.Cam.Qt.Windows.March.2019/goto_window.h new file mode 100755 index 0000000..47b6bec --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/goto_window.h @@ -0,0 +1,38 @@ +#ifndef __GOTO_WINDOW__H_ +#define __GOTO_WINDOW__H_ + +#include "qtheaders.h" +#include "display_window.h" +#include "playback_thread.h" + +class AC_MainWindow; + +class GotoWindow : public QDialog { + Q_OBJECT +public: + GotoWindow(QWidget *parent); + void setVideoCapture(cv::VideoCapture *cap); + void setDisplayWindow(DisplayWindow *win); + void setMainWindow(AC_MainWindow *window); + void setPlayback(Playback *playb); + void createControls(); + void setFrameIndex(int index); + void showImage(); + void showWindow(int frame_index, int min, int max); +private: + int frame_index; + DisplayWindow *disp_window; + AC_MainWindow *main_window; + cv::VideoCapture *capture_device; + QSlider *goto_pos; + QLineEdit *goto_sec, *goto_frame; + QPushButton *goto_jump; + Playback *playback_thread; + public slots: + void pressedGo(); + void slideChanged(int pos); + +}; + +#endif + diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/main.cpp b/windows/Acid.Cam.Qt.Windows.March.2019/main.cpp new file mode 100755 index 0000000..1b9aaca --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/main.cpp @@ -0,0 +1,29 @@ +/* + * Acid Cam v2 - Qt/OpenCV Edition + * written by Jared Bruni ( http://lostsidedead.com ) + * (C) 2017 GPL + */ + + +//#define LINUX_RELEASE + +#include"qtheaders.h" +#include "main_window.h" +#ifdef LINUX_RELEASE +#include +#endif + +int main(int argc, char **argv) { + +#ifdef LINUX_RELEASE + if(chdir("/usr/share/acidcam") == 0) { + std::cout << "Changed directory to: /usr/share/acidcam\n"; + } +#endif + + QApplication app(argc, argv); + AC_MainWindow window; + window.show(); + return app.exec(); + +} diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/main_window.cpp b/windows/Acid.Cam.Qt.Windows.March.2019/main_window.cpp new file mode 100755 index 0000000..72b3c50 --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/main_window.cpp @@ -0,0 +1,1556 @@ +/* + * Acid Cam v2 - Qt/OpenCV Edition + * written by Jared Bruni ( http://lostsidedead.com ) + * (C) 2017 GPL + */ + + +#include "main_window.h" +#include +#include"plugin.h" +#include + +std::unordered_map filter_map; +void custom_filter(cv::Mat &); + +const char *filter_names[] = { "AC Self AlphaBlend", "Reverse Self AlphaBlend", + "Opposite Self AlphaBlend", "AC2 Distort", "Reverse Distort", "Opposite Distort", + "Full Distort", "A New One", "AC NewOne", "AC Thought Filter", "Line Draw", + "Gradient Square", "Color Wave", "Pixelated Gradient", "Combined Gradient", + "Diagonal", "Average", "Average Divide", "Cos/Sin Multiply", "Modulus Multiply", + "Positive/Negative", "z+1 Blend", "Diamond Pattern", "Pixelated Shift","Pixelated Mix", + "Color Accumulate", "Color Accumulate #2", "Color Accumulate #3", "Angle", + "Vertical Average", "Circular Blend", "Average Blend", "~Divide", "Mix", "Random Number", + "Gradient Repeat", 0 }; + + +const char *menuNames[] = {"All Filters", "All Filters Sorted", "Blend", "Distort", "Pattern", "Gradient", "Mirror", "Strobe", "Blur", "Image", "Square", "Other", "SubFilter", "Special", "User", 0}; + + +void generate_map() { + for(int i = 0; i < ac::draw_max; ++i ) + filter_map[ac::draw_strings[i]] = FilterValue(0, i, -1); + + + int index = 0; + while(filter_names[index] != 0) { + std::string filter_n = "AF_"; + filter_n += filter_names[index]; + filter_map[filter_n] = FilterValue(1, index, -1); + ++index; + ac::filter_menu_map["All Filters"].menu_list->push_back(filter_n); + } + for(unsigned int j = 0; j < plugins.plugin_list.size(); ++j) { + std::string name = "plugin " + plugins.plugin_list[j]->name(); + filter_map[name] = FilterValue(2, j, -1); + } + +} + +void custom_filter(cv::Mat &) { + +} + + +AC_MainWindow::~AC_MainWindow() { + controls_Stop(); + delete playback; +} + +AC_MainWindow::AC_MainWindow(QWidget *parent) : QMainWindow(parent) { + programMode = MODE_CAMERA; + init_plugins(); + ac::init_filter_menu_map(); + generate_map(); + ac::SortFilters(); + ac::filter_menu_map["User"].menu_list->push_back("No Filter"); + setGeometry(100, 100, 800, 700); + setFixedSize(800, 700); + setWindowTitle(tr("Acid Cam v2 - Qt")); + createControls(); + createMenu(); + speed_index = 0; + loading = false; + + cap_camera = new CaptureCamera(this); + cap_camera->setParent(this); + + cap_video = new CaptureVideo(this); + cap_video->setParent(this); + + search_box = new SearchWindow(this); + search_box->setParent(this); + search_box->setFiltersControl(filters, custom_filters); + search_box->main_window = this; + statusBar()->showMessage(tr("Acid Cam v2 Loaded - Use File Menu to Start")); + take_snapshot = false; + goto_window = new GotoWindow(this); + disp = new DisplayWindow(this); + playback = new Playback(); + + goto_window->setParent(this); + goto_window->setDisplayWindow(disp); + goto_window->setPlayback(playback); + goto_window->setMainWindow(this); + + QObject::connect(playback, SIGNAL(procImage(QImage)), this, SLOT(updateFrame(QImage))); + QObject::connect(playback, SIGNAL(stopRecording()), this, SLOT(stopRecording())); + QObject::connect(playback, SIGNAL(frameIncrement()), this, SLOT(frameInc())); + QObject::connect(playback, SIGNAL(resetIndex()), this, SLOT(resetIndex())); + + for(unsigned int i = 0; i < plugins.plugin_list.size(); ++i) { + QString text; + QTextStream stream(&text); + stream << "Loaded Plugin: " << plugins.plugin_list[i]->name().c_str() << "\n"; + Log(text); + } + + int cindex = filters->findText("Self AlphaBlend"); + filters->setCurrentIndex(cindex); + chroma_window = new ChromaWindow(this); + chroma_window->hide(); + define_window = new DefineWindow(this); + define_window->hide(); + define_window->main_window = this; +} + + +void AC_MainWindow::createControls() { + custom_filters = new QListWidget(this); + custom_filters->setGeometry(400, 30, 390, 180); + custom_filters->show(); + menu_cat = new QComboBox(this); + menu_cat->setGeometry(10, 90, 380, 30); + for(int i = 0; menuNames[i] != 0; ++i) { + menu_cat->addItem(menuNames[i]); + } + menu_cat->setCurrentIndex(0); + + filters = new QComboBox(this); + filters->setGeometry(10, 120, 380, 30); + + std::vector fnames; + for(int i = 0; i < ac::draw_max-5; ++i) { + fnames.push_back(ac::draw_strings[i].c_str()); + } + + std::sort(fnames.begin(), fnames.end()); + + for(unsigned long i = 0; i < fnames.size(); ++i) { + filters->addItem(fnames[i].c_str()); + } + + for(int i = 0; filter_names[i] != 0; ++i) { + std::string filter_n = "AF_"; + filter_n += filter_names[i]; + filters->addItem(filter_n.c_str()); + } + + for(unsigned int i = 0; i < plugins.plugin_list.size(); ++i) { + std::string name = "plugin " + plugins.plugin_list[i]->name(); + filters->addItem(name.c_str()); + } + + connect(filters, SIGNAL(currentIndexChanged(int)), this, SLOT(comboFilterChanged(int))); + connect(menu_cat, SIGNAL(currentIndexChanged(int)), this, SLOT(menuFilterChanged(int))); + + + filter_single = new QRadioButton(tr("Single Filter"), this); + filter_single->setGeometry(30, 40, 100, 15); + filter_custom = new QRadioButton(tr("Custom Filter"), this); + filter_custom->setGeometry(30, 65, 100, 15); + + filter_single->setChecked(true); + + connect(filter_single, SIGNAL(pressed()), this, SLOT(setFilterSingle())); + connect(filter_custom, SIGNAL(pressed()), this, SLOT(setFilterCustom())); + + btn_add = new QPushButton(tr("Add"), this); + btn_remove = new QPushButton(tr("Remove"), this); + btn_moveup = new QPushButton(tr("Up"), this); + btn_movedown = new QPushButton(tr("Down"), this); + btn_sub = new QPushButton(tr("Subfilter"), this); + btn_clr = new QPushButton(tr("Clear Sub"), this); + btn_load = new QPushButton(tr("Load"), this); + btn_save = new QPushButton(tr("Save"), this); + btn_add->setGeometry(10, 215, 100, 20); + btn_remove->setGeometry(400, 215, 60, 20); + btn_moveup->setGeometry(465, 215, 60, 20); + btn_movedown->setGeometry(530, 215, 60, 20); + btn_load->setGeometry(655+20, 215, 55, 20); + btn_save->setGeometry(655+60+20, 215, 55, 20); + btn_sub->setGeometry(10, 165, 100, 20); + btn_clr->setGeometry(115, 165, 100, 20); + connect(btn_add, SIGNAL(clicked()), this, SLOT(addClicked())); + connect(btn_remove, SIGNAL(clicked()), this, SLOT(rmvClicked())); + connect(btn_moveup, SIGNAL(clicked()), this, SLOT(upClicked())); + connect(btn_movedown, SIGNAL(clicked()), this, SLOT(downClicked())); + connect(btn_sub, SIGNAL(clicked()), this, SLOT(setSub())); + connect(btn_clr, SIGNAL(clicked()), this, SLOT(clear_subfilter())); + connect(btn_load, SIGNAL(clicked()), this, SLOT(load_CustomFile())); + connect(btn_save, SIGNAL(clicked()), this, SLOT(save_CustomFile())); + QLabel *r_label = new QLabel(tr("Red: "), this); + r_label->setGeometry(10, 255, 50, 20); + slide_r = new QSlider(Qt::Horizontal,this); + slide_r->setGeometry(40, 250, 100, 30); + slide_r->setMaximum(255); + slide_r->setMinimum(0); + slide_r->setTickInterval(0); + + QLabel *g_label = new QLabel(tr("Green: "), this); + g_label->setGeometry(150, 255, 50, 20); + slide_g = new QSlider(Qt::Horizontal, this); + slide_g->setGeometry(190, 250, 100, 30); + slide_g->setMaximum(255); + slide_g->setMinimum(0); + slide_g->setTickInterval(0); + + QLabel *b_label = new QLabel(tr("Blue: "), this); + b_label->setGeometry(300, 255, 50, 20); + slide_b = new QSlider(Qt::Horizontal, this); + slide_b->setGeometry(330, 250, 100, 30); + slide_b->setMaximum(255); + slide_b->setMinimum(0); + slide_b->setTickInterval(0); + + connect(slide_r, SIGNAL(valueChanged(int)), this, SLOT(slideChanged(int))); + connect(slide_g, SIGNAL(valueChanged(int)), this, SLOT(slideChanged(int))); + connect(slide_b, SIGNAL(valueChanged(int)), this, SLOT(slideChanged(int))); + + QLabel *label_slide_bright = new QLabel(tr("Brightness: "), this); + label_slide_bright->setGeometry(10, 280, 75, 20); + slide_bright = new QSlider(Qt::Horizontal, this); + slide_bright->setGeometry(80, 275, 100, 30); + slide_bright->setMaximum(255); + slide_bright->setMinimum(0); + slide_bright->setTickInterval(0); + + + QLabel *label_slide_gamma = new QLabel(tr("Gamma: "), this); + label_slide_gamma->setGeometry(190, 280, 65, 20); + slide_gamma = new QSlider(Qt::Horizontal, this); + slide_gamma->setGeometry(245, 275, 100, 30); + slide_gamma->setMaximum(255); + slide_gamma->setMinimum(0); + slide_gamma->setTickInterval(0); + + QLabel *label_sat = new QLabel(tr("Saturation: "), this); + label_sat->setGeometry(350, 280, 100, 20); + slide_saturation = new QSlider(Qt::Horizontal, this); + slide_saturation->setGeometry(420, 275, 100, 30); + slide_saturation->setMaximum(255); + slide_saturation->setMinimum(0); + slide_saturation->setTickInterval(0); + + connect(slide_bright, SIGNAL(valueChanged(int)), this, SLOT(colorChanged(int))); + connect(slide_gamma, SIGNAL(valueChanged(int)), this, SLOT(colorChanged(int))); + connect(slide_saturation, SIGNAL(valueChanged(int)), this, SLOT(colorChanged(int))); + + QLabel *color_maps_label = new QLabel("Color Maps", this); + color_maps_label->setGeometry(545, 260, 75, 20); + + color_maps = new QComboBox(this); + color_maps->setGeometry(540, 275, 250, 30); + color_maps->addItem(tr("None")); + color_maps->addItem(tr("Autum")); + color_maps->addItem(tr("Bone")); + color_maps->addItem(tr("Jet")); + color_maps->addItem(tr("Winter")); + color_maps->addItem(tr("Rainbow")); + color_maps->addItem(tr("Ocean")); + color_maps->addItem(tr("Summer")); + color_maps->addItem(tr("Cool")); + color_maps->addItem(tr("HSV")); + color_maps->addItem(tr("Pink")); + color_maps->addItem(tr("Hot")); + color_maps->addItem(tr("Parula")); + + connect(color_maps, SIGNAL(currentIndexChanged(int)), this, SLOT(colorMapChanged(int))); + + log_text = new QTextEdit(this); + log_text->setGeometry(10, 325, 780,310); + log_text->setReadOnly(true); + + QString text; + QTextStream stream(&text); + stream << tr("Acid Cam Filters v"); + stream << ac::version.c_str(); + stream << " loaded " << filters->count() << " filters.\n"; + log_text->setText(text); + chk_negate = new QCheckBox(tr("Negate"), this); + chk_negate->setGeometry(120,215,100, 20); + chk_negate->setCheckState(Qt::Unchecked); + use_settings = new QCheckBox(tr("Settings"), this); + use_settings->setCheckState(Qt::Checked); + use_settings->setGeometry(605, 215,80, 20); + connect(chk_negate, SIGNAL(clicked()), this, SLOT(chk_Clicked())); + + combo_rgb = new QComboBox(this); + combo_rgb->setGeometry(200,215, 190, 25); + combo_rgb->addItem(tr("RGB")); + combo_rgb->addItem(tr("BGR")); + combo_rgb->addItem(tr("BRG")); + combo_rgb->addItem(tr("GRB")); + setWindowIcon(QPixmap(":/images/icon.png")); + progress_bar = new QProgressBar(this); + progress_bar->setGeometry(0, 640, 800, 20); + progress_bar->setMinimum(0); + progress_bar->setMaximum(100); + progress_bar->hide(); + menu_cat->setCurrentIndex(1); +} + +void AC_MainWindow::createMenu() { + + file_menu = menuBar()->addMenu(tr("&File")); + controls_menu = menuBar()->addMenu(tr("&Controls")); + options = menuBar()->addMenu(tr("&Options")); + help_menu = menuBar()->addMenu(tr("Help")); + + file_new_capture = new QAction(tr("Capture from Webcam"),this); + file_new_capture->setShortcut(tr("Ctrl+N")); + file_menu->addAction(file_new_capture); + + file_new_video = new QAction(tr("Capture from Video"), this); + file_new_video->setShortcut(tr("Ctrl+V")); + file_menu->addAction(file_new_video); + + file_exit = new QAction(tr("E&xit"), this); + file_exit->setShortcut(tr("Ctrl+X")); + file_menu->addAction(file_exit); + + movement = options->addMenu(tr("Movement")); + in_out_increase = new QAction(tr("Move In, Move Out, Increase"), this); + in_out_increase->setCheckable(true); + in_out_increase->setChecked(true); + movement->addAction(in_out_increase); + + in_out = new QAction(tr("Move in, Move Out"), this); + in_out->setCheckable(true); + movement->addAction(in_out); + + out_reset = new QAction(tr("Move Out, Reset"), this); + out_reset->setCheckable(true); + movement->addAction(out_reset); + speed_actions[0] = 0.001; + speed_actions[1] = 0.05; + speed_actions[2] = 0.01; + speed_actions[3] = 0.1; + speed_actions[4] = 0.5; + speed_actions[5] = 1.0; + speed_actions[6] = 3.0; + const QString act_val[] = { "0.001 (Very Slow)", "0.05 (Slow)", "0.01 (Normal)", "0.1 (Regular)", "0.5 (Fast)", "1.0 (Faster)", "3.0 (Very Fast)"}; + speed_menu = options->addMenu("Movement Speed"); + for(int i = 0; i < 7; ++i) { + speed_action_items[i] = new QAction(act_val[i], this); + speed_action_items[i]->setCheckable(true); + speed_menu->addAction(speed_action_items[i]); + } + image_menu = options->addMenu(tr("Image")); + noflip = new QAction(tr("Normal"), this); + noflip->setCheckable(true); + noflip->setChecked(true); + image_menu->addAction(noflip); + flip1 = new QAction(tr("Flip Vertical"), this); + flip1->setCheckable(true); + flip1->setChecked(false); + image_menu->addAction(flip1); + flip2 = new QAction(tr("Flip Horizontal"), this); + flip2->setCheckable(true); + flip2->setChecked(false); + image_menu->addAction(flip2); + flip3 = new QAction(tr("Flip Vertical and Horizontal"), this); + flip3->setCheckable(true); + flip3->setChecked(false); + image_menu->addAction(flip3); + options->addSeparator(); + clear_sub = new QAction(tr("Clear SubFilter"), this); + options->addAction(clear_sub); + clear_sub->setShortcut(tr("Ctrl+F")); + clear_image = new QAction(tr("Clear Image"), this); + options->addAction(clear_image); + options->addSeparator(); + repeat_v = new QAction(tr("Repeat"), this); + repeat_v->setCheckable(true); + repeat_v->setChecked(false); + + fade_on = new QAction(tr("Fade"), this); + fade_on->setCheckable(true); + fade_on->setChecked(true); + options->addAction(fade_on); + options->addAction(repeat_v); + + connect(fade_on, SIGNAL(triggered()), this, SLOT(setFade())); + connect(repeat_v, SIGNAL(triggered()), this, SLOT(repeat_vid())); + connect(clear_image, SIGNAL(triggered()), this, SLOT(clear_img())); + connect(clear_sub, SIGNAL(triggered()), this, SLOT(clear_subfilter())); + connect(flip1, SIGNAL(triggered()), this, SLOT(flip1_action())); + connect(flip2, SIGNAL(triggered()), this, SLOT(flip2_action())); + connect(flip3, SIGNAL(triggered()), this, SLOT(flip3_action())); + connect(noflip, SIGNAL(triggered()), this, SLOT(noflip_action())); + connect(speed_action_items[0], SIGNAL(triggered()), this, SLOT(speed1())); + connect(speed_action_items[1], SIGNAL(triggered()), this, SLOT(speed2())); + connect(speed_action_items[2], SIGNAL(triggered()), this, SLOT(speed3())); + connect(speed_action_items[3], SIGNAL(triggered()), this, SLOT(speed4())); + connect(speed_action_items[4], SIGNAL(triggered()), this, SLOT(speed5())); + connect(speed_action_items[5], SIGNAL(triggered()), this, SLOT(speed6())); + connect(speed_action_items[6], SIGNAL(triggered()), this, SLOT(speed7())); + speed2(); + connect(file_new_capture, SIGNAL(triggered()), this, SLOT(file_NewCamera())); + connect(file_new_video, SIGNAL(triggered()), this, SLOT(file_NewVideo())); + connect(file_exit, SIGNAL(triggered()), this, SLOT(file_Exit())); + connect(in_out_increase, SIGNAL(triggered()), this, SLOT(movementOption1())); + connect(in_out, SIGNAL(triggered()), this, SLOT(movementOption2())); + connect(out_reset, SIGNAL(triggered()), this, SLOT(movementOption3())); + controls_stop = new QAction(tr("Sto&p"), this); + controls_stop->setShortcut(tr("Ctrl+C")); + controls_menu->addAction(controls_stop); + controls_stop->setEnabled(false); + controls_snapshot = new QAction(tr("Take &Snapshot"), this); + controls_snapshot->setShortcut(tr("Ctrl+A")); + controls_menu->addAction(controls_snapshot); + controls_pause = new QAction(tr("&Pause"), this); + controls_pause->setShortcut(tr("Ctrl+P")); + controls_menu->addAction(controls_pause); + controls_step = new QAction(tr("Step"), this); + controls_step->setShortcut(tr("Ctrl+I")); + controls_menu->addAction(controls_step); + controls_setimage = new QAction(tr("Set Image"), this); + //controls_setimage->setShortcut(tr("Ctrl+Q")); + controls_menu->addAction(controls_setimage); + controls_setkey = new QAction(tr("Set Color Key Image"), this); + //controls_setkey->setShortcut(tr("Ctrl+K")); + controls_menu->addAction(controls_setkey); + controls_showvideo = new QAction(tr("Hide Display Video"), this); + controls_showvideo->setShortcut(tr("Ctrl+V")); + controls_menu->addAction(controls_showvideo); + reset_filters = new QAction(tr("Reset Filters"), this); + reset_filters->setShortcut(tr("Ctrl+R")); + controls_menu->addAction(reset_filters); + controls_showvideo->setEnabled(false); + controls_showvideo->setCheckable(true); + open_search = new QAction(tr("Search Filters"), this); + open_search->setShortcut(tr("Ctrl+S")); + controls_menu->addAction(open_search); + select_key = new QAction(tr("Set Chroma Key"), this); + controls_menu->addAction(select_key); + connect(select_key, SIGNAL(triggered()), this, SLOT(openColorWindow())); + connect(open_search,SIGNAL(triggered()), this, SLOT(openSearch())); + connect(controls_snapshot, SIGNAL(triggered()), this, SLOT(controls_Snap())); + connect(controls_pause, SIGNAL(triggered()), this, SLOT(controls_Pause())); + connect(controls_step, SIGNAL(triggered()), this, SLOT(controls_Step())); + connect(controls_stop, SIGNAL(triggered()), this, SLOT(controls_Stop())); + connect(controls_setimage, SIGNAL(triggered()), this, SLOT(controls_SetImage())); + connect(controls_setkey, SIGNAL(triggered()), this, SLOT(controls_SetKey())); + connect(controls_showvideo, SIGNAL(triggered()), this, SLOT(controls_ShowVideo())); + connect(reset_filters, SIGNAL(triggered()), this, SLOT(controls_Reset())); + connect(combo_rgb, SIGNAL(currentIndexChanged(int)), this, SLOT(cb_SetIndex(int))); + controls_pause->setText(tr("Pause")); + help_about = new QAction(tr("About"), this); + help_about->setShortcut(tr("Ctrl+A")); + help_menu->addAction(help_about); + connect(help_about, SIGNAL(triggered()), this, SLOT(help_About())); + controls_stop->setEnabled(false); + controls_pause->setEnabled(false); + controls_step->setEnabled(false); + controls_snapshot->setEnabled(false); + + set_newnames = new QAction(tr("Set Favorites"), this); + connect(set_newnames, SIGNAL(triggered()), this, SLOT(show_Favorites())); + controls_menu->addAction(set_newnames); +} + +void AC_MainWindow::resetIndex() { + frame_index = 0; +} + +void AC_MainWindow::clear_subfilter() { + int crow = custom_filters->currentRow(); + if(crow >= 0) { + QListWidgetItem *item = custom_filters->item(crow); + std::string text = item->text().toStdString(); + if(text.find(":") == std::string::npos) + return; + std::string val = text.substr(0, text.find(":")); + item->setText(val.c_str()); + std::vector v; + buildVector(v); + playback->setVector(v); + Log(tr("Cleared SubFilter")); + } + ac::setSubFilter(-1); +} + +void AC_MainWindow::clear_img() { + blend_set = false; + blend_image.release(); + Log(tr("Cleared Image\n")); +} + +void AC_MainWindow::flip1_action() { + flip1->setChecked(true); + flip2->setChecked(false); + flip3->setChecked(false); + noflip->setChecked(false); + playback->SetFlip(false, true); + Log(tr("Flipped Image\n")); +} + +void AC_MainWindow::flip2_action() { + flip1->setChecked(false); + flip2->setChecked(true); + flip3->setChecked(false); + noflip->setChecked(false); + playback->SetFlip(true, false); + Log(tr("Flipped Image\n")); +} + +void AC_MainWindow::flip3_action() { + flip1->setChecked(false); + flip2->setChecked(false); + flip3->setChecked(true); + noflip->setChecked(false); + playback->SetFlip(true, true); + Log(tr("Flipped Image\n")); +} + +void AC_MainWindow::noflip_action() { + flip1->setChecked(false); + flip2->setChecked(false); + flip3->setChecked(false); + noflip->setChecked(true); + playback->SetFlip(false, false); + Log(tr("Removed Flip Action\n")); + +} + +void AC_MainWindow::repeat_vid() { + bool val = repeat_v->isChecked(); + playback->enableRepeat(val); + if(val == true) { + Log(tr("Repeat Enabled\n")); + } else { + Log(tr("Repeat Disabled\n")); + } +} + +void AC_MainWindow::speed1() { + speed_index = 0; + ac::alpha_increase = speed_actions[0]; + QString text; + QTextStream stream(&text); + stream << "Movements Speed Set to: " << ac::alpha_increase << "\n"; + Log(text); + for(int i = 0; i < 7; ++i) { + speed_action_items[i]->setChecked(false); + } + speed_action_items[0]->setChecked(true); + +} +void AC_MainWindow::speed2() { + speed_index = 1; + QString text; + QTextStream stream(&text); + ac::alpha_increase = speed_actions[1]; + stream << "Movements Speed Set to: " << ac::alpha_increase << "\n"; + Log(text); + for(int i = 0; i < 7; ++i) { + speed_action_items[i]->setChecked(false); + } + speed_action_items[1]->setChecked(true); +} +void AC_MainWindow::speed3() { + speed_index = 2; + ac::alpha_increase = speed_actions[2]; + QString text; + QTextStream stream(&text); + stream << "Movements Speed Set to: " << ac::alpha_increase << "\n"; + Log(text); + for(int i = 0; i < 7; ++i) { + speed_action_items[i]->setChecked(false); + } + speed_action_items[2]->setChecked(true); + +} +void AC_MainWindow::speed4() { + speed_index = 3; + ac::alpha_increase = speed_actions[3]; + QString text; + QTextStream stream(&text); + stream << "Movements Speed Set to: " << ac::alpha_increase << "\n"; + Log(text); + for(int i = 0; i < 7; ++i) { + speed_action_items[i]->setChecked(false); + } + speed_action_items[3]->setChecked(true); +} +void AC_MainWindow::speed5() { + speed_index = 4; + ac::alpha_increase = speed_actions[4]; + QString text; + QTextStream stream(&text); + stream << "Movements Speed Set to: " << ac::alpha_increase << "\n"; + Log(text); + for(int i = 0; i < 7; ++i) { + speed_action_items[i]->setChecked(false); + } + speed_action_items[4]->setChecked(true); +} +void AC_MainWindow::speed6() { + speed_index = 5; + ac::alpha_increase = speed_actions[5]; + QString text; + QTextStream stream(&text); + stream << "Movements Speed Set to: " << ac::alpha_increase << "\n"; + Log(text); + for(int i = 0; i < 7; ++i) { + speed_action_items[i]->setChecked(false); + } + speed_action_items[5]->setChecked(true); +} + +void AC_MainWindow::speed7() { + speed_index = 6; + QString text; + QTextStream stream(&text); + ac::alpha_increase = speed_actions[6]; + stream << "Movements Speed Set to: " << ac::alpha_increase << "\n"; + Log(text); + for(int i = 0; i < 7; ++i) { + speed_action_items[i]->setChecked(false); + } + speed_action_items[6]->setChecked(true); +} + +void AC_MainWindow::movementOption1() { + ac::setProcMode(0); + in_out_increase->setChecked(true); + in_out->setChecked(false); + out_reset->setChecked(false); + Log(tr("Proc Mode set to: 0\n")); +} +void AC_MainWindow::movementOption2() { + in_out_increase->setChecked(false); + in_out->setChecked(true); + out_reset->setChecked(false); + ac::setProcMode(1); + Log(tr("Proc Mode set to: 1\n")); +} + +void AC_MainWindow::movementOption3() { + in_out_increase->setChecked(false); + in_out->setChecked(false); + out_reset->setChecked(true); + ac::setProcMode(2); + Log(tr("Proc Mode set to: 2\n")); +} + +void AC_MainWindow::chk_Clicked() { + playback->setOptions(chk_negate->isChecked(), combo_rgb->currentIndex()); +} +void AC_MainWindow::cb_SetIndex(int index) { + playback->setOptions(chk_negate->isChecked(), index); +} + +void AC_MainWindow::slideChanged(int) { + playback->setRGB(slide_r->sliderPosition(), slide_g->sliderPosition(), slide_b->sliderPosition()); +} + +void AC_MainWindow::colorChanged(int) { + playback->setColorOptions(slide_bright->sliderPosition(), slide_gamma->sliderPosition(), slide_saturation->sliderPosition()); +} + +void AC_MainWindow::colorMapChanged(int pos) { + playback->setColorMap(pos); + Log("Changed Color Map\n"); +} + +void AC_MainWindow::comboFilterChanged(int) { + if(loading == true) return; + playback->setIndexChanged(filters->currentText().toStdString()); + QString str; + QTextStream stream(&str); + stream << "Filter changed to: " << filters->currentText() << "\n"; + Log(str); + std::string text = filters->currentText().toStdString(); + if(blend_set == false && text.find("Image") != std::string::npos) + Log(tr("Set an Image to use this filter\n")); + else if(ac::subfilter == -1 && text.find("SubFilter") != std::string::npos) + Log(tr("Set a SubFilter to use this filter\n")); + +} + +void AC_MainWindow::setFilterSingle() { + playback->setSingleMode(true); + Log("Set to Single Filter Mode\n"); +} +void AC_MainWindow::setFilterCustom() { + playback->setSingleMode(false); + Log("Set to Custom Filter Mode\n"); +} + +void AC_MainWindow::addClicked() { + int row = filters->currentIndex(); + if(row != -1) { + //QListWidgetItem *item = filters->item(row); + std::string sub_str = filters->currentText().toStdString(); + custom_filters->addItem(filters->currentText()); + //custom_filters->addItem(sub_str.c_str()); + QString qs; + QTextStream stream(&qs); + stream << "Added Filter: " << filters->currentText() << "\n"; + Log(qs); + std::vector v; + buildVector(v); + playback->setVector(v); + } +} +void AC_MainWindow::updateList() { + std::vector v; + buildVector(v); + playback->setVector(v); +} + +void AC_MainWindow::rmvClicked() { + int item = custom_filters->currentRow(); + if(item != -1) { + QListWidgetItem *i = custom_filters->takeItem(item); + QString qs; + QTextStream stream(&qs); + stream << "Removed Filter: " << i->text() << "\n"; + Log(qs); + std::vector v; + buildVector(v); + playback->setVector(v); + } +} + +void AC_MainWindow::upClicked() { + int item = custom_filters->currentRow(); + if(item > 0) { + QListWidgetItem *i = custom_filters->takeItem(item); + custom_filters->insertItem(item-1, i->text()); + custom_filters->setCurrentRow(item-1); + std::vector v; + buildVector(v); + playback->setVector(v); + } +} + +void AC_MainWindow::downClicked() { + int item = custom_filters->currentRow(); + if(item >= 0 && item < custom_filters->count()-1) { + QListWidgetItem *i = custom_filters->takeItem(item); + custom_filters->insertItem(item+1, i->text()); + custom_filters->setCurrentRow(item+1); + std::vector v; + buildVector(v); + playback->setVector(v); + } +} + +void AC_MainWindow::setSub() { + int row = filters->currentIndex(); + int crow = custom_filters->currentRow(); + if(row != -1 && crow != -1) { + std::ostringstream stream; + QListWidgetItem *item = custom_filters->item(crow); + QString filter_num = filters->currentText(); + int value_index = filter_map[filter_num.toStdString()].index; + int filter_index = filter_map[filter_num.toStdString()].filter; + if(value_index == 0) { + std::string fname = filters->currentText().toStdString(); + std::string filter_val = item->text().toStdString(); + if(filter_val.find(":") != std::string::npos) + filter_val = filter_val.substr(0, filter_val.find(":")); + + if(!(fname.find("SubFilter") == std::string::npos && filter_val.find("SubFilter") != std::string::npos)) { + stream << filter_val << " does not support a subfilter.\n"; + Log(stream.str().c_str()); + return; + } + stream << "SubFilter set to: " << filter_num.toStdString() << "\n"; + stream << "SubFilter index: " << filter_index << "\n"; + std::ostringstream stream1; + stream1 << filter_val << ":" << fname; + item->setText(stream1.str().c_str()); + std::vector v; + buildVector(v); + playback->setVector(v); + QString l = stream.str().c_str(); + Log(l); + } + } +} +void AC_MainWindow::Log(const QString &s) { + QString text; + text = log_text->toPlainText(); + text += s; + log_text->setText(text); + QTextCursor tmpCursor = log_text->textCursor(); + tmpCursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor); + log_text->setTextCursor(tmpCursor); +} + +bool AC_MainWindow::startCamera(int res, int dev, const QString &outdir, bool record, int type) { + programMode = MODE_CAMERA; + progress_bar->hide(); + controls_showvideo->setEnabled(false); + playback->setDisplayed(true); + controls_stop->setEnabled(true); + controls_pause->setEnabled(true); + controls_step->setEnabled(false); + controls_snapshot->setEnabled(true); + // setup device + step_frame = false; + video_file_name = ""; + frame_index = 0; + /* + capture_camera.open(dev); + if(!capture_camera.isOpened()) { + return false; + }*/ + video_frames = 0; + video_fps = 24; /* + int ores_w = capture_camera.get(CV_CAP_PROP_FRAME_WIDTH); + int ores_h = capture_camera.get(CV_CAP_PROP_FRAME_HEIGHT); + */ + int res_w = 0; + int res_h = 0; + /*QString str; + QTextStream stream(&str); + stream << "Opened capture device " << res_w << "x" << res_h << "\n"; + stream << "FPS: " << video_fps << "\n";*/ + output_directory = outdir; + frame_index = 0; + //Log(str); + paused = false; + recording = record; + QString output_name; + QTextStream stream_(&output_name); + static unsigned int index = 0; + time_t t = time(0); + struct tm *m; + m = localtime(&t); + QString ext; + ext = (type == 0) ? ".mov" : ".avi"; + Log(tr("Capture Device Opened [Camera]\n")); + std::ostringstream time_stream; + time_stream << "-" << (m->tm_year + 1900) << "." << (m->tm_mon + 1) << "." << m->tm_mday << "_" << m->tm_hour << "." << m->tm_min << "." << m->tm_sec << "_"; + stream_ << outdir << "/" << "Video" << time_stream.str().c_str() << "AC2.Output." << (++index) << ext; + switch(res) { + case 0: + res_w = 640; + res_h = 480; + break; + case 1: + res_w = 1280; + res_h = 720; + break; + case 2: + res_w = 1920; + res_h = 1080; + + break; + } + + /* + bool cw = capture_camera.set(CV_CAP_PROP_FRAME_WIDTH, res_w); + bool ch = capture_camera.set(CV_CAP_PROP_FRAME_HEIGHT, res_h); + + if(cw == false || ch == false) { + QMessageBox::information(this, tr("Info"), tr("Could not set resolution reverting to default ..")); + res_w = ores_w; + res_h = ores_h; + capture_camera.set(CV_CAP_PROP_FRAME_WIDTH, res_w); + capture_camera.set(CV_CAP_PROP_FRAME_HEIGHT, res_h); + } */ + + if(recording) { + video_file_name = output_name; + writer = cv::VideoWriter(output_name.toStdString(), (type == 0) ? CV_FOURCC('m', 'p', '4', 'v') : CV_FOURCC('X','V','I','D'), video_fps, cv::Size(res_w, res_h), true); + + if(!writer.isOpened()) { + Log(tr("Could not create video writer..\n")); + QMessageBox::information(this, tr("Error"), tr("Incorrect Pathname/Or you do not have permission to write to the directory.")); + return false; + } + QString out_s; + QTextStream out_stream(&out_s); + out_stream << "Now recording to: " << output_name << "\nResolution: " << res_w << "x" << res_h << " FPS: " << video_fps << "\n"; + Log(out_s); + } + // if successful + file_new_capture->setEnabled(false); + file_new_video->setEnabled(false); + controls_stop->setEnabled(true); + bool rt_val = playback->setVideoCamera(dev, res, writer, recording); + if(rt_val == false) return false; + playback->Play(); + disp->show(); + return true; +} + +bool AC_MainWindow::startVideo(const QString &filename, const QString &outdir, bool record, int type) { + programMode = MODE_VIDEO; + controls_stop->setEnabled(true); + controls_pause->setEnabled(true); + controls_step->setEnabled(true); + controls_snapshot->setEnabled(true); + if(record == true) + controls_showvideo->setEnabled(true); + + progress_bar->show(); + playback->setDisplayed(true); + video_file_name = ""; + step_frame = false; + capture_video.open(filename.toStdString()); + if(!capture_video.isOpened()) { + return false; + } + video_frames = capture_video.get(CV_CAP_PROP_FRAME_COUNT); + if(video_frames <= 0) return false; + video_fps = capture_video.get(CV_CAP_PROP_FPS); + int res_w = capture_video.get(CV_CAP_PROP_FRAME_WIDTH); + int res_h = capture_video.get(CV_CAP_PROP_FRAME_HEIGHT); + QString str; + QTextStream stream(&str); + stream << "Opened capture device [Video] " << res_w << "x" << res_h << "\n"; + stream << "Video File: " << filename << "\n"; + stream << "FPS: " << video_fps << "\n"; + stream << "Frame Count: " << video_frames << "\n"; + output_directory = outdir; + frame_index = 0; + Log(str); + // if successful + file_new_capture->setEnabled(false); + file_new_video->setEnabled(false); + controls_stop->setEnabled(true); + paused = false; + recording = record; + QString output_name; + QTextStream stream_(&output_name); + static unsigned int index = 0; + time_t t = time(0); + struct tm *m; + m = localtime(&t); + QString ext; + ext = (type == 0) ? ".mov" : ".avi"; + std::ostringstream time_stream; + time_stream << "-" << (m->tm_year + 1900) << "." << (m->tm_mon + 1) << "." << m->tm_mday << "_" << m->tm_hour << "." << m->tm_min << "." << m->tm_sec << "_"; + stream_ << outdir << "/" << "Video" << time_stream.str().c_str() << "AC2.Output." << (++index) << ext; + + + if(recording) { + video_file_name = output_name; + writer = cv::VideoWriter(output_name.toStdString(), (type == 0) ? CV_FOURCC('m', 'p', '4', 'v') : CV_FOURCC('X','V','I','D'), video_fps, cv::Size(res_w, res_h), true); + + if(!writer.isOpened()) { + Log("Error could not open video writer.\n"); + QMessageBox::information(this, tr("Error invalid path"), tr("Incorrect Pathname/Or you do not have permission to write to the directory.")); + return false; + } + QString out_s; + QTextStream out_stream(&out_s); + out_stream << "Now recording to: " << output_name << "\nResolution: " << res_w << "x" << res_h << " FPS: " << video_fps << "\n"; + Log(out_s); + } + playback->setVideo(capture_video,writer,recording); + playback->Play(); + disp->show(); + return true; +} + +void AC_MainWindow::controls_Stop() { + playback->Stop(); + goto_window->hide(); + progress_bar->hide(); + controls_showvideo->setEnabled(false); + controls_stop->setEnabled(false); + controls_pause->setEnabled(false); + controls_step->setEnabled(false); + controls_snapshot->setEnabled(false); + if(capture_video.isOpened()) { + capture_video.release(); + if(recording == true) writer.release(); + file_new_capture->setEnabled(true); + file_new_video->setEnabled(true); + if(recording) { + QString stream_; + QTextStream stream(&stream_); + stream << "Wrote video file: " << video_file_name << "\n"; + Log(stream_); + } + disp->hide(); + playback->Release(); + } + if(programMode == MODE_CAMERA) { + //capture_camera.release(); + if(recording == true) writer.release(); + file_new_capture->setEnabled(true); + file_new_video->setEnabled(true); + if(recording) { + QString stream_; + QTextStream stream(&stream_); + stream << "Wrote video file: " << video_file_name << "\n"; + Log(stream_); + } + disp->hide(); + playback->Release(); + } + Log(tr("Capture device [Closed]\n"));; +} + +void AC_MainWindow::controls_ShowVideo() { + QString st = controls_showvideo->text(); + + if(st == "Hide Display Video") { + playback->setDisplayed(Qt::Unchecked); + disp->hide(); + controls_showvideo->setText("Show Display Video"); + } else { + controls_showvideo->setText("Hide Display Video"); + playback->setDisplayed(true); + disp->show(); + } +} + +void AC_MainWindow::controls_Reset() { + playback->reset_filters(); +} + +void AC_MainWindow::file_Exit() { + QApplication::exit(0); +} + +void AC_MainWindow::file_NewVideo() { + cap_video->show(); + goto_window->hide(); +} + +void AC_MainWindow::file_NewCamera() { + cap_camera->show(); + goto_window->hide(); +} + +void AC_MainWindow::controls_Snap() { + take_snapshot = true; +} + +void AC_MainWindow::controls_Pause() { + QString p = controls_pause->text(); + if(p == "Pause") { + controls_pause->setText("Paused"); + controls_pause->setChecked(true); + paused = true; + if(programMode == MODE_VIDEO) { + goto_window->showWindow(frame_index, 0, video_frames); + } + playback->Stop(); + } else { + controls_pause->setText("Pause"); + controls_pause->setChecked(false); + goto_window->hide(); + playback->Play(); + paused = false; + } +} + +void AC_MainWindow::controls_SetImage() { + QString fileName = QFileDialog::getOpenFileName(this,tr("Open Image"), "", tr("Image Files (*.png *.jpg)")); + if(fileName != "") { + cv::Mat tblend_image = cv::imread(fileName.toStdString()); + if(!tblend_image.empty()) { + playback->setImage(tblend_image); + QString text; + QTextStream stream(&text); + stream << "Successfully Loaded Image: [" << fileName << "] Size: " << tblend_image.cols << "x" << tblend_image.rows << "\n"; + Log(text); + } else { + QMessageBox::information(this, tr("Image Load failed"), tr("Could not load image")); + } + } +} + +void AC_MainWindow::controls_SetKey() { + QString fileName = QFileDialog::getOpenFileName(this,tr("Open Color Key Image"), "", tr("Image Files (*.png)")); + if(fileName != "") { + cv::Mat tblend_image = cv::imread(fileName.toStdString()); + if(!tblend_image.empty()) { + playback->setColorKey(tblend_image); + QString str_value; + QTextStream stream(&str_value); + stream << "ColorKey is (255,0,255)\n Image Set: " << fileName; + QMessageBox::information(this, tr("Loaded Image"), tr(str_value.toStdString().c_str())); + } else { + QMessageBox::information(this, tr("Image Load failed"), tr("Could not load ColorKey image")); + } + } +} + +void AC_MainWindow::controls_Step() { + playback->setStep(); + playback->Play(); + step_frame = true; +} + +void AC_MainWindow::buildVector(std::vector &v) { + if(!v.empty()) v.erase(v.begin(), v.end()); + for(int i = 0; i < custom_filters->count(); ++i) { + QListWidgetItem *val = custom_filters->item(i); + QString name = val->text(); + std::string n = name.toStdString(); + if(n.find(":") == std::string::npos) + v.push_back(filter_map[name.toStdString()]); + else { + std::string namev = name.toStdString(); + std::string left_str = namev.substr(0, namev.find(":")); + std::string right_str = namev.substr(namev.find(":")+1,namev.length()-left_str.length()-1); + int index_val = filter_map[right_str].filter; + FilterValue fv(filter_map[left_str].index, filter_map[left_str].filter, index_val); + v.push_back(fv); + } + } +} + +cv::Mat QImage2Mat(QImage const& src) +{ + cv::Mat tmp(src.height(),src.width(),CV_8UC3,(uchar*)src.bits(),src.bytesPerLine()); + cv::Mat result; + cvtColor(tmp, result,CV_BGR2RGB); + return result; +} + +QImage Mat2QImage(cv::Mat const& src) +{ + cv::Mat temp; + cvtColor(src, temp,CV_BGR2RGB); + QImage dest((const uchar *) temp.data, temp.cols, temp.rows, temp.step, QImage::Format_RGB888); + dest.bits(); + return dest; +} + +void AC_MainWindow::setFrameIndex(int index) { + frame_index = index; +} + +void AC_MainWindow::updateFrame(QImage img) { + if(playback->isStopped() == false) { + disp->displayImage(img); + frame_index++; + QString frame_string; + QTextStream frame_stream(&frame_string); + if(!recording) { + frame_stream << "(Current/Total Frames/Seconds) - (" << frame_index << "/" << video_frames << "/" << (unsigned long)(frame_index/video_fps) << ") "; + } else { + struct stat buf; + stat(video_file_name.toStdString().c_str(), &buf); + frame_stream << "(Current/Total Frames/Seconds/Size) - (" << frame_index << "/" << video_frames << "/" << (unsigned int)(frame_index/video_fps) << "/" << ((buf.st_size/1024)/1024) << " MB) "; + } + if(programMode == MODE_VIDEO) { + + float index = frame_index; + float max_frames = video_frames; + float value = (index/max_frames)*100; + unsigned int val = static_cast(value); + progress_bar->setValue(val); + frame_stream << " - " << val << "%"; + } + statusBar()->showMessage(frame_string); + + if(take_snapshot == true) { + cv::Mat mat = QImage2Mat(img); + static int index = 0; + QString text; + QTextStream stream(&text); + time_t t = time(0); + struct tm *m; + m = localtime(&t); + std::ostringstream time_stream; + time_stream << "-" << (m->tm_year + 1900) << "." << (m->tm_mon + 1) << "." << m->tm_mday << "_" << m->tm_hour << "." << m->tm_min << "." << m->tm_sec << "_"; + stream << output_directory << "/" << "AC2.Snapshot." << time_stream.str().c_str() << "." << ++index << ".png"; + cv::imwrite(text.toStdString(), mat); + QString total; + QTextStream stream_total(&total); + stream_total << "Took Snapshot: " << text << "\n"; + Log(total); + take_snapshot = false; + } + } +} + +void AC_MainWindow::stopRecording() { + controls_Stop(); + frame_index = video_frames; + controls_stop->setEnabled(false); + controls_pause->setEnabled(false); + controls_step->setEnabled(false); + controls_snapshot->setEnabled(false); + progress_bar->hide(); +} + + +void AC_MainWindow::setSubFilter(const QString &filter_num) { + int value_index = filter_map[filter_num.toStdString()].index; + int filter_index = filter_map[filter_num.toStdString()].filter; + int crow = custom_filters->currentRow(); + if(value_index == 0 && crow >= 0) { + std::ostringstream stream; + QListWidgetItem *item = custom_filters->item(crow); + std::string fname = filter_num.toStdString(); + std::string filter_val = item->text().toStdString(); + if(filter_val.find(":") != std::string::npos) + filter_val = filter_val.substr(0, filter_val.find(":")); + + if(!(fname.find("SubFilter") == std::string::npos && filter_val.find("SubFilter") != std::string::npos)) { + stream << filter_val << " does not support a subfilter.\n"; + Log(stream.str().c_str()); + return; + } + stream << "SubFilter set to: " << filter_num.toStdString() << "\n"; + stream << "SubFilter index: " << filter_index << "\n"; + std::ostringstream stream1; + stream1 << filter_val << ":" << fname; + item->setText(stream1.str().c_str()); + std::vector v; + buildVector(v); + playback->setVector(v); + QString l = stream.str().c_str(); + Log(l); + } else { + QString txt; + QTextStream stream(&txt); + stream << "Only Regular Filters can be used as a SubFilter not AF\n"; + Log(txt); + } +} + +void AC_MainWindow::setFade() { + bool fc = fade_on->isChecked(); + playback->setFadeFilter(fc); +} + +void AC_MainWindow::frameInc() { + frame_index++; + QString frame_string; + QTextStream frame_stream(&frame_string); + + if(!recording) { + frame_stream << "(Current/Total Frames/Seconds) - (" << frame_index << "/" << video_frames << "/" << (unsigned int)(frame_index/video_fps) << ") "; + } else { + struct stat buf; + stat(video_file_name.toStdString().c_str(), &buf); + frame_stream << "(Current/Total Frames/Seconds/Size) - (" << frame_index << "/" << video_frames << "/" << (unsigned int)(frame_index/video_fps) << "/" << ((buf.st_size/1024)/1024) << " MB) "; + + } + if(programMode == MODE_VIDEO) { + float index = frame_index; + float max_frames = video_frames; + float value = (index/max_frames)*100; + unsigned int val = static_cast(value); + if(frame_index <= video_frames) + frame_stream << " - " << val << "%"; + progress_bar->setValue(val); + } + statusBar()->showMessage(frame_string); +} + +void AC_MainWindow::help_About() { + QString about_str; + QTextStream stream(&about_str); + stream << tr("Acid Cam Qt version: ") << ac_version << " filters: " << ac::version.c_str() << "

"; + stream << tr("Engineering by Jared Bruni

This software is dedicated to all the people that experience mental illness.

My Social Media Accounts

\n\n GitHub
\nYouTube
Instagram
LostSideDead Facebook
My Facebook
Twitter


\n"); + + QMessageBox::information(this, tr("About Acid Cam"), about_str); +} + +void AC_MainWindow::openSearch() { + search_box->show(); +} + +void AC_MainWindow::openColorWindow() { + chroma_window->show(); +} + +void AC_MainWindow::menuFilterChanged(int index) { + if(index >= 0) { + loading = true; + const char *menu_n = menuNames[index]; + filters->clear(); + auto v = ac::filter_menu_map[menu_n].menu_list; + for(auto in = v->begin(); in != v->end(); ++in) { + filters->addItem(in->c_str()); + } + filters->setCurrentIndex(0); + loading = false; + } +} + +void AC_MainWindow::show_Favorites() { + define_window->show(); +} + +void AC_MainWindow::resetMenu() { + int index = menu_cat->currentIndex(); + if(menuNames[index] == std::string("User")) { + menuFilterChanged(index); + filters->setCurrentIndex(0); + comboFilterChanged(index); + } +} + +void AC_MainWindow::setOptionString(std::string op, std::string value) { + int num = atoi(value.c_str()); + if(op == "=red") { + slide_r->setSliderPosition(num); + return; + } + if(op == "=green") { + slide_g->setSliderPosition(num); + return; + } + if(op == "=blue") { + slide_b->setSliderPosition(num); + return; + } + if(op == "=color_map") { + color_maps->setCurrentIndex(num); + return; + } + if(op == "=brightness") { + slide_bright->setSliderPosition(num); + return; + } + if(op == "=gamma") { + slide_gamma->setSliderPosition(num); + return; + } + if(op == "=sat") { + slide_saturation->setSliderPosition(num); + return; + } + if(op == "=negate") { + chk_negate->setChecked(num); + return; + } + if(op == "=color_order") { + combo_rgb->setCurrentIndex(num); + return; + } + if(op == "=proc") { + setProcMode(num); + return; + } + if(op == "=mvmnt") { + setSpeedIndex(num); + return; + } +} + +void AC_MainWindow::setProcMode(int index) { + switch(index) { + case 0: + movementOption1(); + break; + case 1: + movementOption2(); + break; + case 2: + movementOption3(); + break; + } +} + +void AC_MainWindow::load_CustomFile() { + QString file_name = QFileDialog::getOpenFileName(this, tr("Open File"),"",tr("Filter Files (*.filter)")); + if(file_name.length()==0) + return; + + std::fstream file; + file.open(file_name.toStdString(), std::ios::in); + if(!file.is_open()) { + QMessageBox::information(this,"Could not open file", "Could not open file do i have rights to this folder?"); + return; + } + std::vector values; + while(!file.eof()) { + std::string item; + std::getline(file, item); + if(file) + values.push_back(item); + } + // check if data valid + for(unsigned int i = 0; i < values.size(); ++i ){ + std::string item = values[i]; + std::string s_left, s_right; + auto pos = item.find(":"); + if(pos == std::string::npos) { + QMessageBox::information(this,"Incorrect File..\n", "Values in file incorrect"); + return; + } + s_left = item.substr(0,pos); + s_right = item.substr(pos+1, item.length()); + + if(item[0] == '=') + continue; + + if(filter_map.find(s_left) == filter_map.end()) { + QString itext = "Filter: "; + itext += s_left.c_str(); + itext += " Not found in this version... old version?"; + QMessageBox::information(this, "Filter Not Found", itext); + return; + } + if(s_right != "None" && filter_map.find(s_right) == filter_map.end()) { + QString itext = "Filter: "; + itext += s_right.c_str(); + itext += " Not found in this version... old version?"; + QMessageBox::information(this, "Filter Not Found", itext); + return; + } + + int val1 = filter_map[s_left].filter; + int val2 = filter_map[s_right].filter; + if(!(val1 >= 0 && val1 < ac::draw_max-4)) { + QMessageBox::information(this,"Unsupported Value","Filter value out of range... wrong program revision?"); + return; + } + if(!(val2 == -1 || (val2 >= 0 && val2 < ac::draw_max-4))) { + QMessageBox::information(this, "Unsupported SubFilter value","Sub Filter value of range..."); + return; + } + } + while(custom_filters->count() > 0) { + custom_filters->takeItem(0); + } + for(unsigned int i = 0; i < values.size(); ++i) { + std::string item = values[i]; + std::string s_left, s_right; + s_left = item.substr(0, item.find(":")); + s_right = item.substr(item.find(":")+1, item.length()); + if(s_left[0] == '=' && use_settings->isChecked() == true) { + setOptionString(s_left, s_right); + continue; + } else if(s_left[0] == '=') { + continue; + } + int value1 = filter_map[s_left].filter; + int value2 = 0; + if(s_right == "None") + value2 = -1; + else + value2 = filter_map[s_right].filter; + //int value1 = atoi(s_left.c_str()); + //int value2 = atoi(s_right.c_str()); + std::ostringstream stream; + stream << ac::draw_strings[value1]; + if(value2 != -1) + stream << ":" << ac::draw_strings[value2]; + custom_filters->addItem(stream.str().c_str()); + } + slideChanged(0); + colorChanged(0); + colorMapChanged(color_maps->currentIndex()); + std::ostringstream sval; + sval << "Loaded Custom Filter: " << file_name.toStdString() << "\n"; + std::vector v; + buildVector(v); + playback->setVector(v); + file.close(); + Log(sval.str().c_str()); +} + +// ugly way of doing this +void AC_MainWindow::setSpeedIndex(int index) { + switch(index) { + case 0: + speed1(); + break; + case 1: + speed2(); + break; + case 2: + speed3(); + break; + case 3: + speed4(); + break; + case 4: + speed5(); + break; + case 5: + speed6(); + break; + case 6: + speed7(); + break; + + } +} + +namespace ac { + extern int proc_mode; +} + +void AC_MainWindow::save_CustomFile() { + if(custom_filters->count() == 0) { + QMessageBox::information(this, "Seleect Filters", "You need to adds ome filters to be able to save..."); + return; + } + QString file_name = QFileDialog::getSaveFileName(this, tr("Save File"),"", tr("Filter Save (*.filter)")); + + if(file_name.length()==0) + return; + + std::fstream file_n; + file_n.open(file_name.toStdString(),std::ios::out); + if(!file_n.is_open()) { + QMessageBox::information(this, "Error", "File could not be opened..."); + return; + } + std::vector v; + buildVector(v); + if(v.size()==0) { + QMessageBox::information(this, "No Filters", "Please Add Filters to Save"); + return; + } + if(use_settings->isChecked() == 1) { + int rgb[] = { slide_r->sliderPosition(), slide_g->sliderPosition(), slide_b->sliderPosition()}; + file_n << "=red:" << rgb[0] << "\n"; + file_n << "=green:" << rgb[1] << "\n"; + file_n << "=blue:" << rgb[2] << "\n"; + int color_m = color_maps->currentIndex(); + file_n << "=color_map:" << color_m << "\n"; + int bright = slide_bright->sliderPosition(); + file_n << "=brightness:" << bright << "\n"; + int gam = slide_gamma->sliderPosition(); + file_n << "=gamma:" << gam << "\n"; + int sat = slide_saturation->sliderPosition(); + file_n << "=sat:" << sat << "\n"; + int chkNegate = chk_negate->isChecked(); + file_n << "=negate:" << chkNegate << "\n"; + int cord = combo_rgb->currentIndex(); + file_n << "=color_order:" << cord << "\n"; + int procM = ac::proc_mode; + file_n << "=proc:" << procM << "\n"; + int mvmnt = speed_index; + file_n << "=mvmnt:"<< mvmnt << "\n"; + } + for(unsigned int i = 0; i < v.size(); ++i) { + if(v[i].index == 0) { + int value1 = v[i].filter; + int value2 = v[i].subfilter; + std::string v1, v2; + v1 = ac::draw_strings[value1]; + if(value2 == -1) + v2 = "None"; + else + v2 = ac::draw_strings[value2]; + file_n << v1 << ":" << v2 << "\n"; + } + } + std::ostringstream stream; + stream << "Wrote custom to: " << file_name.toStdString() << "\n"; + Log(stream.str().c_str()); + file_n.close(); +} diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/main_window.h b/windows/Acid.Cam.Qt.Windows.March.2019/main_window.h new file mode 100755 index 0000000..19cbbde --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/main_window.h @@ -0,0 +1,149 @@ + +/* + * Acid Cam v2 - Qt/OpenCV Edition + * written by Jared Bruni ( http://lostsidedead.com ) + * (C) 2017 GPL + */ + +#ifndef __MAIN_WINDOW_H__ +#define __MAIN_WINDOW_H__ + +#include "qtheaders.h" +#include "new_dialog.h" +#include "display_window.h" +#include "playback_thread.h" +#include "search_box.h" +#include "goto_window.h" +#include "chroma_window.h" +#include "user_define.h" + + +class SearchWindow; + +class AC_MainWindow : public QMainWindow { + Q_OBJECT +public: + AC_MainWindow(QWidget *parent = 0); + ~AC_MainWindow(); + void Log(const QString &s); + bool startCamera(int res, int dev, const QString &outdir, bool record, int type); + bool startVideo(const QString &filename, const QString &outdir, bool record, int type); + QListWidget /**filters,*/ *custom_filters; + QPushButton *btn_add, *btn_remove, *btn_moveup, *btn_movedown,*btn_load, *btn_save, *btn_sub, *btn_clr; + QTextEdit *log_text; + QCheckBox *chk_negate, *use_settings; + QComboBox *combo_rgb; + QSlider *slide_r, *slide_g, *slide_b, *slide_bright, *slide_gamma, *slide_saturation; + QProgressBar *progress_bar; + QComboBox *color_maps, *filters, *menu_cat; + QMenu *file_menu, *controls_menu, *help_menu, *options, *movement, *speed_menu; + QAction *file_exit, *file_new_capture, *file_new_video; + QAction *controls_snapshot, *controls_pause, *controls_step, *controls_stop, *controls_setimage,*controls_setkey,*controls_showvideo, *clear_images, *reset_filters; + QAction *help_about; + QAction *open_search; + QAction *in_out_increase; + QAction *in_out; + QAction *out_reset; + QAction *speed_action_items[7]; + QMenu *image_menu; + QAction *flip1, *flip2, *flip3, *noflip; + QAction *clear_sub; + QAction *clear_image; + QAction *repeat_v; + QAction *fade_on; + QAction *select_key; + QAction *set_newnames; + double speed_actions[7]; + QRadioButton *filter_single, *filter_custom; + void updateList(); + void setSubFilter(const QString &num); + void setFrameIndex(int i); + void resetMenu(); + void setSpeedIndex(int index); + void setOptionString(std::string op, std::string value); + void setProcMode(int index); +public slots: + void addClicked(); + void rmvClicked(); + void upClicked(); + void setSub(); + void downClicked(); + void file_Exit(); + void file_NewVideo(); + void file_NewCamera(); + void controls_Stop(); + void controls_Snap(); + void controls_Pause(); + void controls_Step(); + void controls_SetImage(); + void controls_ShowVideo(); + void controls_SetKey(); + void controls_Reset(); + void help_About(); + void updateFrame(QImage img); + void stopRecording(); + void resetIndex(); + void chk_Clicked(); + void cb_SetIndex(int index); + void frameInc(); + void slideChanged(int pos); + void colorChanged(int pos); + void colorMapChanged(int pos); + void comboFilterChanged(int pos); + void setFilterSingle(); + void setFilterCustom(); + void openSearch(); + void movementOption1(); + void movementOption2(); + void movementOption3(); + void speed1(); + void speed2(); + void speed3(); + void speed4(); + void speed5(); + void speed6(); + void speed7(); + void flip1_action(); + void flip2_action(); + void flip3_action(); + void noflip_action(); + void clear_subfilter(); + void clear_img(); + void repeat_vid(); + void setFade(); + void openColorWindow(); + void menuFilterChanged(int index); + void show_Favorites(); + void load_CustomFile(); + void save_CustomFile(); +private: + void createControls(); + void createMenu(); + DisplayWindow *disp; + CaptureCamera *cap_camera; + CaptureVideo *cap_video; + SearchWindow *search_box; + ChromaWindow *chroma_window; + DefineWindow *define_window; + GotoWindow *goto_window; + cv::VideoCapture capture_camera, capture_video; + cv::VideoWriter writer; + unsigned long video_frames; + double video_fps; + bool paused, recording, step_frame; + QString video_file_name; + QString output_directory; + bool take_snapshot; + unsigned long file_pos, frame_index; + Playback *playback; + VideoMode programMode; + void buildVector(std::vector &v); + bool loading; + int speed_index; +}; + +extern const char *filer_names[]; +extern std::unordered_map filter_map; +void generate_map(); + +#endif diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/new_dialog.cpp b/windows/Acid.Cam.Qt.Windows.March.2019/new_dialog.cpp new file mode 100755 index 0000000..78124a1 --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/new_dialog.cpp @@ -0,0 +1,167 @@ + +/* + * Acid Cam v2 - Qt/OpenCV Edition + * written by Jared Bruni ( http://lostsidedead.com ) + * (C) 2017 GPL + */ + + +#include "new_dialog.h" +#include "main_window.h" + + +CaptureCamera::CaptureCamera(QWidget *parent) : QDialog(parent) { + setGeometry(100, 100, 290, 120); + setFixedSize(290, 120); + setWindowTitle(tr("Capture from Webcam")); + setWindowIcon(QPixmap(":/images/icon.png")); + createControls(); +} + +void CaptureCamera::createControls() { + QLabel *res = new QLabel(tr("Resolution: "), this); + res->setGeometry(10, 10, 75, 20); + combo_res = new QComboBox(this); + combo_res->setGeometry(85, 10, 200, 25); + combo_res->addItem("640x480 (SD)"); + combo_res->addItem("1280x720 (HD)"); + combo_res->addItem("1920x1080 (Full HD)"); + QLabel *dev = new QLabel(tr("Device: "), this); + dev->setGeometry(10, 35, 50, 20); + combo_device = new QComboBox(this); + combo_device->setGeometry(85, 35, 200, 25); + for(int i = 0; i < 10; ++i) { + QString s; + QTextStream stream(&s); + stream << i; + combo_device->addItem(*stream.string()); + } + btn_select = new QPushButton(tr("Save Directory"), this); + btn_select->setGeometry(10, 65, 100, 20); + output_dir = new QLineEdit("", this); + output_dir->setGeometry(110, 65, 175, 20); + output_dir->setReadOnly(true); + chk_record = new QCheckBox(tr("Record"), this); + chk_record->setGeometry(10, 95, 70, 20); + btn_start = new QPushButton(tr("Start"), this); + btn_start->setGeometry(185, 95, 100, 20); + connect(btn_start, SIGNAL(clicked()), this, SLOT(btn_Start())); + connect(btn_select, SIGNAL(clicked()), this, SLOT(btn_Select())); + + video_type = new QComboBox(this); + video_type->setGeometry(80, 90, 90, 25); + video_type->addItem("MOV"); + video_type->addItem("AVI"); +} + +void CaptureCamera::setParent(AC_MainWindow *p) { + win_parent = p; +} + +void CaptureCamera::btn_Select() { + + QString def_path = ""; +#if defined(__linux__) + def_path = ""; +#elif defined(__APPLE__) + def_path = "/Users"; +#elif defined(_WIN32) + def_path = "C:\\"; +#endif + + QString dir = QFileDialog::getExistingDirectory(this, tr("Open Directory"),def_path,QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); + + if(dir != "") { + output_dir->setText(dir); + } +} + +void CaptureCamera::btn_Start() { + + int vtype; + vtype = video_type->currentIndex(); + + if(output_dir->text().length() > 0) { + if(win_parent->startCamera(combo_res->currentIndex(), combo_device->currentIndex(), output_dir->text(), chk_record->isChecked(), vtype)) { + hide(); + + } else { + QMessageBox::information(this, tr("Could not open Capture device"), tr("Make sure you Webcam is pluged in. If you have more than one Webcam use the proper device index.")); + } + } else { + QMessageBox::information(this, tr("Error please fill out Save Directory"), tr("Could not create Capture device requires Save Directory")); + } +} + +CaptureVideo::CaptureVideo(QWidget *parent) : QDialog(parent) { + setGeometry(100, 100, 330, 100); + setFixedSize(330, 100); + setWindowTitle(tr("Capture from Video")); + setWindowIcon(QPixmap(":/images/icon.png")); + createControls(); +} + +void CaptureVideo::createControls() { + btn_setedit = new QPushButton(tr("Source File"), this); + btn_setedit->setGeometry(10, 10, 110, 20); + edit_src = new QLineEdit(this); + edit_src->setGeometry(120, 10, 200, 20); + edit_src->setReadOnly(true); + btn_setout = new QPushButton(tr("Set Output"), this); + btn_setout->setGeometry(10, 30, 110, 20); + edit_outdir = new QLineEdit(this); + edit_outdir->setGeometry(120, 30, 200, 20); + edit_outdir->setReadOnly(true); + btn_start = new QPushButton(tr("Start"), this); + btn_start->setGeometry(10, 60, 100, 20); + chk_record = new QCheckBox(tr("Record"), this); + chk_record->setGeometry(110, 60, 80, 20); + + video_type = new QComboBox(this); + video_type->setGeometry(180, 55, 120, 25); + video_type->addItem("MOV"); + video_type->addItem("AVI"); + connect(btn_setedit, SIGNAL(clicked()), this, SLOT(btn_SetSourceFile())); + connect(btn_setout, SIGNAL(clicked()), this, SLOT(btn_SetOutputDir())); + connect(btn_start, SIGNAL(clicked()), this, SLOT(btn_Start())); +} + +void CaptureVideo::setParent(AC_MainWindow *p) { + win_parent = p; +} + +void CaptureVideo::btn_SetSourceFile() { + QString def_path = ""; + QString fileName = QFileDialog::getOpenFileName(this,tr("Open Video"), def_path, tr("Video Files (*.avi *.mov *.mp4 *.mkv)")); + if(fileName != "") + edit_src->setText(fileName); +} + +void CaptureVideo::btn_SetOutputDir() { + QString def_path = ""; + QString dir = QFileDialog::getExistingDirectory(this, tr("Set Output Directory"),def_path,QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); + if(dir != "") + edit_outdir->setText(dir); +} + +void CaptureVideo::btn_Start() { + if(edit_src->text().length() <= 0) { + QMessageBox::information(this, tr("No Input"), tr("Please Select a Video File")); + return; + } + if(edit_outdir->text().length() <= 0) { + QMessageBox::information(this, tr("No Output"), tr("Please Select Output Directory")); + return; + } + + int num; + num = video_type->currentIndex(); + + if(win_parent->startVideo(edit_src->text(), edit_outdir->text(), chk_record->isChecked(), num)) { + hide(); + } else { + QMessageBox::information(this, tr("Could not open file"), tr("Could not open video file, an error has occured")); + } +} + + diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/new_dialog.h b/windows/Acid.Cam.Qt.Windows.March.2019/new_dialog.h new file mode 100755 index 0000000..ea08c63 --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/new_dialog.h @@ -0,0 +1,56 @@ + +/* + * Acid Cam v2 - Qt/OpenCV Edition + * written by Jared Bruni ( http://lostsidedead.com ) + * (C) 2017 GPL + */ + +#ifndef _NEW_DIALOG_H_ +#define _NEW_DIALOG_H_ + +#include "qtheaders.h" + +class AC_MainWindow; + +class CaptureCamera : public QDialog { + Q_OBJECT +public: + CaptureCamera(QWidget *parent = 0); + void createControls(); + void setParent(AC_MainWindow *p); + + QComboBox *combo_res, *combo_device; + QLineEdit *output_dir; + QCheckBox *chk_record; + QPushButton *btn_start, *btn_select; + QComboBox *video_type; +public slots: + void btn_Select(); + void btn_Start(); + +private: + AC_MainWindow *win_parent; +}; + +class CaptureVideo : public QDialog { + Q_OBJECT +public: + CaptureVideo(QWidget *parent = 0); + void createControls(); + void setParent(AC_MainWindow *p); + + QLineEdit *edit_src, *edit_outdir; + QPushButton *btn_setedit, *btn_setout, *btn_start; + QCheckBox *chk_record; + QComboBox *video_type; + +public slots: + void btn_SetSourceFile(); + void btn_SetOutputDir(); + void btn_Start(); +private: + AC_MainWindow *win_parent; + +}; + +#endif diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/playback_thread.cpp b/windows/Acid.Cam.Qt.Windows.March.2019/playback_thread.cpp new file mode 100755 index 0000000..bb10e5c --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/playback_thread.cpp @@ -0,0 +1,407 @@ +/* + * Acid Cam v2 - Qt/OpenCV Edition + * written by Jared Bruni ( http://lostsidedead.com ) + * (C) 2017 GPL + */ + + +#include"playback_thread.h" + +Playback::Playback(QObject *parent) : QThread(parent) { + stop = true; + isStep = false; + isPaused = false; + bright_ = gamma_ = saturation_ = 0; + single_mode = true; + alpha = 0; + prev_filter = FilterValue(0, 0, -1); + flip_frame1 = false; + flip_frame2 = false; + repeat_video = false; + fadefilter = true; +} + +void Playback::Play() { + if(!isRunning()) { + if(isStopped()) { + stop = false; + } + } + //start(LowPriority); + start(HighPriority); +} + +void Playback::setVideo(cv::VideoCapture cap, cv::VideoWriter wr, bool record) { + mode = MODE_VIDEO; + mutex.lock(); + capture = cap; + writer = wr; + recording = record; + if(capture.isOpened()) { + frame_rate = capture.get(CV_CAP_PROP_FPS); + if(frame_rate <= 0) frame_rate = 24; + } + mutex.unlock(); +} + +bool Playback::setVideoCamera(int device, int res, cv::VideoWriter wr, bool record) { + mode = MODE_CAMERA; + device_num = device; + mutex.lock(); +#if defined(__linux__) || defined(__APPLE__) + capture.open(device); + if(!capture.isOpened()) { + mutex.unlock(); + return false; + } +#else + if(!capture.isOpened()) { + capture.open(device); + if(!capture.isOpened()) { + mutex.unlock(); + return false; + } + } +#endif + + recording = record; + writer = wr; + int res_w = 0, res_h = 0, ores_w = 640, ores_h = 480; + switch(res) { + case 0: + res_w = 640; + res_h = 480; + break; + case 1: + res_w = 1280; + res_h = 720; + break; + case 2: + res_w = 1920; + res_h = 1080; + break; + } + bool cw = capture.set(CV_CAP_PROP_FRAME_WIDTH, res_w); + bool ch = capture.set(CV_CAP_PROP_FRAME_HEIGHT, res_h); + if(cw == false || ch == false) { + res_w = ores_w; + res_h = ores_h; + capture.set(CV_CAP_PROP_FRAME_WIDTH, res_w); + capture.set(CV_CAP_PROP_FRAME_HEIGHT, res_h); + } + mutex.unlock(); + return true; +} + +void Playback::setVector(std::vector v) { + mutex_add.lock(); + current = v; + mutex_add.unlock(); +} + +void Playback::setOptions(bool n, int c) { + mutex.lock(); + ac::isNegative = n; + negate = n; + reverse = c; + ac::color_order = c; + ac::in_custom = true; + mutex.unlock(); +} + +void Playback::reset_filters() { + mutex.lock(); + if(ac::reset_alpha == false) { + ac::reset_alpha = true; + } + ac::frames_released = true; + mutex.unlock(); +} + +void Playback::SetFlip(bool f1, bool f2) { + mutex.lock(); + flip_frame1 = f1; + flip_frame2 = f2; + mutex.unlock(); +} + +void Playback::setColorOptions(int b, int g, int s) { + mutex.lock(); + bright_ = b; + gamma_ = g; + saturation_ = s; + mutex.unlock(); +} + +void Playback::setIndexChanged(std::string value) { + prev_filter = current_filter; + current_filter = filter_map[value]; + alpha = 1.0; +} + +void Playback::setSubFilter(int index) { + mutex.lock(); + ac::setSubFilter(index); + mutex.unlock(); +} + +void Playback::setSingleMode(bool val) { + single_mode = val; +} + +void Playback::setRGB(int r, int g, int b) { + mutex.lock(); + ac::swapColor_r = r; + ac::swapColor_g = g; + ac::swapColor_b = b; + mutex.unlock(); +} + +void Playback::setColorMap(int c) { + mutex.lock(); + ac::set_color_map = c; + mutex.unlock(); +} + +void Playback::setDisplayed(bool shown) { + video_shown = shown; +} + +void Playback::drawEffects(cv::Mat &frame) { + if(ac::set_color_map > 0) ac::ApplyColorMap(frame); + ac::frames_released = false; + ac::reset_alpha = false; + if(bright_ > 0) { + ac::setBrightness(frame, 1.0, bright_); + } + if(gamma_ > 0) { + cv::Mat gam = frame.clone(); + ac::setGamma(gam, frame, gamma_); + } + if(saturation_ > 0) { + ac::setSaturation(frame, saturation_); + } + if(colorkey_filter == true || (colorkey_replace == true && !color_replace_image.empty())) { + cv::Mat cframe = frame.clone(); + cv::Vec3b well_color(255,0,255); + ac::filterColorKeyed(well_color, ac::orig_frame, cframe, frame); + } +} + +void Playback::drawFilter(cv::Mat &frame, FilterValue &f) { + if(f.index == 0) { + ac::setSubFilter(f.subfilter); + ac::draw_func[f.filter](frame); + ac::setSubFilter(-1); + } else if(current_filter.index == 1) { + current_filterx = f.filter; + ac::alphaFlame(frame); + } else if(f.index == 2) { + draw_plugin(frame, f.filter); + } +} + +void Playback::run() { + + int duration = 1000/ac::fps; + + while(!stop) { + mutex.lock(); + if(!capture.read(frame)) { + if(repeat_video && mode == MODE_VIDEO) { + mutex.unlock(); + setFrameIndex(0); + emit resetIndex(); + continue; + } + stop = true; + mutex.unlock(); + emit stopRecording(); + ac::release_all_objects(); + return; + } + cv::Mat temp_frame; + if(flip_frame1 == true) { + cv::flip(frame, temp_frame, 1); + frame = temp_frame; + } + if(flip_frame2 == true) { + cv::flip(frame, temp_frame, 0); + frame = temp_frame; + } + + mutex.unlock(); + static std::vector cur; + mutex_shown.lock(); + cur = current; + mutex_shown.unlock(); + ac::orig_frame = frame.clone(); + if(single_mode == true && alpha > 0) { + if(fadefilter == true) filterFade(frame, current_filter, prev_filter, alpha); + drawEffects(frame); + alpha -= 0.08; + } else if(single_mode == true) { + mutex.lock(); + ac::in_custom = false; + drawFilter(frame, current_filter); + drawEffects(frame); + msleep(duration/2); + mutex.unlock(); + } else if(cur.size()>0) { + mutex.lock(); + ac::in_custom = true; + for(unsigned int i = 0; i < cur.size(); ++i) { + if(i == cur.size()-1) + ac::in_custom = false; + drawFilter(frame, cur[i]); + msleep(duration/2); + } + drawEffects(frame); + mutex.unlock(); + } else { + msleep(duration); + } + mutex.lock(); + if(recording && writer.isOpened()) { + writer.write(frame); + } + mutex.unlock(); + if(video_shown == true) { + if(frame.channels()==3) { + cv::cvtColor(frame, rgb_frame, CV_BGR2RGB); + img = QImage((const unsigned char*)(rgb_frame.data), rgb_frame.cols, rgb_frame.rows, QImage::Format_RGB888); + } else { + img = QImage((const unsigned char*)(frame.data), frame.cols, frame.rows, QImage::Format_Indexed8); + } + emit procImage(img); + if(isStep == true) { + isStep = false; + return; + } + } else { + emit frameIncrement(); + } + } + ac::release_all_objects(); +} + + +Playback::~Playback() { + mutex.lock(); + stop = true; +#if defined(__linux__) || defined(__APPLE__) + condition.wakeOne(); +#endif + mutex.unlock(); +#if defined(__linux__) || defined(__APPLE__) + wait(); +#endif +} + +void Playback::setFrameIndex(const long &index) { + mutex.lock(); + capture.set(CV_CAP_PROP_POS_FRAMES, index); + mutex.unlock(); +} + +bool Playback::getFrame(QImage &img, const int &index) { + QImage image; + setFrameIndex(index); + mutex.lock(); + cv::Mat frame; + if(mode == MODE_VIDEO && capture.read(frame)) { + cv::cvtColor(frame, rgb_frame, CV_BGR2RGB); + img = QImage((const unsigned char*)(rgb_frame.data), rgb_frame.cols, rgb_frame.rows, QImage::Format_RGB888); + mutex.unlock(); + setFrameIndex(index); + return true; + } + mutex.unlock(); + return false; +} + +void Playback::enableRepeat(bool re) { + mutex.lock(); + repeat_video = re; + mutex.unlock(); +} + + +void Playback::Clear() { + mutex.lock(); + blend_set = false; + colorkey_set = false; + blend_image.release(); + color_image.release(); + mutex.unlock(); +} + +void Playback::Stop() { + stop = true; + alpha = 0; + prev_filter = FilterValue(0, 0, -1); +} + +void Playback::Release() { + mutex.lock(); + stop = true; + if(capture.isOpened() && mode == MODE_VIDEO) capture.release(); + if(writer.isOpened()) writer.release(); + mutex.unlock(); +} + +void Playback::msleep(int ms) { + QThread::msleep(ms); +} + +bool Playback::isStopped() const { + return this->stop; +} + +void Playback::setStep() { + mutex.lock(); + isStep = true; + mutex.unlock(); +} + +void Playback::setImage(const cv::Mat &frame) { + mutex.lock(); + blend_set = true; + blend_image = frame; + mutex.unlock(); +} + +void Playback::setFadeFilter(bool f) { + mutex.lock(); + fadefilter = f; + mutex.unlock(); +} + +void Playback::setColorKey(const cv::Mat &image) { + mutex.lock(); + colorkey_set = true; + color_image = image; + mutex.unlock(); +} + +void Playback::filterFade(cv::Mat &frame, FilterValue &filter1, FilterValue &filter2, double alpha) { + unsigned int h = frame.rows; // frame height + unsigned int w = frame.cols;// framew idth + // make copies of original frame + cv::Mat frame1 = frame.clone(), frame2 = frame.clone(); + // apply filters on two copies of original frame + drawFilter(frame1,filter1); + drawFilter(frame2,filter2); + // loop through image setting each pixel with alphablended pixel + for(unsigned int z = 0; z < h; ++z) { + for(unsigned int i = 0; i < w; ++i) { + cv::Vec3b &pixel = frame.at(z, i); // target pixel + cv::Vec3b frame1_pix = frame1.at(z, i); // frame1 pixel + cv::Vec3b frame2_pix = frame2.at(z, i); // frame2 pixel + // loop through pixel components and set target pixel to alpha blended pixel of two frames + for(unsigned int q = 0; q < 3; ++q) + pixel[q] = frame2_pix[q]+(frame1_pix[q]*alpha); + } + } +} + diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/playback_thread.h b/windows/Acid.Cam.Qt.Windows.March.2019/playback_thread.h new file mode 100755 index 0000000..fb6c2b4 --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/playback_thread.h @@ -0,0 +1,84 @@ + +/* + * Acid Cam v2 - Qt/OpenCV Edition + * written by Jared Bruni ( http://lostsidedead.com ) + * (C) 2017 GPL + */ + +#ifndef __PLAYBACK_WINDOW_H__ +#define __PLAYBACK_WINDOW_H__ + +#include "qtheaders.h" +#include + +enum VideoMode { MODE_CAMERA = 0, MODE_VIDEO }; + +class Playback : public QThread { + Q_OBJECT +private: + std::atomic stop; + std::atomic video_shown; + QMutex mutex, mutex_shown, mutex_add; + QWaitCondition condition; + cv::Mat frame; + double frame_rate; + bool recording; + cv::VideoCapture capture; + cv::VideoWriter writer; + cv::Mat rgb_frame; + QImage img; + std::vector current; + bool isPaused, isStep; + VideoMode mode; + int device_num; + unsigned long *frame_index; + unsigned int red, green, blue; + unsigned int bright_, gamma_, saturation_; + bool single_mode; + FilterValue current_filter, prev_filter; + double alpha; + bool flip_frame1, flip_frame2; + bool repeat_video; + bool fadefilter; +public: + Playback(QObject *parent = 0); + ~Playback(); + void setFadeFilter(bool f); + void setFrameIndex(const long &index); + bool getFrame(QImage &img, const int &index); + void setRGB(int r, int g, int b); + void setColorOptions(int b, int g, int s); + void setColorMap(int c); + void Play(); + void Stop(); + void Release(); + void SetFlip(bool f1, bool f2); + void setVideo(cv::VideoCapture cap, cv::VideoWriter writer, bool record); + bool setVideoCamera(int device, int res, cv::VideoWriter writer, bool record); + bool isStopped() const; + void run(); + void Clear(); + void msleep(int ms); + void setVector(std::vector s); + void setOptions(bool n, int c); + void setImage(const cv::Mat &image); + void setColorKey(const cv::Mat &image); + void setStep(); + void setDisplayed(bool shown); + void setIndexChanged(std::string name); + void setSingleMode(bool val); + void drawFilter(cv::Mat &frame, FilterValue &filter); + void drawEffects(cv::Mat &frame); + void filterFade(cv::Mat &frame, FilterValue &filter1, FilterValue &filter2, double alpha); + void reset_filters(); + void setSubFilter(int index); + void enableRepeat(bool re); +signals: + void procImage(const QImage image); + void stopRecording(); + void frameIncrement(); + void resetIndex(); + +}; + +#endif diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/plugin.cpp b/windows/Acid.Cam.Qt.Windows.March.2019/plugin.cpp new file mode 100755 index 0000000..b8ee5d3 --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/plugin.cpp @@ -0,0 +1,128 @@ + +/* + * Acid Cam v2 - Qt/OpenCV Edition + * written by Jared Bruni ( http://lostsidedead.com ) + * (C) 2017 GPL + */ + +#include "plugin.h" + +PluginList plugins; + +void add_directory(QDir &cdir, std::vector &files) { + cdir.setFilter(QDir::Files | QDir::Dirs); + QFileInfoList list = cdir.entryInfoList(); + int pos = 0; + QString platform; +#if defined(__linux__) + platform = ".so"; +#elif defined(__APPLE__) + platform = ".dylib"; +#else + platform = ".dll"; +#endif + while(pos < list.size()) { + QFileInfo info = list.at(pos); + if(info.isDir() && info.fileName() != "." && info.fileName() != "..") { + QDir cdir = info.dir(); + cdir.cd(info.fileName()); + add_directory(cdir, files); + ++pos; + continue; + } + else if(info.isFile() && info.fileName() != "." && info.fileName() != ".." && info.fileName().contains(platform)) { + files.push_back(info.filePath().toStdString()); + } + ++pos; + } +} + +void init_plugins() { + std::vector files; + QDir d("plugins"); + add_directory(d, files); + if(files.size()>0) { + for(unsigned int i = 0; i < files.size(); ++i) { + Plugin *p = new Plugin(); + if(p->loadPlugin(files[i])) + plugins.plugin_list.push_back(p); + } + } +} + +void draw_plugin(cv::Mat &frame, int filter) { + for(int z = 0; z < frame.rows; ++z) { + for(int i = 0; i < frame.cols; ++i) { + unsigned char rgb[3]; + cv::Vec3b &cpixel = frame.at(z, i); + rgb[0] = cpixel[0]; + rgb[1] = cpixel[1]; + rgb[2] = cpixel[2]; + plugins.plugin_list[filter]->call_Pixel(i, z, rgb); + cpixel[0] = rgb[0]; + cpixel[1] = rgb[1]; + cpixel[2] = rgb[2]; + } + } + plugins.plugin_list[filter]->call_Complete(); +} + + +void plugin_callback(cv::Mat &) { + +} + +Plugin::Plugin() { + library = 0; +} + +Plugin::~Plugin() { + if(library) delete library; +} + +bool Plugin::loadPlugin(const std::string &text) { + library = new QLibrary(text.c_str()); + if(!library) { + QMessageBox::information(0, QObject::tr("Could not load Library"), text.c_str()); + return false; + } + + pixel_function = (pixel) library->resolve("pixel"); + if(!pixel_function) { + QMessageBox::information(0, text.c_str(), "Could not find pixel function"); + return false; + } + + complete_function = (complete) library->resolve("complete"); + if(!complete_function) { + QMessageBox::information(0, text.c_str(), "Could not find complete function"); + return false; + } + mod_name = text; + return true; +} + + +void Plugin::call_Pixel(int x, int y, unsigned char *rgb) { + + if(pixel_function) + pixel_function(x, y, rgb); + +} +void Plugin::call_Complete() { + if(complete_function) + complete_function(); +} + +PluginList::PluginList() { + +} + +PluginList::~PluginList() { + if(plugin_list.size() == 0) return; + + for(auto i = plugin_list.begin(); i != plugin_list.end(); ++i) + delete *i; +} + + diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/plugin.h b/windows/Acid.Cam.Qt.Windows.March.2019/plugin.h new file mode 100755 index 0000000..e421cd6 --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/plugin.h @@ -0,0 +1,39 @@ +/* + * Acid Cam v2 - Qt/OpenCV Edition + * written by Jared Bruni ( http://lostsidedead.com ) + * (C) 2017 GPL + */ + +#ifndef _PLUGIN_H +#define _PLUGIN_H + +#include "qtheaders.h" + + +typedef void (*pixel)(int x, int y, unsigned char *buf); +typedef void (*complete)(); + +class Plugin { +public: + Plugin(); + ~Plugin(); + bool loadPlugin(const std::string &text); + void call_Pixel(int x, int y, unsigned char *rgb); + void call_Complete(); + std::string name() const { return mod_name; } +private: + pixel pixel_function; + complete complete_function; + QLibrary *library; + std::string mod_name; +}; + +class PluginList { +public: + PluginList(); + ~PluginList(); + std::vector plugin_list; +}; + +extern PluginList plugins; +#endif diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/qresource.qrc b/windows/Acid.Cam.Qt.Windows.March.2019/qresource.qrc new file mode 100755 index 0000000..4034009 --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/qresource.qrc @@ -0,0 +1,5 @@ + + +images/icon.png + + diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/qtheaders.h b/windows/Acid.Cam.Qt.Windows.March.2019/qtheaders.h new file mode 100755 index 0000000..ecdc3de --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/qtheaders.h @@ -0,0 +1,64 @@ +/* + * Acid Cam v2 - Qt/OpenCV Edition + * written by Jared Bruni ( http://lostsidedead.com ) + * (C) 2017 GPL + */ + +#ifndef _QT_HEADERS__ +#define _QT_HEADERS__ +#define ac_version "v1.28.2" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include"ac.h" +#include"fractal.h" +#include +#include +#include +#include +#include + +struct FilterValue { + int index, filter, subfilter; + FilterValue() : index(0), filter(0), subfilter(-1) {} + FilterValue(int i, int f, int s) : index(i), filter(f), subfilter(s) {} + FilterValue &operator=(const FilterValue &v) { + index = v.index; + filter = v.filter; + subfilter = v.subfilter; + return *this; + } +}; +void init_plugins(); +void draw_plugin(cv::Mat &frame, int filter); +extern std::unordered_map filter_map; + +#endif diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/search_box.cpp b/windows/Acid.Cam.Qt.Windows.March.2019/search_box.cpp new file mode 100755 index 0000000..394bdcb --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/search_box.cpp @@ -0,0 +1,90 @@ +#include"search_box.h" +#include"tokenize.h" + +std::string lowerString(std::string text) { + std::string new_text; + for(unsigned long i = 0; i < text.length(); ++i) + new_text += tolower(text[i]); + return new_text; +} + +SearchWindow::SearchWindow(QWidget *parent) : QDialog(parent) { + setFixedSize(640, 480); + setWindowTitle(tr("Search Filters")); + setWindowIcon(QPixmap(":/images/icon.png")); + createControls(); +} + + +void SearchWindow::createControls() { + search_list = new QListWidget(this); + search_list->setGeometry(25, 25, 595, 400); + search_list->show(); + search_text = new QLineEdit(this); + search_text->setGeometry(25, 430, 290, 30); + search_text->show(); + search = new QPushButton(this); + search->setGeometry(325, 430, 100, 30); + search->setText(tr("Search")); + subf = new QPushButton(this); + subf->setGeometry(490+25+10,430, 100, 30); + subf->setText(tr("SubFilter")); + add = new QPushButton(this); + add->setText(tr("Add")); + add->setGeometry((490+25+10)-100, 430, 100, 30); + connect(search, SIGNAL(pressed()), this, SLOT(search_filter())); + connect(add, SIGNAL(pressed()), this, SLOT(add_current())); + connect(subf, SIGNAL(pressed()), this, SLOT(set_subf())); +} + +void SearchWindow::search_filter() { + + while(search_list->count() > 0) { + search_list->takeItem(0); + } + + std::string search = lowerString(search_text->text().toStdString()); + std::vector tokens; + token::tokenize(search, std::string(" "), tokens); + + for(int i = 0; i < filters->count(); ++i) { + std::string search_items = lowerString(filters->itemText(i).toStdString()); + for(unsigned q = 0; q < tokens.size(); ++q) { + if(search_items.find(tokens[q]) != std::string::npos) { + search_list->addItem(filters->itemText(i)); + } + } + } +} + +void SearchWindow::add_current() { + int index = search_list->currentRow(); + if(index >= 0) { + QListWidgetItem *in = search_list->item(index); + custom_list->addItem(in->text()); + main_window->updateList(); + std::string text = in->text().toStdString(); + if(blend_set == false && text.find("Image") != std::string::npos) + main_window->Log(tr("Set an Image to use this filter\n")); + else if(text.find("SubFilter") != std::string::npos) + main_window->Log(tr("Set a SubFilter to use this filter\n")); + QString qtext; + QTextStream stream(&qtext); + stream << "Filter set to: " << in->text() << "\n"; + main_window->Log(qtext); + } +} + +void SearchWindow::setFiltersControl(QComboBox *filter_box, QListWidget *custombox) { + filters = filter_box; + custom_list = custombox; +} + +void SearchWindow::set_subf() { + int index = search_list->currentRow(); + if(index >= 0) { + QListWidgetItem *in = search_list->item(index); + main_window->setSubFilter(in->text()); + main_window->updateList(); + } +} diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/search_box.h b/windows/Acid.Cam.Qt.Windows.March.2019/search_box.h new file mode 100755 index 0000000..3b0f2c4 --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/search_box.h @@ -0,0 +1,27 @@ + +#ifndef __SEARCHBOX__H__ +#define __SEARCHBOX__H__ + +#include "qtheaders.h" +#include "main_window.h" + +class SearchWindow : public QDialog { + Q_OBJECT +public: + AC_MainWindow *main_window; + SearchWindow(QWidget *parent = 0); + void createControls(); + void setFiltersControl(QComboBox *filter_box, QListWidget *custom); +public slots: + void search_filter(); + void add_current(); + void set_subf(); +private: + QListWidget *search_list,*custom_list; + QLineEdit *search_text; + QPushButton *search, *add, *subf; + QComboBox *filters; +}; + +#endif + diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/select_image.cpp b/windows/Acid.Cam.Qt.Windows.March.2019/select_image.cpp new file mode 100755 index 0000000..eae9f23 --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/select_image.cpp @@ -0,0 +1 @@ +#include "select_image.h" diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/select_image.h b/windows/Acid.Cam.Qt.Windows.March.2019/select_image.h new file mode 100755 index 0000000..2bb3b90 --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/select_image.h @@ -0,0 +1,6 @@ +#ifndef __SELECT_IMAGE__ +#define __SELECT_IMAGE__ + +#include "qtheaders.h" + +#endif diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/tokenize.h b/windows/Acid.Cam.Qt.Windows.March.2019/tokenize.h new file mode 100755 index 0000000..9758a3c --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/tokenize.h @@ -0,0 +1,111 @@ +/* Acid Cam Functions for OpenCV + * written by Jared Bruni https://github.com/lostjared + + This software is dedicated to all the people that struggle with mental illness. + + Website: http://lostsidedead.com + YouTube: http://youtube.com/LostSideDead + Instagram: http://instagram.com/jaredbruni + Twitter: http://twitter.com/jaredbruni + Facebook: http://facebook.com/LostSideDead0x + + You can use this program free of charge and redistrubute as long + as you do not charge anything for this program. This program is 100% + Free. + + BSD 2-Clause License + + Copyright (c) 2018, Jared Bruni + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + */ + +#ifndef __TOKENIZE_H__ +#define __TOKENIZE_H__ + +#include +#include +#include + +namespace token { + + template + type substr(type t, size_t start, size_t stop) { + type temp; + for(size_t i = start; i < stop; i++) + temp += t[i]; + return temp; + } + + template<> char* substr(char *t, size_t start, size_t stop) { + char *temp = new char [ stop-start+1 ]; + size_t pos = 0; + for(size_t i = start; i < stop; i++) + temp[pos++] = t[i]; + temp[pos] = 0; + return temp; + } + + template + size_t len(type &t) { + size_t c = 0; + for(c = 0; t[c] != 0; c++); + return c; + } + + template + size_t find(size_t start, type& source, type& sub) { + for(size_t i = start; source[i] != 0; i++) { + bool add = true; + for(size_t z = 0; sub[z] != 0; z++) { + if(source[i+z] != sub[z]) { + add = false; + break; + } + } + if(add == true) + return i; + } + return 0; + } + + template + size_t tokenize(type source, type delim, std::vector &v) { + size_t i = find(0,source,delim),z=0; + if(i == 0) i = find(i+1, source,delim); + size_t lenz = len(source), dlen = len(delim); + while (i != 0 && i < lenz && z < lenz ) { + type s = substr(source,z,i); + if(len(s) > 0 && s[0] != delim[0]) + v.push_back(s); + z = i+dlen; + i = find(i+1, source, delim); + } + if( z < lenz ) v.push_back( substr(source,z,lenz) ); + return v.size(); + } +} + +#endif + diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/tokenize.hpp b/windows/Acid.Cam.Qt.Windows.March.2019/tokenize.hpp new file mode 100755 index 0000000..0a463ad --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/tokenize.hpp @@ -0,0 +1,112 @@ +/* + * Software written by Jared Bruni https://github.com/lostjared + + This software is dedicated to all the people that experience mental illness. + + Website: http://lostsidedead.com + YouTube: http://youtube.com/LostSideDead + Instagram: http://instagram.com/jaredbruni + Twitter: http://twitter.com/jaredbruni + Facebook: http://facebook.com/LostSideDead0x + + You can use this program free of charge and redistrubute it online as long + as you do not charge anything for this program. This program is meant to be + 100% free. + + BSD 2-Clause License + + Copyright (c) 2019, Jared Bruni + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + */ + + +#ifndef __TOKENIZE_H__ +#define __TOKENIZE_H__ + +#include +#include +#include + +namespace token { + + template + type substr(type t, size_t start, size_t stop) { + type temp; + for(size_t i = start; i < stop; i++) + temp += t[i]; + return temp; + } + + template<> char* substr(char *t, size_t start, size_t stop) { + char *temp = new char [ stop-start+1 ]; + size_t pos = 0; + for(size_t i = start; i < stop; i++) + temp[pos++] = t[i]; + temp[pos] = 0; + return temp; + } + + template + size_t len(type &t) { + size_t c = 0; + for(c = 0; t[c] != 0; c++); + return c; + } + + template + size_t find(size_t start, type& source, type& sub) { + for(size_t i = start; source[i] != 0; i++) { + bool add = true; + for(size_t z = 0; sub[z] != 0; z++) { + if(source[i+z] != sub[z]) { + add = false; + break; + } + } + if(add == true) + return i; + } + return 0; + } + + template + size_t tokenize(type source, type delim, std::vector &v) { + size_t i = find(0,source,delim),z=0; + if(i == 0) i = find(i+1, source,delim); + size_t lenz = len(source), dlen = len(delim); + while (i != 0 && i < lenz && z < lenz ) { + type s = substr(source,z,i); + if(len(s) > 0 && s[0] != delim[0]) + v.push_back(s); + z = i+dlen; + i = find(i+1, source, delim); + } + if( z < lenz ) v.push_back( substr(source,z,lenz) ); + return v.size(); + } +} + +#endif + diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/user_define.cpp b/windows/Acid.Cam.Qt.Windows.March.2019/user_define.cpp new file mode 100755 index 0000000..463760f --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/user_define.cpp @@ -0,0 +1,126 @@ + +#include "user_define.h" +#include "main_window.h" +#include +#include +#include + +DefineWindow::DefineWindow(QWidget *p) : QMainWindow(p) { + setFixedSize(640, 320); + setWindowTitle("Filter Define"); + createControls(); +} + +void DefineWindow::createControls() { + def_filters = new QComboBox(this); + def_filters->setGeometry(10, 10, 620, 30); + def_list = new QListWidget(this); + def_list->setGeometry(10, 50, 620, 200); + def_newname = new QLineEdit("", this); + def_newname->setGeometry(10, 260, 620, 25); + def_set = new QPushButton("Set", this); + def_set->setGeometry(10, 290, 100, 20); + def_clear = new QPushButton("Clear", this); + def_clear->setGeometry(120, 290, 100, 20); + def_save = new QPushButton("Save", this); + def_save->setGeometry(230, 290, 100, 20); + def_load = new QPushButton("Load", this); + def_load->setGeometry(340, 290, 100, 20); + + for(auto &i : ac::svAllSorted) { + def_filters->addItem(i.c_str()); + } + connect(def_set, SIGNAL(clicked()), this, SLOT(setFilterName())); + connect(def_clear, SIGNAL(clicked()), this, SLOT(clearFilterNames())); + connect(def_save, SIGNAL(clicked()), this, SLOT(saveNames())); + connect(def_load, SIGNAL(clicked()), this, SLOT(loadNames())); +} + +void DefineWindow::setFilterName() { + QString filter_name = def_filters->currentText(); + QString filter_text = def_newname->text(); + if(filter_text.length() > 0) { + std::string real_final_name = "User_"; + real_final_name += filter_text.toStdString(); + std::string sval = filter_name.toStdString(); + if(sval.find("Image") != std::string::npos) + real_final_name += "_Image"; + if(sval.find("SubFilter") != std::string::npos) + real_final_name += "_SubFilter"; + std::vector *v = ac::filter_menu_map["User"].menu_list; + v->push_back(real_final_name); + std::string ft = filter_name.toStdString(); + std::string fn = real_final_name; + filter_map[fn].index = 0; + filter_map[fn].filter = filter_map[ft].filter; + filter_map[fn].subfilter = -1; + main_window->resetMenu(); + def_list->addItem(real_final_name.c_str()); + def_newname->setText(""); + } +} +void DefineWindow::clearFilterNames() { + std::vector *v = ac::filter_menu_map["User"].menu_list; + if(!v->empty()) { + v->erase(v->begin(), v->end()); + v->push_back("No Filter"); + while(def_list->count() > 0) { + def_list->takeItem(0); + } + main_window->resetMenu(); + } +} + +void DefineWindow::saveNames() { + QString fileName = QFileDialog::getSaveFileName(this,tr("Save List"), "", tr("Acid Cam List (*.acl)")); + if(fileName.length() <= 0) + return; + std::fstream file; + file.open(fileName.toStdString(), std::ios::out); + if(!file.is_open()) { + QMessageBox::information(this, tr("Could not save file"), tr("Could not save file")); + return; + } + for(int index = 0; index < def_list->count(); ++index) { + QListWidgetItem *m = def_list->item(index); + std::string filter_name = m->text().toStdString(); + FilterValue &v = filter_map[filter_name]; + file << filter_name << ":" << v.filter << "\n"; + } + file.close(); +} + +void DefineWindow::loadNames() { + QString fileName = QFileDialog::getOpenFileName(this,tr("Open List"), "", tr("Acid Cam List (*.acl)")); + if(fileName.length() <= 0) + return; + std::fstream file(fileName.toStdString(), std::ios::in); + if(!file.is_open()) { + QMessageBox::information(this, tr("Could not open file"), tr("File could not be opened")); + return; + } + clearFilterNames(); + while(!file.eof()) { + std::string line; + std::getline(file, line); + if(file) { + std::string left, right; + auto pos = line.find(":"); + if(pos == std::string::npos) { + QMessageBox::information(this, tr("Invalid File Format"), tr("Invalid")); + return; + } + left = line.substr(0, pos); + right = line.substr(pos+1, line.length()-pos); + std::cout << "Left: " << left << "\n"; + std::cout << "Right: " << right << "\n"; + filter_map[left].index = 0; + filter_map[left].subfilter = -1; + filter_map[left].filter = atoi(right.c_str()); + def_list->addItem(left.c_str()); + std::vector *v = ac::filter_menu_map["User"].menu_list; + v->push_back(left); + } + } +} + diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/user_define.h b/windows/Acid.Cam.Qt.Windows.March.2019/user_define.h new file mode 100755 index 0000000..07135e9 --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/user_define.h @@ -0,0 +1,28 @@ +#ifndef __USER_DEFINE_H +#define __USER_DEFINE_H + +#include "qtheaders.h" + + +class AC_MainWindow; + +class DefineWindow : public QMainWindow { +Q_OBJECT +public: + DefineWindow(QWidget *p); + void createControls(); + AC_MainWindow *main_window; +public slots: + void setFilterName(); + void clearFilterNames(); + void saveNames(); + void loadNames(); +private: + QComboBox *def_filters; + QListWidget *def_list; + QLineEdit *def_newname; + QPushButton *def_set, *def_clear, *def_save, *def_load; +}; + + +#endif diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/win-icon.ico b/windows/Acid.Cam.Qt.Windows.March.2019/win-icon.ico new file mode 100755 index 0000000000000000000000000000000000000000..ab39b95fc335855d9b61840a1925019d58f2f78b GIT binary patch literal 280982 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 z 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 literal 0 HcmV?d00001 diff --git a/windows/Acid.Cam.Qt.Windows.March.2019/win-icon.rc b/windows/Acid.Cam.Qt.Windows.March.2019/win-icon.rc new file mode 100755 index 0000000..c29cbcd --- /dev/null +++ b/windows/Acid.Cam.Qt.Windows.March.2019/win-icon.rc @@ -0,0 +1 @@ +IDI_ICON1 ICON DISCARDABLE "win-icon.ico"

&3OP+$A(ldok)tHZiRUSZ71QyhYN#?c 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