├── .gitignore ├── .idea ├── codeStyleSettings.xml ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── encodings.xml ├── gradle.xml ├── gradle_extensions.xml ├── misc.xml ├── runConfigurations.xml └── vcs.xml ├── Index_of_Filters.md ├── Index_of_Filters_CN.md ├── README.md ├── README_CN.md ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── library ├── .gitignore ├── CMakeLists.txt ├── bintrayUpload.gradle ├── build.gradle ├── proguard-rules.pro ├── project.properties └── src │ ├── androidTest │ └── java │ │ └── cn │ │ └── co │ │ └── willow │ │ └── android │ │ └── ultimate │ │ └── gpuimage │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── cpp │ │ └── yuv-decoder.cpp │ └── java │ │ └── cn │ │ └── co │ │ └── willow │ │ └── android │ │ └── ultimate │ │ └── gpuimage │ │ ├── core_config │ │ ├── FilterConfig.java │ │ ├── OutputConfig.java │ │ ├── RecordCoderState.java │ │ ├── RecorderMessageState.java │ │ ├── RecorderState.java │ │ └── Rotation.java │ │ ├── core_looper │ │ ├── MessagesHandlerThread.java │ │ ├── PlayerQueueLock.java │ │ └── meta │ │ │ ├── CurrentItemMetaData.java │ │ │ └── MetaData.java │ │ ├── core_record_18 │ │ ├── TextureMovieEncoder.java │ │ ├── base_encoder │ │ │ ├── AudioEncoder.java │ │ │ ├── VideoEncoder.java │ │ │ └── XMediaMuxer.java │ │ └── gles │ │ │ ├── EGLCore.java │ │ │ ├── EGLSurfaceBase.java │ │ │ └── WindowSurface.java │ │ ├── core_render │ │ ├── BaseRenderer.java │ │ ├── PureImageRenderer.java │ │ └── VideoRecorderRenderer.java │ │ ├── core_render_filter │ │ ├── GPUImageFilter.java │ │ ├── GPUImageFilterGroup.java │ │ ├── base_filter │ │ │ ├── GPUImageBrightnessFilter.java │ │ │ ├── GPUImageContrastFilter.java │ │ │ ├── GPUImageExposureFilter.java │ │ │ ├── GPUImageGammaFilter.java │ │ │ ├── GPUImageGrayscaleFilter.java │ │ │ ├── GPUImageHighlightShadowFilter.java │ │ │ ├── GPUImageHueFilter.java │ │ │ ├── GPUImageLevelsFilter.java │ │ │ ├── GPUImageOpacityFilter.java │ │ │ ├── GPUImagePosterizeFilter.java │ │ │ ├── GPUImageRGBFilter.java │ │ │ ├── GPUImageSaturationFilter.java │ │ │ ├── GPUImageSharpenFilter.java │ │ │ ├── GPUImageToneCurveFilter.java │ │ │ └── GPUImageTransformFilter.java │ │ ├── blend_mode_filter │ │ │ ├── GPUImageAddBlendFilter.java │ │ │ ├── GPUImageChromaKeyBlendFilter.java │ │ │ ├── GPUImageColorBlendFilter.java │ │ │ ├── GPUImageColorBurnBlendFilter.java │ │ │ ├── GPUImageColorDodgeBlendFilter.java │ │ │ ├── GPUImageDarkenBlendFilter.java │ │ │ ├── GPUImageDifferenceBlendFilter.java │ │ │ ├── GPUImageDivideBlendFilter.java │ │ │ ├── GPUImageExclusionBlendFilter.java │ │ │ ├── GPUImageHardLightBlendFilter.java │ │ │ ├── GPUImageHueBlendFilter.java │ │ │ ├── GPUImageLightenBlendFilter.java │ │ │ ├── GPUImageLinearBurnBlendFilter.java │ │ │ ├── GPUImageLuminosityBlendFilter.java │ │ │ ├── GPUImageMultiplyBlendFilter.java │ │ │ ├── GPUImageOverlayBlendFilter.java │ │ │ ├── GPUImageSaturationBlendFilter.java │ │ │ ├── GPUImageScreenBlendFilter.java │ │ │ ├── GPUImageSimpleOverlayBlendFilter.java │ │ │ ├── GPUImageSoftLightBlendFilter.java │ │ │ ├── GPUImageSourceOverBlendFilter.java │ │ │ ├── GPUImageSubtractBlendFilter.java │ │ │ ├── GPUImageTwoInputFilter.java │ │ │ ├── color_mapping_blend │ │ │ │ └── GPUImageLookupFilter.java │ │ │ └── mix_control_blend │ │ │ │ ├── GPUImageAlphaBlendFilter.java │ │ │ │ ├── GPUImageDissolveBlendFilter.java │ │ │ │ └── GPUImageMixBlendFilter.java │ │ ├── color_enhance_filter │ │ │ ├── GPUImageBilateralFilter.java │ │ │ ├── GPUImageCGAColorspaceFilter.java │ │ │ ├── GPUImageColorBalanceFilter.java │ │ │ ├── GPUImageColorInvertFilter.java │ │ │ ├── GPUImageColorMatrixFilter.java │ │ │ ├── GPUImageFalseColorFilter.java │ │ │ ├── GPUImageMonochromeFilter.java │ │ │ └── GPUImageWhiteBalanceFilter.java │ │ ├── conversion_filter │ │ │ ├── GPUImageBulgeDistortionFilter.java │ │ │ ├── GPUImageCrosshatchFilter.java │ │ │ ├── GPUImageGlassSphereFilter.java │ │ │ ├── GPUImageSphereRefractionFilter.java │ │ │ ├── GPUImageSwirlFilter.java │ │ │ └── GPUImageVignetteFilter.java │ │ ├── filter_3x3_sampling │ │ │ ├── GPUImage3x3ConvolutionFilter.java │ │ │ ├── GPUImage3x3TextureSamplingFilter.java │ │ │ ├── GPUImageDirectionalSobelEdgeDetectionFilter.java │ │ │ ├── GPUImageLaplacianFilter.java │ │ │ ├── GPUImageNonMaximumSuppressionFilter.java │ │ │ ├── GPUImageSobelThresholdFilter.java │ │ │ └── GPUImageWeakPixelInclusionFilter.java │ │ ├── filter_dual_sampling │ │ │ ├── GPUImageBoxBlurFilter.java │ │ │ ├── GPUImageDilationFilter.java │ │ │ ├── GPUImageGaussianBlurFilter.java │ │ │ ├── GPUImageRGBDilationFilter.java │ │ │ └── GPUImageTwoPassTextureSamplingFilter.java │ │ ├── recommend_effect_filter │ │ │ ├── GPUImageCartoonFilter.java │ │ │ ├── GPUImageEmbossFilter.java │ │ │ ├── GPUImageHalftoneFilter.java │ │ │ ├── GPUImageHazeFilter.java │ │ │ ├── GPUImageKuwaharaFilter.java │ │ │ ├── GPUImagePixelationFilter.java │ │ │ └── GPUImageSepiaFilter.java │ │ └── recommend_effect_filter_group │ │ │ ├── GPUImageSketchFilter.java │ │ │ ├── GPUImageSmoothCartoonFilter.java │ │ │ ├── GPUImageSobelEdgeDetection.java │ │ │ └── GPUImageThresholdEdgeDetection.java │ │ ├── manager │ │ ├── image_editor │ │ │ ├── PureImageManager.java │ │ │ └── image_loader │ │ │ │ ├── BaseImageLoader.java │ │ │ │ ├── FileImageLoader.java │ │ │ │ └── UriImageLoader.java │ │ └── video_recorder │ │ │ ├── VideoFilterManager.java │ │ │ ├── VideoRecordConstrain.java │ │ │ ├── VideoRecordManager.java │ │ │ ├── VideoRecordManagerCallback.java │ │ │ └── record_messages │ │ │ ├── BaseMessage.java │ │ │ ├── BaseRecorderMessage.java │ │ │ ├── ClearRecordInstance.java │ │ │ ├── CreateNewRecordInstance.java │ │ │ ├── RecordPrepare.java │ │ │ ├── RecordRelease.java │ │ │ ├── RecordStart.java │ │ │ └── RecordStop.java │ │ ├── ui │ │ ├── FilterRecoderView.java │ │ └── ScalePlayerView.java │ │ └── utils │ │ ├── CameraUtil.java │ │ ├── GPUImageNativeLibrary.java │ │ ├── GlUtil.java │ │ ├── LogUtil.java │ │ ├── TextureRotationUtil.java │ │ └── gif_core │ │ ├── AnimatedGifEncoder.java │ │ ├── LZWEncoder.java │ │ └── NeuQuant.java │ └── test │ └── java │ └── cn │ └── co │ └── willow │ └── android │ └── ultimate │ └── gpuimage │ └── ExampleUnitTest.java ├── sample ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── cn │ │ └── co │ │ └── willow │ │ └── android │ │ └── ultimate │ │ └── gpuimage │ │ └── sample │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── cn │ │ │ └── co │ │ │ └── willow │ │ │ └── android │ │ │ └── ultimate │ │ │ └── gpuimage │ │ │ └── sample │ │ │ ├── SampleApplication.java │ │ │ ├── activity │ │ │ ├── SampleVideoActivity.java │ │ │ └── SplashActivity.java │ │ │ ├── function_holder │ │ │ ├── BaseHolder.java │ │ │ ├── VideoControlHolder.java │ │ │ ├── VideoPlayerDialog.java │ │ │ └── VideoRecordHolder.java │ │ │ ├── interaction_logic │ │ │ └── SamplePresenter.java │ │ │ ├── self_defined_filter │ │ │ ├── FilterType.java │ │ │ ├── GPUImageFace01Filter.java │ │ │ └── GPUImageFace02Filter.java │ │ │ └── util │ │ │ ├── FileUtil.java │ │ │ ├── TimeUtil.java │ │ │ └── UIUtils.java │ └── res │ │ ├── drawable-xxhdpi │ │ ├── filter_face01.png │ │ └── filter_face02.png │ │ ├── drawable │ │ ├── control_alert_camera_btn.xml │ │ ├── control_default_camera_btn.xml │ │ ├── oval_red_point.xml │ │ ├── rectangle_black_radius_bg.xml │ │ ├── rectangle_green_radius_bg.xml │ │ ├── rectangle_green_radius_bg_p.xml │ │ ├── rectangle_red_radius_bg.xml │ │ ├── rectangle_transparent.xml │ │ └── side_nav_bar.xml │ │ ├── layout │ │ ├── activity_sample.xml │ │ ├── activity_splash.xml │ │ ├── holder_video_controller.xml │ │ ├── holder_video_player.xml │ │ └── holder_video_recorder_gl.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── transition │ │ ├── trans_control_pannel.xml │ │ ├── trans_video_enter.xml │ │ ├── trans_video_exit.xml │ │ └── trans_video_player.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── drawables.xml │ │ ├── strings.xml │ │ ├── styles.xml │ │ └── trans_name.xml │ └── test │ └── java │ └── cn │ └── co │ └── willow │ └── android │ └── ultimate │ └── gpuimage │ └── sample │ └── ExampleUnitTest.java └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | libs/ 11 | 12 | # JCenter config # 13 | ############ 14 | library/bintray.properties 15 | .idea/modules.xml 16 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 19 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 21 | 22 | 34 | 44 | 45 | 46 | 47 | 48 | 49 | 51 | 52 | 53 | 54 | 55 | 1.8 56 | 57 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | jcenter() 6 | maven { 7 | url 'https://maven.google.com/' 8 | name 'Google' 9 | } 10 | } 11 | dependencies { 12 | classpath 'com.android.tools.build:gradle:3.0.1' 13 | classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1' //用于打包Maven所需文件 14 | classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.6' //用于上传Maven生成的文件到Bintray 15 | } 16 | } 17 | 18 | allprojects { 19 | repositories { 20 | jcenter() 21 | maven { 22 | url 'https://maven.google.com/' 23 | name 'Google' 24 | } 25 | } 26 | } 27 | 28 | task clean(type: Delete) { 29 | delete rootProject.buildDir 30 | } 31 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | org.gradle.jvmargs=-Xmx1536m 13 | 14 | # When configured, Gradle will run in incubating parallel mode. 15 | # This option should only be used with decoupled projects. More details, visit 16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 17 | # org.gradle.parallel=true 18 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Windsander/Android-UltimateGPUImage/0545cb66b1ad0fa74e495ed52877d7d6128061ba/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Tue Feb 06 16:30:12 CST 2018 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip 7 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /library/.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files # 2 | ########################### 3 | *.apk 4 | *.ap_ 5 | 6 | # Compiled source # 7 | ################### 8 | *.com 9 | *.class 10 | *.dll 11 | *.exe 12 | *.o 13 | *.dex 14 | 15 | ## Packages # 16 | ############# 17 | ## it's better to unpack these files and commit the raw source 18 | ## git has its own built in compression methods 19 | #*.7z 20 | #*.dmg 21 | #*.gz 22 | #*.iso 23 | #*.rar 24 | #*.tar 25 | #*.zip 26 | 27 | # Logs and databases # 28 | ###################### 29 | *.log 30 | 31 | # OS generated files # 32 | ###################### 33 | .DS_Store* 34 | ehthumbs.db 35 | Icon? 36 | Thumbs.db 37 | 38 | # Editor Files # 39 | ################ 40 | *~ 41 | *.swp 42 | 43 | # Gradle Files # 44 | ################ 45 | .gradle 46 | .gradletasknamecache 47 | .m2 48 | 49 | # Build output directies # 50 | ########################## 51 | target/ 52 | build/ 53 | /*/build 54 | .externalNativeBuild 55 | 56 | # IntelliJ specific files/directories # 57 | ####################################### 58 | out 59 | .idea 60 | *.ipr 61 | *.iws 62 | *.iml 63 | atlassian-ide-plugin.xml 64 | /local.properties 65 | /captures 66 | 67 | # Eclipse specific files/directories # 68 | ###################################### 69 | .classpath 70 | .project 71 | .settings 72 | .metadata 73 | bin/ 74 | 75 | # NetBeans specific files/directories # 76 | ####################################### 77 | .nbattrs 78 | /.nb-gradle/profiles/private/ 79 | .nb-gradle-properties 80 | 81 | # Scala build # 82 | ############### 83 | *.cache 84 | /.nb-gradle/private/ 85 | 86 | # Analysis # 87 | ############ 88 | *.hprof -------------------------------------------------------------------------------- /library/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # For more information about using CMake with Android Studio, read the 2 | # documentation: https://d.android.com/studio/projects/add-native-code.html 3 | 4 | cmake_minimum_required(VERSION 3.4.1) 5 | 6 | add_library( yuv-decoder SHARED src/main/cpp/yuv-decoder.cpp ) 7 | 8 | find_library( log-lib log ) 9 | 10 | target_link_libraries( yuv-decoder ${log-lib} ) -------------------------------------------------------------------------------- /library/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion 26 5 | buildToolsVersion "26.0.2" 6 | 7 | defaultConfig { 8 | minSdkVersion 18 9 | targetSdkVersion 26 10 | versionCode 50 11 | versionName "1.0.3" 12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 13 | 14 | externalNativeBuild { 15 | cmake { 16 | cppFlags "" 17 | } 18 | } 19 | } 20 | 21 | sourceSets { 22 | main { 23 | jniLibs.srcDirs 'jniLibs' 24 | } 25 | } 26 | 27 | buildTypes { 28 | release { 29 | minifyEnabled false 30 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 31 | } 32 | } 33 | 34 | externalNativeBuild { 35 | cmake { 36 | path "CMakeLists.txt" 37 | } 38 | } 39 | } 40 | 41 | dependencies { 42 | compile fileTree(dir: 'libs', include: ['*.jar']) 43 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 44 | exclude group: 'com.android.support', module: 'support-annotations' 45 | }) 46 | compile 'com.android.support:appcompat-v7:26.1.0' 47 | compile 'com.github.wseemann:FFmpegMediaMetadataRetriever:1.0.14' 48 | testCompile 'junit:junit:4.12' 49 | } 50 | apply from: "bintrayUpload.gradle" -------------------------------------------------------------------------------- /library/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in C:\DeveloperKits\Android\sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /library/project.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Windsander/Android-UltimateGPUImage/0545cb66b1ad0fa74e495ed52877d7d6128061ba/library/project.properties -------------------------------------------------------------------------------- /library/src/androidTest/java/cn/co/willow/android/ultimate/gpuimage/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumentation test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("cn.co.willow.android.ultimate.gpuimage", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /library/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_config/FilterConfig.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_config; 2 | 3 | /** 4 | * 滤镜基本配置 5 | *

6 | * Created by willow.li on 2016/10/27. 7 | */ 8 | public class FilterConfig { 9 | 10 | public static final int NO_TEXTURE = -1; // 无纹理标识 11 | 12 | public enum ScaleType { 13 | CENTER_INSIDE, 14 | CENTER_CROP 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_config/RecordCoderState.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_config; 2 | 3 | /** 4 | * 编码器状态枚举类 5 | *

6 | * Created by willow.li on 2016/10/27. 7 | */ 8 | public enum RecordCoderState { 9 | IDLE, 10 | PREPARED, 11 | START, 12 | STOP, 13 | ERROR, 14 | } 15 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_config/RecorderMessageState.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_config; 2 | 3 | /** 4 | * 消息状态枚举类 5 | * 模式:消息开始标志 -> 录制状态执行 -> 消息结束 6 | *

7 | * Created by willow.li on 2016/10/27. 8 | */ 9 | public enum RecorderMessageState { 10 | CLEAR_ALL, 11 | CLEAR_FINISH, 12 | IDLE, 13 | INITIALIZING, 14 | INITIALIZED, 15 | PREPARING, 16 | PREPARED, 17 | START_RECORD, 18 | RECORDING, 19 | STOPING, 20 | STOPED, 21 | RELEASE, 22 | ERROR 23 | } 24 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_config/RecorderState.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_config; 2 | 3 | /** 4 | * 录制状态枚举类 5 | *

6 | * Created by willow.li on 2016/10/27. 7 | */ 8 | public enum RecorderState { 9 | IDLE, 10 | INITIALIZE, 11 | INITIALIZED, 12 | PREPARED, 13 | RECORD, 14 | STOP, 15 | ERROR, 16 | } 17 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_config/Rotation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Willow 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.co.willow.android.ultimate.gpuimage.core_config; 18 | 19 | public enum Rotation { 20 | NORMAL, ROTATION_90, ROTATION_180, ROTATION_270; 21 | 22 | /** 23 | * Retrieves the int representation of the Rotation. 24 | * 25 | * @return 0, 90, 180 or 270 26 | */ 27 | public int asInt() { 28 | switch (this) { 29 | case NORMAL: return 0; 30 | case ROTATION_90: return 90; 31 | case ROTATION_180: return 180; 32 | case ROTATION_270: return 270; 33 | default: throw new IllegalStateException("Unknown Rotation!"); 34 | } 35 | } 36 | 37 | /** 38 | * Create a Rotation from an integer. Needs to be either 0, 90, 180 or 270. 39 | * 40 | * @param rotation 0, 90, 180 or 270 41 | * @return Rotation object 42 | */ 43 | public static Rotation fromInt(int rotation) { 44 | switch (rotation) { 45 | case 0: return NORMAL; 46 | case 90: return ROTATION_90; 47 | case 180: return ROTATION_180; 48 | case 270: return ROTATION_270; 49 | case 360: return NORMAL; 50 | default: throw new IllegalStateException( 51 | rotation + " is an unknown rotation. Needs to be either 0, 90, 180 or 270!"); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_looper/MessagesHandlerThread.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_looper; 2 | 3 | import java.util.List; 4 | import java.util.Queue; 5 | import java.util.concurrent.ConcurrentLinkedQueue; 6 | import java.util.concurrent.Executor; 7 | import java.util.concurrent.Executors; 8 | import java.util.concurrent.atomic.AtomicBoolean; 9 | 10 | import cn.co.willow.android.ultimate.gpuimage.manager.video_recorder.record_messages.BaseMessage; 11 | import cn.co.willow.android.ultimate.gpuimage.utils.LogUtil; 12 | 13 | /** 14 | * This class is designed to process a message queue. 15 | * It calls very specific methods of {@link BaseMessage} in very specific times. 16 | *

17 | * 1. When message is polled from queue it calls {@link BaseMessage#polledFromQueue()} 18 | * 2. When message should be run it calls {@link BaseMessage#runMessage()} 19 | * 3. When message finished running it calls {@link BaseMessage#messageFinished()} 20 | */ 21 | public class MessagesHandlerThread { 22 | 23 | private static final String TAG = MessagesHandlerThread.class.getSimpleName(); 24 | 25 | private final Queue mPlayerMessagesQueue = new ConcurrentLinkedQueue<>(); 26 | private final PlayerQueueLock mQueueLock = new PlayerQueueLock(); 27 | private final Executor mQueueProcessingThread = Executors.newSingleThreadExecutor(); 28 | 29 | private AtomicBoolean mTerminated = new AtomicBoolean(false); // TODO: use it 30 | private BaseMessage mLastMessage; 31 | 32 | public MessagesHandlerThread() { 33 | mQueueProcessingThread.execute(new Runnable() { 34 | @Override 35 | public void run() { 36 | do { 37 | mQueueLock.lock(TAG); 38 | if (mPlayerMessagesQueue.isEmpty()) { 39 | try { 40 | mQueueLock.wait(TAG); 41 | } catch (InterruptedException e) { 42 | e.printStackTrace(); 43 | throw new RuntimeException("InterruptedException"); 44 | } 45 | } 46 | mLastMessage = mPlayerMessagesQueue.poll(); 47 | mLastMessage.polledFromQueue(); 48 | mQueueLock.unlock(TAG); 49 | 50 | mLastMessage.runMessage(); 51 | 52 | mQueueLock.lock(TAG); 53 | mLastMessage.messageFinished(); 54 | mQueueLock.unlock(TAG); 55 | 56 | } while (!mTerminated.get()); 57 | 58 | } 59 | }); 60 | } 61 | 62 | /** 63 | * Use it if you need to NotifyDataChanged a single message 64 | */ 65 | public void addMessage(BaseMessage message) { 66 | mQueueLock.lock(TAG); 67 | mPlayerMessagesQueue.add(message); 68 | mQueueLock.notify(TAG); 69 | mQueueLock.unlock(TAG); 70 | } 71 | 72 | public void addMessages(List messages) { 73 | mQueueLock.lock(TAG); 74 | mPlayerMessagesQueue.addAll(messages); 75 | mQueueLock.notify(TAG); 76 | mQueueLock.unlock(TAG); 77 | } 78 | 79 | public void pauseQueueProcessing(String outer) { 80 | mQueueLock.lock(outer); 81 | } 82 | 83 | public void resumeQueueProcessing(String outer) { 84 | mQueueLock.unlock(outer); 85 | } 86 | 87 | public void clearAllPendingMessages(String outer) { 88 | if (mQueueLock.isLocked(outer)) { 89 | mPlayerMessagesQueue.clear(); 90 | } else { 91 | throw new RuntimeException("cannot perform action, you are not holding a lockVideoThread"); 92 | } 93 | } 94 | 95 | public void terminate() { 96 | mTerminated.set(true); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_looper/PlayerQueueLock.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_looper; 2 | 3 | import java.util.concurrent.locks.Condition; 4 | import java.util.concurrent.locks.ReentrantLock; 5 | 6 | import cn.co.willow.android.ultimate.gpuimage.utils.LogUtil; 7 | 8 | public class PlayerQueueLock { 9 | 10 | private static final String TAG = PlayerQueueLock.class.getSimpleName(); 11 | private static final boolean SHOW_LOGS = false; 12 | private final ReentrantLock mQueueLock = new ReentrantLock(); 13 | private final Condition mProcessQueueCondition = mQueueLock.newCondition(); 14 | 15 | public void lock(String owner) { 16 | if (SHOW_LOGS) LogUtil.v(TAG, ">> lockVideoThread, owner [" + owner + "]"); 17 | mQueueLock.lock(); 18 | if (SHOW_LOGS) LogUtil.v(TAG, "<< lockVideoThread, owner [" + owner + "]"); 19 | } 20 | 21 | public void unlock(String owner) { 22 | if (SHOW_LOGS) LogUtil.v(TAG, ">> unlock, owner [" + owner + "]"); 23 | mQueueLock.unlock(); 24 | if (SHOW_LOGS) LogUtil.v(TAG, "<< unlock, owner [" + owner + "]"); 25 | } 26 | 27 | public boolean isLocked(String owner) { 28 | boolean isLocked = mQueueLock.isLocked(); 29 | if (SHOW_LOGS) LogUtil.v(TAG, "isLocked, owner [" + owner + "]"); 30 | return isLocked; 31 | } 32 | 33 | public void wait(String owner) throws InterruptedException { 34 | if (SHOW_LOGS) LogUtil.v(TAG, ">> wait, owner [" + owner + "]"); 35 | mProcessQueueCondition.await(); 36 | if (SHOW_LOGS) LogUtil.v(TAG, "<< wait, owner [" + owner + "]"); 37 | } 38 | 39 | public void notify(String owner) { 40 | if (SHOW_LOGS) LogUtil.v(TAG, ">> notify, owner [" + owner + "]"); 41 | mProcessQueueCondition.signal(); 42 | if (SHOW_LOGS) LogUtil.v(TAG, "<< notify, owner [" + owner + "]"); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_looper/meta/CurrentItemMetaData.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_looper.meta; 2 | 3 | import android.view.View; 4 | 5 | public class CurrentItemMetaData implements MetaData { 6 | 7 | public final int positionOfCurrentItem; 8 | public final View currentItemView; 9 | 10 | public CurrentItemMetaData(int positionOfCurrentItem, View currentItemView) { 11 | this.positionOfCurrentItem = positionOfCurrentItem; 12 | this.currentItemView = currentItemView; 13 | } 14 | 15 | @Override 16 | public String toString() { 17 | return "CurrentItemMetaData{" + 18 | "positionOfCurrentItem=" + positionOfCurrentItem + 19 | ", currentItemView=" + currentItemView + 20 | '}'; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_looper/meta/MetaData.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_looper.meta; 2 | 3 | public interface MetaData { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_record_18/gles/WindowSurface.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 Google Inc. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.co.willow.android.ultimate.gpuimage.core_record_18.gles; 18 | 19 | import android.graphics.SurfaceTexture; 20 | import android.view.Surface; 21 | 22 | /** 23 | * Recordable EGL window surface. 24 | *

25 | * It's good practice to explicitly release() the surface, preferably from a "finally" block. 26 | */ 27 | public class WindowSurface extends EGLSurfaceBase { 28 | 29 | private Surface mSurface; 30 | private boolean mReleaseSurface; 31 | 32 | public WindowSurface(EGLCore eglCore, Surface surface, boolean releaseSurface) { 33 | super(eglCore); 34 | createWindowSurface(surface); 35 | mSurface = surface; 36 | mReleaseSurface = releaseSurface; 37 | } 38 | 39 | public WindowSurface(EGLCore eglCore, SurfaceTexture surfaceTexture) { 40 | super(eglCore); 41 | createWindowSurface(surfaceTexture); 42 | } 43 | 44 | 45 | /*对外暴露方法==================================================================================*/ 46 | public void release() { 47 | releaseEglSurface(); 48 | if (mSurface != null) { 49 | if (mReleaseSurface) { 50 | mSurface.release(); 51 | } 52 | mSurface = null; 53 | } 54 | } 55 | 56 | public void recreate(EGLCore newEGLCore) { 57 | if (mSurface == null) { 58 | throw new RuntimeException("not yet implemented for SurfaceTexture"); 59 | } 60 | mEGLCore = newEGLCore; // switch to new context 61 | createWindowSurface(mSurface); // create new surface 62 | } 63 | } -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render/PureImageRenderer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Willow 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.co.willow.android.ultimate.gpuimage.core_render; 18 | 19 | import android.annotation.TargetApi; 20 | import android.graphics.Bitmap; 21 | import android.graphics.Canvas; 22 | import android.opengl.GLES20; 23 | 24 | import cn.co.willow.android.ultimate.gpuimage.core_render_filter.GPUImageFilter; 25 | import cn.co.willow.android.ultimate.gpuimage.utils.GlUtil; 26 | 27 | import static cn.co.willow.android.ultimate.gpuimage.core_config.FilterConfig.NO_TEXTURE; 28 | 29 | @TargetApi(11) 30 | public class PureImageRenderer extends BaseRenderer { 31 | 32 | public PureImageRenderer(final GPUImageFilter filter) { 33 | super(filter); 34 | } 35 | 36 | 37 | /*参数配置====================================================================================*/ 38 | public void setImageBitmap(final Bitmap bitmap) { 39 | setImageBitmap(bitmap, true); 40 | } 41 | 42 | public void setImageBitmap(final Bitmap bitmap, final boolean recycle) { 43 | if (bitmap == null) { 44 | return; 45 | } 46 | 47 | runOnDraw(new Runnable() { 48 | 49 | @Override 50 | public void run() { 51 | Bitmap resizedBitmap = null; 52 | if (bitmap.getWidth() % 2 == 1) { 53 | resizedBitmap = Bitmap.createBitmap(bitmap.getWidth() + 1, bitmap.getHeight(), 54 | Bitmap.Config.ARGB_8888); 55 | Canvas can = new Canvas(resizedBitmap); 56 | can.drawARGB(0x00, 0x00, 0x00, 0x00); 57 | can.drawBitmap(bitmap, 0, 0, null); 58 | mAddedPadding = 1; 59 | } else { 60 | mAddedPadding = 0; 61 | } 62 | 63 | mGLTextureId = GlUtil.createTexture( 64 | resizedBitmap != null ? resizedBitmap : bitmap, 65 | mGLTextureId, 66 | recycle); 67 | if (resizedBitmap != null) { 68 | resizedBitmap.recycle(); 69 | } 70 | mImageWidth = bitmap.getWidth(); 71 | mImageHeight = bitmap.getHeight(); 72 | adjustImageScaling(); 73 | } 74 | }); 75 | } 76 | 77 | 78 | public void deleteImage() { 79 | runOnDraw(new Runnable() { 80 | 81 | @Override 82 | public void run() { 83 | GLES20.glDeleteTextures(1, new int[]{ 84 | mGLTextureId 85 | }, 0); 86 | mGLTextureId = NO_TEXTURE; 87 | } 88 | }); 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/base_filter/GPUImageBrightnessFilter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.base_filter; 2 | 3 | import android.opengl.GLES30; 4 | 5 | import cn.co.willow.android.ultimate.gpuimage.core_render_filter.GPUImageFilter; 6 | 7 | /** 8 | * 基础滤镜:亮度滤镜,值范围-1.0~1.0,0为正常值 9 | * brightness value ranges from -1.0 to 1.0, with 0.0 as the normal level 10 | */ 11 | public class GPUImageBrightnessFilter extends GPUImageFilter { 12 | public static final String BRIGHTNESS_FRAGMENT_SHADER = "" + 13 | "varying highp vec2 textureCoordinate;\n" + 14 | " \n" + 15 | " uniform sampler2D inputImageTexture;\n" + 16 | " uniform lowp float brightness;\n" + 17 | " \n" + 18 | " void main()\n" + 19 | " {\n" + 20 | " lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n" + 21 | " \n" + 22 | " gl_FragColor = vec4((textureColor.rgb + vec3(brightness)), textureColor.w);\n" + 23 | " }"; 24 | 25 | private int mBrightnessLocation; 26 | private float mBrightness; 27 | 28 | public GPUImageBrightnessFilter() { 29 | this(0.0f); 30 | } 31 | 32 | public GPUImageBrightnessFilter(final float brightness) { 33 | super(NO_FILTER_VERTEX_SHADER, BRIGHTNESS_FRAGMENT_SHADER); 34 | mBrightness = brightness; 35 | } 36 | 37 | @Override 38 | public void onInit() { 39 | super.onInit(); 40 | mBrightnessLocation = GLES30.glGetUniformLocation(getProgram(), "brightness"); 41 | } 42 | 43 | @Override 44 | public void onInitialized() { 45 | super.onInitialized(); 46 | setBrightness(mBrightness); 47 | } 48 | 49 | public void setBrightness(final float brightness) { 50 | mBrightness = brightness; 51 | setFloat(mBrightnessLocation, mBrightness); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/base_filter/GPUImageContrastFilter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.base_filter; 2 | 3 | import android.opengl.GLES30; 4 | 5 | import cn.co.willow.android.ultimate.gpuimage.core_render_filter.GPUImageFilter; 6 | 7 | /** 8 | * 基础滤镜:对比度滤镜,值范围 0.0~4.0,1.0为正常值 9 | * Changes the contrast of the image.
10 | *
11 | * contrast value ranges from 0.0 to 4.0, with 1.0 as the normal level 12 | */ 13 | public class GPUImageContrastFilter extends GPUImageFilter { 14 | public static final String CONTRAST_FRAGMENT_SHADER = "" + 15 | "varying highp vec2 textureCoordinate;\n" + 16 | " \n" + 17 | " uniform sampler2D inputImageTexture;\n" + 18 | " uniform lowp float contrast;\n" + 19 | " \n" + 20 | " void main()\n" + 21 | " {\n" + 22 | " lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n" + 23 | " \n" + 24 | " gl_FragColor = vec4(((textureColor.rgb - vec3(0.5)) * contrast + vec3(0.5)), textureColor.w);\n" + 25 | " }"; 26 | 27 | private int mContrastLocation; 28 | private float mContrast; 29 | 30 | public GPUImageContrastFilter() { 31 | this(1.2f); 32 | } 33 | 34 | public GPUImageContrastFilter(float contrast) { 35 | super(NO_FILTER_VERTEX_SHADER, CONTRAST_FRAGMENT_SHADER); 36 | mContrast = contrast; 37 | } 38 | 39 | @Override 40 | public void onInit() { 41 | super.onInit(); 42 | mContrastLocation = GLES30.glGetUniformLocation(getProgram(), "contrast"); 43 | } 44 | 45 | @Override 46 | public void onInitialized() { 47 | super.onInitialized(); 48 | setContrast(mContrast); 49 | } 50 | 51 | public void setContrast(final float contrast) { 52 | mContrast = contrast; 53 | setFloat(mContrastLocation, mContrast); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/base_filter/GPUImageExposureFilter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.base_filter; 2 | 3 | import android.opengl.GLES30; 4 | 5 | import cn.co.willow.android.ultimate.gpuimage.core_render_filter.GPUImageFilter; 6 | 7 | /** 8 | * 基础滤镜:曝光率滤镜,值范围 -10.0~10.0,0.0为正常值 9 | * exposure: The adjusted exposure (-10.0 - 10.0, with 0.0 as the default) 10 | */ 11 | public class GPUImageExposureFilter extends GPUImageFilter { 12 | public static final String EXPOSURE_FRAGMENT_SHADER = "" + 13 | " varying highp vec2 textureCoordinate;\n" + 14 | " \n" + 15 | " uniform sampler2D inputImageTexture;\n" + 16 | " uniform highp float exposure;\n" + 17 | " \n" + 18 | " void main()\n" + 19 | " {\n" + 20 | " highp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n" + 21 | " \n" + 22 | " gl_FragColor = vec4(textureColor.rgb * pow(2.0, exposure), textureColor.w);\n" + 23 | " } "; 24 | 25 | private int mExposureLocation; 26 | private float mExposure; 27 | 28 | public GPUImageExposureFilter() { 29 | this(1.0f); 30 | } 31 | 32 | public GPUImageExposureFilter(final float exposure) { 33 | super(NO_FILTER_VERTEX_SHADER, EXPOSURE_FRAGMENT_SHADER); 34 | mExposure = exposure; 35 | } 36 | 37 | @Override 38 | public void onInit() { 39 | super.onInit(); 40 | mExposureLocation = GLES30.glGetUniformLocation(getProgram(), "exposure"); 41 | } 42 | 43 | @Override 44 | public void onInitialized() { 45 | super.onInitialized(); 46 | setExposure(mExposure); 47 | } 48 | 49 | public void setExposure(final float exposure) { 50 | mExposure = exposure; 51 | setFloat(mExposureLocation, mExposure); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/base_filter/GPUImageGammaFilter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.base_filter; 2 | 3 | import android.opengl.GLES30; 4 | 5 | import cn.co.willow.android.ultimate.gpuimage.core_render_filter.GPUImageFilter; 6 | 7 | /** 8 | * 基础滤镜:伽马滤镜,值范围 0.0~3,1.0为正常值 9 | * gamma value ranges from 0.0 to 3.0, with 1.0 as the normal level 10 | */ 11 | public class GPUImageGammaFilter extends GPUImageFilter { 12 | 13 | public static final String GAMMA_FRAGMENT_SHADER = "" + 14 | "varying highp vec2 textureCoordinate;\n" + 15 | " \n" + 16 | " uniform sampler2D inputImageTexture;\n" + 17 | " uniform lowp float gamma;\n" + 18 | " \n" + 19 | " void main()\n" + 20 | " {\n" + 21 | " lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n" + 22 | " \n" + 23 | " gl_FragColor = vec4(pow(textureColor.rgb, vec3(gamma)), textureColor.w);\n" + 24 | " }"; 25 | 26 | private int mGammaLocation; 27 | private float mGamma; 28 | 29 | public GPUImageGammaFilter() { 30 | this(1.2f); 31 | } 32 | 33 | public GPUImageGammaFilter(final float gamma) { 34 | super(NO_FILTER_VERTEX_SHADER, GAMMA_FRAGMENT_SHADER); 35 | mGamma = gamma; 36 | } 37 | 38 | @Override 39 | public void onInit() { 40 | super.onInit(); 41 | mGammaLocation = GLES30.glGetUniformLocation(getProgram(), "gamma"); 42 | } 43 | 44 | @Override 45 | public void onInitialized() { 46 | super.onInitialized(); 47 | setGamma(mGamma); 48 | } 49 | 50 | public void setGamma(final float gamma) { 51 | mGamma = gamma; 52 | setFloat(mGammaLocation, mGamma); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/base_filter/GPUImageGrayscaleFilter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Willow 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.base_filter; 18 | 19 | import cn.co.willow.android.ultimate.gpuimage.core_render_filter.GPUImageFilter; 20 | 21 | /** 22 | * 基础滤镜:灰度效果滤镜 23 | * Applies a grayscale effect to the image. 24 | */ 25 | public class GPUImageGrayscaleFilter extends GPUImageFilter { 26 | public static final String GRAYSCALE_FRAGMENT_SHADER = "" + 27 | "precision highp float;\n" + 28 | "\n" + 29 | "varying vec2 textureCoordinate;\n" + 30 | "\n" + 31 | "uniform sampler2D inputImageTexture;\n" + 32 | "\n" + 33 | "const highp vec3 W = vec3(0.2125, 0.7154, 0.0721);\n" + 34 | "\n" + 35 | "void main()\n" + 36 | "{\n" + 37 | " lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n" + 38 | " float luminance = dot(textureColor.rgb, W);\n" + 39 | "\n" + 40 | " gl_FragColor = vec4(vec3(luminance), textureColor.a);\n" + 41 | "}"; 42 | 43 | public GPUImageGrayscaleFilter() { 44 | super(NO_FILTER_VERTEX_SHADER, GRAYSCALE_FRAGMENT_SHADER); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/base_filter/GPUImageHighlightShadowFilter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.base_filter; 2 | 3 | import android.opengl.GLES30; 4 | 5 | import cn.co.willow.android.ultimate.gpuimage.core_render_filter.GPUImageFilter; 6 | 7 | /** 8 | * 基础滤镜:高光阴影增强,值范围 0.0~1.0,0.0为正常值 9 | * Adjusts the shadows and highlights of an image 10 | * shadows: Increase to lighten shadows, from 0.0 to 1.0, with 0.0 as the default. 11 | * highlights: Decrease to darken highlights, from 0.0 to 1.0, with 1.0 as the default. 12 | */ 13 | public class GPUImageHighlightShadowFilter extends GPUImageFilter { 14 | public static final String HIGHLIGHT_SHADOW_FRAGMENT_SHADER = "" + 15 | " uniform sampler2D inputImageTexture;\n" + 16 | " varying highp vec2 textureCoordinate;\n" + 17 | " \n" + 18 | " uniform lowp float shadows;\n" + 19 | " uniform lowp float highlights;\n" + 20 | " \n" + 21 | " const mediump vec3 luminanceWeighting = vec3(0.3, 0.3, 0.3);\n" + 22 | " \n" + 23 | " void main()\n" + 24 | " {\n" + 25 | " lowp vec4 source = texture2D(inputImageTexture, textureCoordinate);\n" + 26 | " mediump float luminance = dot(source.rgb, luminanceWeighting);\n" + 27 | " \n" + 28 | " mediump float shadow = clamp((pow(luminance, 1.0/(shadows+1.0)) + (-0.76)*pow(luminance, 2.0/(shadows+1.0))) - luminance, 0.0, 1.0);\n" + 29 | " mediump float highlight = clamp((1.0 - (pow(1.0-luminance, 1.0/(2.0-highlights)) + (-0.8)*pow(1.0-luminance, 2.0/(2.0-highlights)))) - luminance, -1.0, 0.0);\n" + 30 | " lowp vec3 result = vec3(0.0, 0.0, 0.0) + ((luminance + shadow + highlight) - 0.0) * ((source.rgb - vec3(0.0, 0.0, 0.0))/(luminance - 0.0));\n" + 31 | " \n" + 32 | " gl_FragColor = vec4(result.rgb, source.a);\n" + 33 | " }"; 34 | 35 | private int mShadowsLocation; 36 | private float mShadows; 37 | private int mHighlightsLocation; 38 | private float mHighlights; 39 | 40 | public GPUImageHighlightShadowFilter() { 41 | this(0.0f, 1.0f); 42 | } 43 | 44 | public GPUImageHighlightShadowFilter(final float shadows, final float highlights) { 45 | super(NO_FILTER_VERTEX_SHADER, HIGHLIGHT_SHADOW_FRAGMENT_SHADER); 46 | mHighlights = highlights; 47 | mShadows = shadows; 48 | } 49 | 50 | @Override 51 | public void onInit() { 52 | super.onInit(); 53 | mHighlightsLocation = GLES30.glGetUniformLocation(getProgram(), "highlights"); 54 | mShadowsLocation = GLES30.glGetUniformLocation(getProgram(), "shadows"); 55 | } 56 | 57 | @Override 58 | public void onInitialized() { 59 | super.onInitialized(); 60 | setHighlights(mHighlights); 61 | setShadows(mShadows); 62 | } 63 | 64 | public void setHighlights(final float highlights) { 65 | mHighlights = highlights; 66 | setFloat(mHighlightsLocation, mHighlights); 67 | } 68 | 69 | public void setShadows(final float shadows) { 70 | mShadows = shadows; 71 | setFloat(mShadowsLocation, mShadows); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/base_filter/GPUImageHueFilter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.base_filter; 2 | 3 | import android.opengl.GLES30; 4 | 5 | import cn.co.willow.android.ultimate.gpuimage.core_render_filter.GPUImageFilter; 6 | 7 | /** 8 | * 基础滤镜:色调滤镜 9 | * give u ability to control images hue with this filter 10 | */ 11 | public class GPUImageHueFilter extends GPUImageFilter { 12 | public static final String HUE_FRAGMENT_SHADER = "" + 13 | "precision highp float;\n" + 14 | "varying highp vec2 textureCoordinate;\n" + 15 | "\n" + 16 | "uniform sampler2D inputImageTexture;\n" + 17 | "uniform mediump float hueAdjust;\n" + 18 | "const highp vec4 kRGBToYPrime = vec4 (0.299, 0.587, 0.114, 0.0);\n" + 19 | "const highp vec4 kRGBToI = vec4 (0.595716, -0.274453, -0.321263, 0.0);\n" + 20 | "const highp vec4 kRGBToQ = vec4 (0.211456, -0.522591, 0.31135, 0.0);\n" + 21 | "\n" + 22 | "const highp vec4 kYIQToR = vec4 (1.0, 0.9563, 0.6210, 0.0);\n" + 23 | "const highp vec4 kYIQToG = vec4 (1.0, -0.2721, -0.6474, 0.0);\n" + 24 | "const highp vec4 kYIQToB = vec4 (1.0, -1.1070, 1.7046, 0.0);\n" + 25 | "\n" + 26 | "void main ()\n" + 27 | "{\n" + 28 | " // Sample the input pixel\n" + 29 | " highp vec4 color = texture2D(inputImageTexture, textureCoordinate);\n" + 30 | "\n" + 31 | " // Convert to YIQ\n" + 32 | " highp float YPrime = dot (color, kRGBToYPrime);\n" + 33 | " highp float I = dot (color, kRGBToI);\n" + 34 | " highp float Q = dot (color, kRGBToQ);\n" + 35 | "\n" + 36 | " // Calculate the hue and chroma\n" + 37 | " highp float hue = atan (Q, I);\n" + 38 | " highp float chroma = sqrt (I * I + Q * Q);\n" + 39 | "\n" + 40 | " // Make the user's adjustments\n" + 41 | " hue += (-hueAdjust); //why negative rotation?\n" + 42 | "\n" + 43 | " // Convert back to YIQ\n" + 44 | " Q = chroma * sin (hue);\n" + 45 | " I = chroma * cos (hue);\n" + 46 | "\n" + 47 | " // Convert back to RGB\n" + 48 | " highp vec4 yIQ = vec4 (YPrime, I, Q, 0.0);\n" + 49 | " color.r = dot (yIQ, kYIQToR);\n" + 50 | " color.g = dot (yIQ, kYIQToG);\n" + 51 | " color.b = dot (yIQ, kYIQToB);\n" + 52 | "\n" + 53 | " // Save the result\n" + 54 | " gl_FragColor = color;\n" + 55 | "}\n"; 56 | 57 | private float mHue; 58 | private int mHueLocation; 59 | 60 | public GPUImageHueFilter() { 61 | this(90.0f); 62 | } 63 | 64 | public GPUImageHueFilter(final float hue) { 65 | super(NO_FILTER_VERTEX_SHADER, HUE_FRAGMENT_SHADER); 66 | mHue = hue; 67 | } 68 | 69 | @Override 70 | public void onInit() { 71 | super.onInit(); 72 | mHueLocation = GLES30.glGetUniformLocation(getProgram(), "hueAdjust"); 73 | } 74 | 75 | @Override 76 | public void onInitialized() { 77 | super.onInitialized(); 78 | setHue(mHue); 79 | } 80 | 81 | public void setHue(final float hue) { 82 | mHue = hue; 83 | float hueAdjust = (mHue % 360.0f) * (float) Math.PI / 180.0f; 84 | setFloat(mHueLocation, hueAdjust); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/base_filter/GPUImageOpacityFilter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Willow 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.base_filter; 18 | 19 | import android.opengl.GLES30; 20 | 21 | import cn.co.willow.android.ultimate.gpuimage.core_render_filter.GPUImageFilter; 22 | 23 | /** 24 | * 基础滤镜:不透明度调节,值范围 0.0~1.0,1.0为正常值 25 | * Adjusts the alpha channel of the incoming image 26 | * opacity: The value to multiply the incoming alpha channel for each pixel by (0.0 - 1.0, with 1.0 as the default) 27 | */ 28 | public class GPUImageOpacityFilter extends GPUImageFilter { 29 | public static final String OPACITY_FRAGMENT_SHADER = "" + 30 | " varying highp vec2 textureCoordinate;\n" + 31 | " \n" + 32 | " uniform sampler2D inputImageTexture;\n" + 33 | " uniform lowp float opacity;\n" + 34 | " \n" + 35 | " void main()\n" + 36 | " {\n" + 37 | " lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n" + 38 | " \n" + 39 | " gl_FragColor = vec4(textureColor.rgb, textureColor.a * opacity);\n" + 40 | " }\n"; 41 | 42 | private int mOpacityLocation; 43 | private float mOpacity; 44 | 45 | public GPUImageOpacityFilter() { 46 | this(1.0f); 47 | } 48 | 49 | public GPUImageOpacityFilter(final float opacity) { 50 | super(NO_FILTER_VERTEX_SHADER, OPACITY_FRAGMENT_SHADER); 51 | mOpacity = opacity; 52 | } 53 | 54 | @Override 55 | public void onInit() { 56 | super.onInit(); 57 | mOpacityLocation = GLES30.glGetUniformLocation(getProgram(), "opacity"); 58 | } 59 | 60 | @Override 61 | public void onInitialized() { 62 | super.onInitialized(); 63 | setOpacity(mOpacity); 64 | } 65 | 66 | public void setOpacity(final float opacity) { 67 | mOpacity = opacity; 68 | setFloat(mOpacityLocation, mOpacity); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/base_filter/GPUImagePosterizeFilter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.base_filter; 2 | 3 | import android.opengl.GLES30; 4 | 5 | import cn.co.willow.android.ultimate.gpuimage.core_render_filter.GPUImageFilter; 6 | 7 | /** 8 | * 基础滤镜:色调分离,形成噪点效果,值范围 1~256,10为正常值 9 | * Reduces the color range of the image.
10 | *
11 | * colorLevels: ranges from 1 to 256, with a default of 10 12 | */ 13 | public class GPUImagePosterizeFilter extends GPUImageFilter { 14 | public static final String POSTERIZE_FRAGMENT_SHADER = "" + 15 | "varying highp vec2 textureCoordinate;\n" + 16 | "\n" + 17 | "uniform sampler2D inputImageTexture;\n" + 18 | "uniform highp float colorLevels;\n" + 19 | "\n" + 20 | "void main()\n" + 21 | "{\n" + 22 | " highp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n" + 23 | " \n" + 24 | " gl_FragColor = floor((textureColor * colorLevels) + vec4(0.5)) / colorLevels;\n" + 25 | "}"; 26 | 27 | private int mGLUniformColorLevels; 28 | private int mColorLevels; 29 | 30 | public GPUImagePosterizeFilter() { 31 | this(10); 32 | } 33 | 34 | public GPUImagePosterizeFilter(final int colorLevels) { 35 | super(GPUImageFilter.NO_FILTER_VERTEX_SHADER, POSTERIZE_FRAGMENT_SHADER); 36 | mColorLevels = colorLevels; 37 | } 38 | 39 | @Override 40 | public void onInit() { 41 | super.onInit(); 42 | mGLUniformColorLevels = GLES30.glGetUniformLocation(getProgram(), "colorLevels"); 43 | setColorLevels(mColorLevels); 44 | } 45 | 46 | public void setColorLevels(final int colorLevels) { 47 | mColorLevels = colorLevels; 48 | setFloat(mGLUniformColorLevels, colorLevels); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/base_filter/GPUImageRGBFilter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.base_filter; 2 | 3 | import android.opengl.GLES30; 4 | 5 | import cn.co.willow.android.ultimate.gpuimage.core_render_filter.GPUImageFilter; 6 | 7 | /** 8 | * RGB 三原色调整 9 | * Adjusts the individual RGB channels of an image 10 | * red: Normalized values by which each color channel is multiplied. The range is from 0.0 up, with 1.0 as the default. 11 | * green: 12 | * blue: 13 | */ 14 | public class GPUImageRGBFilter extends GPUImageFilter { 15 | public static final String RGB_FRAGMENT_SHADER = "" + 16 | " varying highp vec2 textureCoordinate;\n" + 17 | " \n" + 18 | " uniform sampler2D inputImageTexture;\n" + 19 | " uniform highp float red;\n" + 20 | " uniform highp float green;\n" + 21 | " uniform highp float blue;\n" + 22 | " \n" + 23 | " void main()\n" + 24 | " {\n" + 25 | " highp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n" + 26 | " \n" + 27 | " gl_FragColor = vec4(textureColor.r * red, textureColor.g * green, textureColor.b * blue, 1.0);\n" + 28 | " }\n"; 29 | 30 | private int mRedLocation; 31 | private float mRed; 32 | private int mGreenLocation; 33 | private float mGreen; 34 | private int mBlueLocation; 35 | private float mBlue; 36 | private boolean mIsInitialized = false; 37 | 38 | public GPUImageRGBFilter() { 39 | this(1.0f, 1.0f, 1.0f); 40 | } 41 | 42 | public GPUImageRGBFilter(final float red, final float green, final float blue) { 43 | super(NO_FILTER_VERTEX_SHADER, RGB_FRAGMENT_SHADER); 44 | mRed = red; 45 | mGreen = green; 46 | mBlue = blue; 47 | } 48 | 49 | @Override 50 | public void onInit() { 51 | super.onInit(); 52 | mRedLocation = GLES30.glGetUniformLocation(getProgram(), "red"); 53 | mGreenLocation = GLES30.glGetUniformLocation(getProgram(), "green"); 54 | mBlueLocation = GLES30.glGetUniformLocation(getProgram(), "blue"); 55 | mIsInitialized = true; 56 | setRed(mRed); 57 | setGreen(mGreen); 58 | setBlue(mBlue); 59 | } 60 | 61 | public void setRed(final float red) { 62 | mRed = red; 63 | if (mIsInitialized) { 64 | setFloat(mRedLocation, mRed); 65 | } 66 | } 67 | 68 | public void setGreen(final float green) { 69 | mGreen = green; 70 | if (mIsInitialized) { 71 | setFloat(mGreenLocation, mGreen); 72 | } 73 | } 74 | 75 | public void setBlue(final float blue) { 76 | mBlue = blue; 77 | if (mIsInitialized) { 78 | setFloat(mBlueLocation, mBlue); 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/base_filter/GPUImageSaturationFilter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.base_filter; 2 | 3 | import android.opengl.GLES30; 4 | 5 | import cn.co.willow.android.ultimate.gpuimage.core_render_filter.GPUImageFilter; 6 | 7 | /** 8 | * 基础滤镜:饱和度,值范围 0.0~2.0,1.0为正常值 9 | * saturation: The degree of saturation or desaturation to apply to the image (0.0 - 2.0, with 1.0 as the default) 10 | */ 11 | public class GPUImageSaturationFilter extends GPUImageFilter { 12 | public static final String SATURATION_FRAGMENT_SHADER = "" + 13 | " varying highp vec2 textureCoordinate;\n" + 14 | " \n" + 15 | " uniform sampler2D inputImageTexture;\n" + 16 | " uniform lowp float saturation;\n" + 17 | " \n" + 18 | " // Values from \"Graphics Shaders: Theory and Practice\" by Bailey and Cunningham\n" + 19 | " const mediump vec3 luminanceWeighting = vec3(0.2125, 0.7154, 0.0721);\n" + 20 | " \n" + 21 | " void main()\n" + 22 | " {\n" + 23 | " lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n" + 24 | " lowp float luminance = dot(textureColor.rgb, luminanceWeighting);\n" + 25 | " lowp vec3 greyScaleColor = vec3(luminance);\n" + 26 | " \n" + 27 | " gl_FragColor = vec4(mix(greyScaleColor, textureColor.rgb, saturation), textureColor.w);\n" + 28 | " \n" + 29 | " }"; 30 | 31 | private int mSaturationLocation; 32 | private float mSaturation; 33 | 34 | public GPUImageSaturationFilter() { 35 | this(1.0f); 36 | } 37 | 38 | public GPUImageSaturationFilter(final float saturation) { 39 | super(NO_FILTER_VERTEX_SHADER, SATURATION_FRAGMENT_SHADER); 40 | mSaturation = saturation; 41 | } 42 | 43 | @Override 44 | public void onInit() { 45 | super.onInit(); 46 | mSaturationLocation = GLES30.glGetUniformLocation(getProgram(), "saturation"); 47 | } 48 | 49 | @Override 50 | public void onInitialized() { 51 | super.onInitialized(); 52 | setSaturation(mSaturation); 53 | } 54 | 55 | public void setSaturation(final float saturation) { 56 | mSaturation = saturation; 57 | setFloat(mSaturationLocation, mSaturation); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/blend_mode_filter/GPUImageAddBlendFilter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.blend_mode_filter; 2 | 3 | /** 4 | * 图片混合滤镜,通常用于创建两个图像之间的动画变亮模糊效果 5 | * always use to create animation, which do lighten and blur between 2 images 6 | */ 7 | public class GPUImageAddBlendFilter extends GPUImageTwoInputFilter { 8 | 9 | public static final String ADD_BLEND_FRAGMENT_SHADER = "" + 10 | "varying highp vec2 textureCoordinate;\n" + 11 | " varying highp vec2 textureCoordinate2;\n" + 12 | "\n" + 13 | " uniform sampler2D inputImageTexture;\n" + 14 | " uniform sampler2D inputImageTexture2;\n" + 15 | " \n" + 16 | " void main()\n" + 17 | " {\n" + 18 | " lowp vec4 base = texture2D(inputImageTexture, textureCoordinate);\n" + 19 | " lowp vec4 overlay = texture2D(inputImageTexture2, textureCoordinate2);\n" + 20 | "\n" + 21 | " mediump float r;\n" + 22 | " if (overlay.r * base.a + base.r * overlay.a >= overlay.a * base.a) {\n" + 23 | " r = overlay.a * base.a + overlay.r * (1.0 - base.a) + base.r * (1.0 - overlay.a);\n" + 24 | " } else {\n" + 25 | " r = overlay.r + base.r;\n" + 26 | " }\n" + 27 | "\n" + 28 | " mediump float g;\n" + 29 | " if (overlay.g * base.a + base.g * overlay.a >= overlay.a * base.a) {\n" + 30 | " g = overlay.a * base.a + overlay.g * (1.0 - base.a) + base.g * (1.0 - overlay.a);\n" + 31 | " } else {\n" + 32 | " g = overlay.g + base.g;\n" + 33 | " }\n" + 34 | "\n" + 35 | " mediump float b;\n" + 36 | " if (overlay.b * base.a + base.b * overlay.a >= overlay.a * base.a) {\n" + 37 | " b = overlay.a * base.a + overlay.b * (1.0 - base.a) + base.b * (1.0 - overlay.a);\n" + 38 | " } else {\n" + 39 | " b = overlay.b + base.b;\n" + 40 | " }\n" + 41 | "\n" + 42 | " mediump float a = overlay.a + base.a - overlay.a * base.a;\n" + 43 | " \n" + 44 | " gl_FragColor = vec4(r, g, b, a);\n" + 45 | " }"; 46 | 47 | public GPUImageAddBlendFilter() { 48 | super(ADD_BLEND_FRAGMENT_SHADER); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/blend_mode_filter/GPUImageColorBlendFilter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.blend_mode_filter; 2 | 3 | /** 4 | * 配色滤镜,将第二张作为着色层的图片渲染到第一张图片上,替换对应颜色 5 | */ 6 | public class GPUImageColorBlendFilter extends GPUImageTwoInputFilter { 7 | 8 | public static final String COLOR_BLEND_FRAGMENT_SHADER = "" + 9 | "varying highp vec2 textureCoordinate;\n" + 10 | " varying highp vec2 textureCoordinate2;\n" + 11 | " \n" + 12 | " uniform sampler2D inputImageTexture;\n" + 13 | " uniform sampler2D inputImageTexture2;\n" + 14 | " \n" + 15 | " highp float lum(lowp vec3 c) {\n" + 16 | " return dot(c, vec3(0.3, 0.59, 0.11));\n" + 17 | " }\n" + 18 | " \n" + 19 | " lowp vec3 clipcolor(lowp vec3 c) {\n" + 20 | " highp float l = lum(c);\n" + 21 | " lowp float n = min(min(c.r, c.g), c.b);\n" + 22 | " lowp float x = max(max(c.r, c.g), c.b);\n" + 23 | " \n" + 24 | " if (n < 0.0) {\n" + 25 | " c.r = l + ((c.r - l) * l) / (l - n);\n" + 26 | " c.g = l + ((c.g - l) * l) / (l - n);\n" + 27 | " c.b = l + ((c.b - l) * l) / (l - n);\n" + 28 | " }\n" + 29 | " if (x > 1.0) {\n" + 30 | " c.r = l + ((c.r - l) * (1.0 - l)) / (x - l);\n" + 31 | " c.g = l + ((c.g - l) * (1.0 - l)) / (x - l);\n" + 32 | " c.b = l + ((c.b - l) * (1.0 - l)) / (x - l);\n" + 33 | " }\n" + 34 | " \n" + 35 | " return c;\n" + 36 | " }\n" + 37 | "\n" + 38 | " lowp vec3 setlum(lowp vec3 c, highp float l) {\n" + 39 | " highp float d = l - lum(c);\n" + 40 | " c = c + vec3(d);\n" + 41 | " return clipcolor(c);\n" + 42 | " }\n" + 43 | " \n" + 44 | " void main()\n" + 45 | " {\n" + 46 | " highp vec4 baseColor = texture2D(inputImageTexture, textureCoordinate);\n" + 47 | " highp vec4 overlayColor = texture2D(inputImageTexture2, textureCoordinate2);\n" + 48 | "\n" + 49 | " gl_FragColor = vec4(baseColor.rgb * (1.0 - overlayColor.a) + setlum(overlayColor.rgb, lum(baseColor.rgb)) * overlayColor.a, baseColor.a);\n" + 50 | " }"; 51 | 52 | public GPUImageColorBlendFilter() { 53 | super(COLOR_BLEND_FRAGMENT_SHADER); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/blend_mode_filter/GPUImageColorBurnBlendFilter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.blend_mode_filter; 2 | 3 | /** 4 | * 色彩加深混合滤镜,效果是第一张图将会以类似蒙皮的形式覆盖在第二张图纸上,形成组合 5 | * the second image will be covered by first image, looks like a skin. 6 | * can use to develop some text effect 7 | */ 8 | public class GPUImageColorBurnBlendFilter extends GPUImageTwoInputFilter { 9 | 10 | public static final String COLOR_BURN_BLEND_FRAGMENT_SHADER = "" + 11 | "varying highp vec2 textureCoordinate;\n" + 12 | " varying highp vec2 textureCoordinate2;\n" + 13 | "\n" + 14 | " uniform sampler2D inputImageTexture;\n" + 15 | " uniform sampler2D inputImageTexture2;\n" + 16 | " \n" + 17 | " void main()\n" + 18 | " {\n" + 19 | " mediump vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n" + 20 | " mediump vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);\n" + 21 | " mediump vec4 whiteColor = vec4(1.0);\n" + 22 | " gl_FragColor = whiteColor - (whiteColor - textureColor) / textureColor2;\n" + 23 | " }"; 24 | 25 | public GPUImageColorBurnBlendFilter() { 26 | super(COLOR_BURN_BLEND_FRAGMENT_SHADER); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/blend_mode_filter/GPUImageColorDodgeBlendFilter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.blend_mode_filter; 2 | 3 | /** 4 | * 色彩减淡混合滤镜,会按照第二张图来抵消同位置的第一张图的对应位置颜色效果 5 | * will use second image to decrease the first image color level at certain place. 6 | */ 7 | public class GPUImageColorDodgeBlendFilter extends GPUImageTwoInputFilter { 8 | 9 | public static final String COLOR_DODGE_BLEND_FRAGMENT_SHADER = "" + 10 | "precision mediump float;\n" + 11 | " \n" + 12 | " varying highp vec2 textureCoordinate;\n" + 13 | " varying highp vec2 textureCoordinate2;\n" + 14 | " \n" + 15 | " uniform sampler2D inputImageTexture;\n" + 16 | " uniform sampler2D inputImageTexture2;\n" + 17 | " \n" + 18 | " void main()\n" + 19 | " {\n" + 20 | " vec4 base = texture2D(inputImageTexture, textureCoordinate);\n" + 21 | " vec4 overlay = texture2D(inputImageTexture2, textureCoordinate2);\n" + 22 | " \n" + 23 | " vec3 baseOverlayAlphaProduct = vec3(overlay.a * base.a);\n" + 24 | " vec3 rightHandProduct = overlay.rgb * (1.0 - base.a) + base.rgb * (1.0 - overlay.a);\n" + 25 | " \n" + 26 | " vec3 firstBlendColor = baseOverlayAlphaProduct + rightHandProduct;\n" + 27 | " vec3 overlayRGB = clamp((overlay.rgb / clamp(overlay.a, 0.01, 1.0)) * step(0.0, overlay.a), 0.0, 0.99);\n" + 28 | " \n" + 29 | " vec3 secondBlendColor = (base.rgb * overlay.a) / (1.0 - overlayRGB) + rightHandProduct;\n" + 30 | " \n" + 31 | " vec3 colorChoice = step((overlay.rgb * base.a + base.rgb * overlay.a), baseOverlayAlphaProduct);\n" + 32 | " \n" + 33 | " gl_FragColor = vec4(mix(firstBlendColor, secondBlendColor, colorChoice), 1.0);\n" + 34 | " }"; 35 | 36 | public GPUImageColorDodgeBlendFilter() { 37 | super(COLOR_DODGE_BLEND_FRAGMENT_SHADER); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/blend_mode_filter/GPUImageDarkenBlendFilter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.blend_mode_filter; 2 | 3 | /** 4 | * 加深混合,通常用于重叠类型,可以类推Proter&Duff 的 darken 渲染模式 5 | */ 6 | public class GPUImageDarkenBlendFilter extends GPUImageTwoInputFilter { 7 | 8 | public static final String DARKEN_BLEND_FRAGMENT_SHADER = "" + 9 | "varying highp vec2 textureCoordinate;\n" + 10 | " varying highp vec2 textureCoordinate2;\n" + 11 | "\n" + 12 | " uniform sampler2D inputImageTexture;\n" + 13 | " uniform sampler2D inputImageTexture2;\n" + 14 | " \n" + 15 | " void main()\n" + 16 | " {\n" + 17 | " lowp vec4 base = texture2D(inputImageTexture, textureCoordinate);\n" + 18 | " lowp vec4 overlayer = texture2D(inputImageTexture2, textureCoordinate2);\n" + 19 | " \n" + 20 | " gl_FragColor = vec4(min(overlayer.rgb * base.a, base.rgb * overlayer.a) + overlayer.rgb * (1.0 - base.a) + base.rgb * (1.0 - overlayer.a), 1.0);\n" + 21 | " }"; 22 | 23 | public GPUImageDarkenBlendFilter() { 24 | super(DARKEN_BLEND_FRAGMENT_SHADER); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/blend_mode_filter/GPUImageDifferenceBlendFilter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.blend_mode_filter; 2 | 3 | /** 4 | * 差异混合,通常用于创建更多变动的颜色 5 | */ 6 | public class GPUImageDifferenceBlendFilter extends GPUImageTwoInputFilter { 7 | 8 | public static final String DIFFERENCE_BLEND_FRAGMENT_SHADER = "" + 9 | "varying highp vec2 textureCoordinate;\n" + 10 | " varying highp vec2 textureCoordinate2;\n" + 11 | "\n" + 12 | " uniform sampler2D inputImageTexture;\n" + 13 | " uniform sampler2D inputImageTexture2;\n" + 14 | " \n" + 15 | " void main()\n" + 16 | " {\n" + 17 | " mediump vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n" + 18 | " mediump vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);\n" + 19 | " gl_FragColor = vec4(abs(textureColor2.rgb - textureColor.rgb), textureColor.a);\n" + 20 | " }"; 21 | 22 | public GPUImageDifferenceBlendFilter() { 23 | super(DIFFERENCE_BLEND_FRAGMENT_SHADER); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/blend_mode_filter/GPUImageDivideBlendFilter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.blend_mode_filter; 2 | 3 | /** 4 | * 通常用于创建两个图像之间的动画变暗模糊效果 5 | * always use to create animation, which do draken and blur between 2 images 6 | */ 7 | public class GPUImageDivideBlendFilter extends GPUImageTwoInputFilter { 8 | public static final String DIVIDE_BLEND_FRAGMENT_SHADER = "varying highp vec2 textureCoordinate;\n" + 9 | " varying highp vec2 textureCoordinate2;\n" + 10 | "\n" + 11 | " uniform sampler2D inputImageTexture;\n" + 12 | " uniform sampler2D inputImageTexture2;\n" + 13 | " \n" + 14 | " void main()\n" + 15 | " {\n" + 16 | " mediump vec4 base = texture2D(inputImageTexture, textureCoordinate);\n" + 17 | " mediump vec4 overlay = texture2D(inputImageTexture2, textureCoordinate2);\n" + 18 | " \n" + 19 | " mediump float ra;\n" + 20 | " if (overlay.a == 0.0 || ((base.r / overlay.r) > (base.a / overlay.a)))\n" + 21 | " ra = overlay.a * base.a + overlay.r * (1.0 - base.a) + base.r * (1.0 - overlay.a);\n" + 22 | " else\n" + 23 | " ra = (base.r * overlay.a * overlay.a) / overlay.r + overlay.r * (1.0 - base.a) + base.r * (1.0 - overlay.a);\n" + 24 | " \n" + 25 | "\n" + 26 | " mediump float ga;\n" + 27 | " if (overlay.a == 0.0 || ((base.g / overlay.g) > (base.a / overlay.a)))\n" + 28 | " ga = overlay.a * base.a + overlay.g * (1.0 - base.a) + base.g * (1.0 - overlay.a);\n" + 29 | " else\n" + 30 | " ga = (base.g * overlay.a * overlay.a) / overlay.g + overlay.g * (1.0 - base.a) + base.g * (1.0 - overlay.a);\n" + 31 | "\n" + 32 | " \n" + 33 | " mediump float ba;\n" + 34 | " if (overlay.a == 0.0 || ((base.b / overlay.b) > (base.a / overlay.a)))\n" + 35 | " ba = overlay.a * base.a + overlay.b * (1.0 - base.a) + base.b * (1.0 - overlay.a);\n" + 36 | " else\n" + 37 | " ba = (base.b * overlay.a * overlay.a) / overlay.b + overlay.b * (1.0 - base.a) + base.b * (1.0 - overlay.a);\n" + 38 | "\n" + 39 | " mediump float a = overlay.a + base.a - overlay.a * base.a;\n" + 40 | " \n" + 41 | " gl_FragColor = vec4(ra, ga, ba, a);\n" + 42 | " }"; 43 | 44 | public GPUImageDivideBlendFilter() { 45 | super(DIVIDE_BLEND_FRAGMENT_SHADER); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/blend_mode_filter/GPUImageExclusionBlendFilter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.blend_mode_filter; 2 | 3 | /** 4 | * 排除混合 5 | */ 6 | public class GPUImageExclusionBlendFilter extends GPUImageTwoInputFilter { 7 | 8 | public static final String EXCLUSION_BLEND_FRAGMENT_SHADER = "" + 9 | "varying highp vec2 textureCoordinate;\n" + 10 | " varying highp vec2 textureCoordinate2;\n" + 11 | "\n" + 12 | " uniform sampler2D inputImageTexture;\n" + 13 | " uniform sampler2D inputImageTexture2;\n" + 14 | " \n" + 15 | " void main()\n" + 16 | " {\n" + 17 | " mediump vec4 base = texture2D(inputImageTexture, textureCoordinate);\n" + 18 | " mediump vec4 overlay = texture2D(inputImageTexture2, textureCoordinate2);\n" + 19 | " \n" + 20 | " // Dca = (Sca.Da + Dca.Sa - 2.Sca.Dca) + Sca.(1 - Da) + Dca.(1 - Sa)\n" + 21 | " \n" + 22 | " gl_FragColor = vec4((overlay.rgb * base.a + base.rgb * overlay.a - 2.0 * overlay.rgb * base.rgb) + overlay.rgb * (1.0 - base.a) + base.rgb * (1.0 - overlay.a), base.a);\n" + 23 | " }"; 24 | 25 | public GPUImageExclusionBlendFilter() { 26 | super(EXCLUSION_BLEND_FRAGMENT_SHADER); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/blend_mode_filter/GPUImageHardLightBlendFilter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.blend_mode_filter; 2 | 3 | /** 4 | * 强光混合,通常用于创建阴影效果 5 | */ 6 | public class GPUImageHardLightBlendFilter extends GPUImageTwoInputFilter { 7 | 8 | public static final String HARD_LIGHT_BLEND_FRAGMENT_SHADER = "" + 9 | "varying highp vec2 textureCoordinate;\n" + 10 | " varying highp vec2 textureCoordinate2;\n" + 11 | "\n" + 12 | " uniform sampler2D inputImageTexture;\n" + 13 | " uniform sampler2D inputImageTexture2;\n" + 14 | "\n" + 15 | " const highp vec3 W = vec3(0.2125, 0.7154, 0.0721);\n" + 16 | "\n" + 17 | " void main()\n" + 18 | " {\n" + 19 | " mediump vec4 base = texture2D(inputImageTexture, textureCoordinate);\n" + 20 | " mediump vec4 overlay = texture2D(inputImageTexture2, textureCoordinate2);\n" + 21 | "\n" + 22 | " highp float ra;\n" + 23 | " if (2.0 * overlay.r < overlay.a) {\n" + 24 | " ra = 2.0 * overlay.r * base.r + overlay.r * (1.0 - base.a) + base.r * (1.0 - overlay.a);\n" + 25 | " } else {\n" + 26 | " ra = overlay.a * base.a - 2.0 * (base.a - base.r) * (overlay.a - overlay.r) + overlay.r * (1.0 - base.a) + base.r * (1.0 - overlay.a);\n" + 27 | " }\n" + 28 | " \n" + 29 | " highp float ga;\n" + 30 | " if (2.0 * overlay.g < overlay.a) {\n" + 31 | " ga = 2.0 * overlay.g * base.g + overlay.g * (1.0 - base.a) + base.g * (1.0 - overlay.a);\n" + 32 | " } else {\n" + 33 | " ga = overlay.a * base.a - 2.0 * (base.a - base.g) * (overlay.a - overlay.g) + overlay.g * (1.0 - base.a) + base.g * (1.0 - overlay.a);\n" + 34 | " }\n" + 35 | " \n" + 36 | " highp float ba;\n" + 37 | " if (2.0 * overlay.b < overlay.a) {\n" + 38 | " ba = 2.0 * overlay.b * base.b + overlay.b * (1.0 - base.a) + base.b * (1.0 - overlay.a);\n" + 39 | " } else {\n" + 40 | " ba = overlay.a * base.a - 2.0 * (base.a - base.b) * (overlay.a - overlay.b) + overlay.b * (1.0 - base.a) + base.b * (1.0 - overlay.a);\n" + 41 | " }\n" + 42 | " \n" + 43 | " gl_FragColor = vec4(ra, ga, ba, 1.0);\n" + 44 | " }"; 45 | 46 | public GPUImageHardLightBlendFilter() { 47 | super(HARD_LIGHT_BLEND_FRAGMENT_SHADER); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/blend_mode_filter/GPUImageLightenBlendFilter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.blend_mode_filter; 2 | 3 | /** 4 | * 减淡混合,通常用于重叠类型 5 | */ 6 | public class GPUImageLightenBlendFilter extends GPUImageTwoInputFilter { 7 | 8 | public static final String LIGHTEN_BLEND_FRAGMENT_SHADER = "" + 9 | "varying highp vec2 textureCoordinate;\n" + 10 | " varying highp vec2 textureCoordinate2;\n" + 11 | "\n" + 12 | " uniform sampler2D inputImageTexture;\n" + 13 | " uniform sampler2D inputImageTexture2;\n" + 14 | " \n" + 15 | " void main()\n" + 16 | " {\n" + 17 | " lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n" + 18 | " lowp vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);\n" + 19 | " \n" + 20 | " gl_FragColor = max(textureColor, textureColor2);\n" + 21 | " }"; 22 | 23 | public GPUImageLightenBlendFilter() { 24 | super(LIGHTEN_BLEND_FRAGMENT_SHADER); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/blend_mode_filter/GPUImageLinearBurnBlendFilter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.blend_mode_filter; 2 | 3 | /** 4 | * 线性加深混合 5 | */ 6 | public class GPUImageLinearBurnBlendFilter extends GPUImageTwoInputFilter { 7 | 8 | public static final String LINEAR_BURN_BLEND_FRAGMENT_SHADER = "" + 9 | "varying highp vec2 textureCoordinate;\n" + 10 | " varying highp vec2 textureCoordinate2;\n" + 11 | " \n" + 12 | " uniform sampler2D inputImageTexture;\n" + 13 | " uniform sampler2D inputImageTexture2;\n" + 14 | " \n" + 15 | " void main()\n" + 16 | " {\n" + 17 | " mediump vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n" + 18 | " mediump vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);\n" + 19 | " \n" + 20 | " gl_FragColor = vec4(clamp(textureColor.rgb + textureColor2.rgb - vec3(1.0), vec3(0.0), vec3(1.0)), textureColor.a);\n" + 21 | " }"; 22 | 23 | public GPUImageLinearBurnBlendFilter() { 24 | super(LINEAR_BURN_BLEND_FRAGMENT_SHADER); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/blend_mode_filter/GPUImageLuminosityBlendFilter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.blend_mode_filter; 2 | 3 | /** 4 | * 图片增亮渲染滤镜 5 | */ 6 | public class GPUImageLuminosityBlendFilter extends GPUImageTwoInputFilter { 7 | 8 | public static final String LUMINOSITY_BLEND_FRAGMENT_SHADER = "" + 9 | "varying highp vec2 textureCoordinate;\n" + 10 | " varying highp vec2 textureCoordinate2;\n" + 11 | " \n" + 12 | " uniform sampler2D inputImageTexture;\n" + 13 | " uniform sampler2D inputImageTexture2;\n" + 14 | " \n" + 15 | " highp float lum(lowp vec3 c) {\n" + 16 | " return dot(c, vec3(0.3, 0.59, 0.11));\n" + 17 | " }\n" + 18 | " \n" + 19 | " lowp vec3 clipcolor(lowp vec3 c) {\n" + 20 | " highp float l = lum(c);\n" + 21 | " lowp float n = min(min(c.r, c.g), c.b);\n" + 22 | " lowp float x = max(max(c.r, c.g), c.b);\n" + 23 | " \n" + 24 | " if (n < 0.0) {\n" + 25 | " c.r = l + ((c.r - l) * l) / (l - n);\n" + 26 | " c.g = l + ((c.g - l) * l) / (l - n);\n" + 27 | " c.b = l + ((c.b - l) * l) / (l - n);\n" + 28 | " }\n" + 29 | " if (x > 1.0) {\n" + 30 | " c.r = l + ((c.r - l) * (1.0 - l)) / (x - l);\n" + 31 | " c.g = l + ((c.g - l) * (1.0 - l)) / (x - l);\n" + 32 | " c.b = l + ((c.b - l) * (1.0 - l)) / (x - l);\n" + 33 | " }\n" + 34 | " \n" + 35 | " return c;\n" + 36 | " }\n" + 37 | " \n" + 38 | " lowp vec3 setlum(lowp vec3 c, highp float l) {\n" + 39 | " highp float d = l - lum(c);\n" + 40 | " c = c + vec3(d);\n" + 41 | " return clipcolor(c);\n" + 42 | " }\n" + 43 | " \n" + 44 | " void main()\n" + 45 | " {\n" + 46 | " highp vec4 baseColor = texture2D(inputImageTexture, textureCoordinate);\n" + 47 | " highp vec4 overlayColor = texture2D(inputImageTexture2, textureCoordinate2);\n" + 48 | " \n" + 49 | " gl_FragColor = vec4(baseColor.rgb * (1.0 - overlayColor.a) + setlum(baseColor.rgb, lum(overlayColor.rgb)) * overlayColor.a, baseColor.a);\n" + 50 | " }"; 51 | 52 | public GPUImageLuminosityBlendFilter() { 53 | super(LUMINOSITY_BLEND_FRAGMENT_SHADER); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/blend_mode_filter/GPUImageMultiplyBlendFilter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.blend_mode_filter; 2 | 3 | /** 4 | * 多重混合滤镜,通常用于创建阴影和深度效果 5 | */ 6 | public class GPUImageMultiplyBlendFilter extends GPUImageTwoInputFilter { 7 | public static final String MULTIPLY_BLEND_FRAGMENT_SHADER = "" + 8 | "varying highp vec2 textureCoordinate;\n" + 9 | " varying highp vec2 textureCoordinate2;\n" + 10 | "\n" + 11 | " uniform sampler2D inputImageTexture;\n" + 12 | " uniform sampler2D inputImageTexture2;\n" + 13 | " \n" + 14 | " void main()\n" + 15 | " {\n" + 16 | " lowp vec4 base = texture2D(inputImageTexture, textureCoordinate);\n" + 17 | " lowp vec4 overlayer = texture2D(inputImageTexture2, textureCoordinate2);\n" + 18 | " \n" + 19 | " gl_FragColor = overlayer * base + overlayer * (1.0 - base.a) + base * (1.0 - overlayer.a);\n" + 20 | " }"; 21 | 22 | public GPUImageMultiplyBlendFilter() { 23 | super(MULTIPLY_BLEND_FRAGMENT_SHADER); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/blend_mode_filter/GPUImageOverlayBlendFilter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.blend_mode_filter; 2 | 3 | /** 4 | * 叠加,重叠绘制,两层图层叠加在一起。通常用于创建阴影效果 5 | */ 6 | public class GPUImageOverlayBlendFilter extends GPUImageTwoInputFilter { 7 | 8 | public static final String OVERLAY_BLEND_FRAGMENT_SHADER = "" + 9 | "varying highp vec2 textureCoordinate;\n" + 10 | " varying highp vec2 textureCoordinate2;\n" + 11 | "\n" + 12 | " uniform sampler2D inputImageTexture;\n" + 13 | " uniform sampler2D inputImageTexture2;\n" + 14 | " \n" + 15 | " void main()\n" + 16 | " {\n" + 17 | " mediump vec4 base = texture2D(inputImageTexture, textureCoordinate);\n" + 18 | " mediump vec4 overlay = texture2D(inputImageTexture2, textureCoordinate2);\n" + 19 | " \n" + 20 | " mediump float ra;\n" + 21 | " if (2.0 * base.r < base.a) {\n" + 22 | " ra = 2.0 * overlay.r * base.r + overlay.r * (1.0 - base.a) + base.r * (1.0 - overlay.a);\n" + 23 | " } else {\n" + 24 | " ra = overlay.a * base.a - 2.0 * (base.a - base.r) * (overlay.a - overlay.r) + overlay.r * (1.0 - base.a) + base.r * (1.0 - overlay.a);\n" + 25 | " }\n" + 26 | " \n" + 27 | " mediump float ga;\n" + 28 | " if (2.0 * base.g < base.a) {\n" + 29 | " ga = 2.0 * overlay.g * base.g + overlay.g * (1.0 - base.a) + base.g * (1.0 - overlay.a);\n" + 30 | " } else {\n" + 31 | " ga = overlay.a * base.a - 2.0 * (base.a - base.g) * (overlay.a - overlay.g) + overlay.g * (1.0 - base.a) + base.g * (1.0 - overlay.a);\n" + 32 | " }\n" + 33 | " \n" + 34 | " mediump float ba;\n" + 35 | " if (2.0 * base.b < base.a) {\n" + 36 | " ba = 2.0 * overlay.b * base.b + overlay.b * (1.0 - base.a) + base.b * (1.0 - overlay.a);\n" + 37 | " } else {\n" + 38 | " ba = overlay.a * base.a - 2.0 * (base.a - base.b) * (overlay.a - overlay.b) + overlay.b * (1.0 - base.a) + base.b * (1.0 - overlay.a);\n" + 39 | " }\n" + 40 | " \n" + 41 | " gl_FragColor = vec4(ra, ga, ba, 1.0);\n" + 42 | " }"; 43 | 44 | public GPUImageOverlayBlendFilter() { 45 | super(OVERLAY_BLEND_FRAGMENT_SHADER); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/blend_mode_filter/GPUImageScreenBlendFilter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.blend_mode_filter; 2 | 3 | /** 4 | * 滤色混合,保留两个图层中较白的部分,较暗的部分被遮盖 5 | */ 6 | public class GPUImageScreenBlendFilter extends GPUImageTwoInputFilter { 7 | 8 | public static final String SCREEN_BLEND_FRAGMENT_SHADER = "" + 9 | "varying highp vec2 textureCoordinate;\n" + 10 | " varying highp vec2 textureCoordinate2;\n" + 11 | "\n" + 12 | " uniform sampler2D inputImageTexture;\n" + 13 | " uniform sampler2D inputImageTexture2;\n" + 14 | " \n" + 15 | " void main()\n" + 16 | " {\n" + 17 | " mediump vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n" + 18 | " mediump vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);\n" + 19 | " mediump vec4 whiteColor = vec4(1.0);\n" + 20 | " gl_FragColor = whiteColor - ((whiteColor - textureColor2) * (whiteColor - textureColor));\n" + 21 | " }"; 22 | 23 | public GPUImageScreenBlendFilter() { 24 | super(SCREEN_BLEND_FRAGMENT_SHADER); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/blend_mode_filter/GPUImageSimpleOverlayBlendFilter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.blend_mode_filter; 2 | 3 | /** 4 | * 正常渲染,第二层位于被渲染层的下层 5 | * This equation is a simplification of the general blending equation. It assumes the destination color is opaque, and therefore drops the destination color's alpha term. 6 | *

7 | * D = C1 * C1a + C2 * C2a * (1 - C1a) 8 | * where D is the resultant color, C1 is the color of the first element, C1a is the alpha of the first element, C2 is the second element color, C2a is the alpha of the second element. The destination alpha is calculated with: 9 | *

10 | * Da = C1a + C2a * (1 - C1a) 11 | * The resultant color is premultiplied with the alpha. To restore the color to the unmultiplied values, just divide by Da, the resultant alpha. 12 | *

13 | * http://stackoverflow.com/questions/1724946/blend-mode-on-a-transparent-and-semi-transparent-background 14 | *

15 | * For some reason Photoshop behaves 16 | * D = C1 + C2 * C2a * (1 - C1a) 17 | */ 18 | public class GPUImageSimpleOverlayBlendFilter extends GPUImageTwoInputFilter { 19 | 20 | public static final String NORMAL_BLEND_FRAGMENT_SHADER = "" + 21 | "varying highp vec2 textureCoordinate;\n" + 22 | " varying highp vec2 textureCoordinate2;\n" + 23 | " \n" + 24 | " uniform sampler2D inputImageTexture;\n" + 25 | " uniform sampler2D inputImageTexture2;\n" + 26 | " \n" + 27 | " void main()\n" + 28 | " {\n" + 29 | " lowp vec4 c2 = texture2D(inputImageTexture, textureCoordinate);\n" + 30 | "\t lowp vec4 c1 = texture2D(inputImageTexture2, textureCoordinate2);\n" + 31 | " \n" + 32 | " lowp vec4 outputColor;\n" + 33 | " \n" + 34 | " outputColor.r = c1.r + c2.r * c2.a * (1.0 - c1.a);\n" + 35 | "\n" + 36 | " outputColor.g = c1.g + c2.g * c2.a * (1.0 - c1.a);\n" + 37 | " \n" + 38 | " outputColor.b = c1.b + c2.b * c2.a * (1.0 - c1.a);\n" + 39 | " \n" + 40 | " outputColor.a = c1.a + c2.a * (1.0 - c1.a);\n" + 41 | " \n" + 42 | " gl_FragColor = outputColor;\n" + 43 | " }"; 44 | 45 | public GPUImageSimpleOverlayBlendFilter() { 46 | super(NORMAL_BLEND_FRAGMENT_SHADER); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/blend_mode_filter/GPUImageSoftLightBlendFilter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.blend_mode_filter; 2 | 3 | /** 4 | * 柔光混合 5 | */ 6 | public class GPUImageSoftLightBlendFilter extends GPUImageTwoInputFilter { 7 | 8 | public static final String SOFT_LIGHT_BLEND_FRAGMENT_SHADER = "" + 9 | "varying highp vec2 textureCoordinate;\n" + 10 | " varying highp vec2 textureCoordinate2;\n" + 11 | "\n" + 12 | " uniform sampler2D inputImageTexture;\n" + 13 | " uniform sampler2D inputImageTexture2;\n" + 14 | " \n" + 15 | " void main()\n" + 16 | " {\n" + 17 | " mediump vec4 base = texture2D(inputImageTexture, textureCoordinate);\n" + 18 | " mediump vec4 overlay = texture2D(inputImageTexture2, textureCoordinate2);\n" + 19 | " \n" + 20 | " gl_FragColor = base * (overlay.a * (base / base.a) + (2.0 * overlay * (1.0 - (base / base.a)))) + overlay * (1.0 - base.a) + base * (1.0 - overlay.a);\n" + 21 | " }"; 22 | 23 | public GPUImageSoftLightBlendFilter() { 24 | super(SOFT_LIGHT_BLEND_FRAGMENT_SHADER); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/blend_mode_filter/GPUImageSourceOverBlendFilter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.blend_mode_filter; 2 | 3 | /** 4 | * 源混合,两个图片源直接混合 5 | * directly mixed 2 images together 6 | */ 7 | public class GPUImageSourceOverBlendFilter extends GPUImageTwoInputFilter { 8 | public static final String SOURCE_OVER_BLEND_FRAGMENT_SHADER = "" + 9 | "varying highp vec2 textureCoordinate;\n" + 10 | " varying highp vec2 textureCoordinate2;\n" + 11 | " \n" + 12 | " uniform sampler2D inputImageTexture;\n" + 13 | " uniform sampler2D inputImageTexture2;\n" + 14 | " \n" + 15 | " void main()\n" + 16 | " {\n" + 17 | " lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n" + 18 | " lowp vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);\n" + 19 | " \n" + 20 | " gl_FragColor = mix(textureColor, textureColor2, textureColor2.a);\n" + 21 | " }"; 22 | 23 | public GPUImageSourceOverBlendFilter() { 24 | super(SOURCE_OVER_BLEND_FRAGMENT_SHADER); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/blend_mode_filter/GPUImageSubtractBlendFilter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.blend_mode_filter; 2 | 3 | /** 4 | * 差值混合,通常用于创建两个图像之间的动画变暗模糊效果 5 | */ 6 | public class GPUImageSubtractBlendFilter extends GPUImageTwoInputFilter { 7 | 8 | public static final String SUBTRACT_BLEND_FRAGMENT_SHADER = "" + 9 | "varying highp vec2 textureCoordinate;\n" + 10 | " varying highp vec2 textureCoordinate2;\n" + 11 | "\n" + 12 | " uniform sampler2D inputImageTexture;\n" + 13 | " uniform sampler2D inputImageTexture2;\n" + 14 | " \n" + 15 | " void main()\n" + 16 | " {\n" + 17 | " lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n" + 18 | " lowp vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);\n" + 19 | "\n" + 20 | " gl_FragColor = vec4(textureColor.rgb - textureColor2.rgb, textureColor.a);\n" + 21 | " }"; 22 | 23 | public GPUImageSubtractBlendFilter() { 24 | super(SUBTRACT_BLEND_FRAGMENT_SHADER); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/blend_mode_filter/color_mapping_blend/GPUImageLookupFilter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.blend_mode_filter.color_mapping_blend; 2 | 3 | import android.opengl.GLES30; 4 | 5 | import cn.co.willow.android.ultimate.gpuimage.core_render_filter.blend_mode_filter.GPUImageTwoInputFilter; 6 | 7 | /** 8 | * 颜色映射表渲染滤镜基类,通过设置好的颜色映射表来进行图片渲染 9 | */ 10 | public class GPUImageLookupFilter extends GPUImageTwoInputFilter { 11 | 12 | public static final String LOOKUP_FRAGMENT_SHADER = "" + 13 | " varying highp vec2 textureCoordinate;\n" + 14 | " varying highp vec2 textureCoordinate2;\n" + // TODO: This is not used 15 | " \n" + 16 | " uniform sampler2D inputImageTexture;\n" + 17 | " uniform sampler2D inputImageTexture2;\n" + // lookup texture 18 | " \n" + 19 | " uniform lowp float intensity;\n" + 20 | " \n" + 21 | " void main()\n" + 22 | " {\n" + 23 | " highp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n" + 24 | " \n" + 25 | " highp float blueColor = textureColor.b * 63.0;\n" + 26 | " \n" + 27 | " highp vec2 quad1;\n" + 28 | " quad1.y = floor(floor(blueColor) / 8.0);\n" + 29 | " quad1.x = floor(blueColor) - (quad1.y * 8.0);\n" + 30 | " \n" + 31 | " highp vec2 quad2;\n" + 32 | " quad2.y = floor(ceil(blueColor) / 8.0);\n" + 33 | " quad2.x = ceil(blueColor) - (quad2.y * 8.0);\n" + 34 | " \n" + 35 | " highp vec2 texPos1;\n" + 36 | " texPos1.x = (quad1.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.r);\n" + 37 | " texPos1.y = (quad1.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.g);\n" + 38 | " \n" + 39 | " highp vec2 texPos2;\n" + 40 | " texPos2.x = (quad2.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.r);\n" + 41 | " texPos2.y = (quad2.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.g);\n" + 42 | " \n" + 43 | " lowp vec4 newColor1 = texture2D(inputImageTexture2, texPos1);\n" + 44 | " lowp vec4 newColor2 = texture2D(inputImageTexture2, texPos2);\n" + 45 | " \n" + 46 | " lowp vec4 newColor = mix(newColor1, newColor2, fract(blueColor));\n" + 47 | " gl_FragColor = mix(textureColor, vec4(newColor.rgb, textureColor.w), intensity);\n" + 48 | " }"; 49 | 50 | private int mIntensityLocation; 51 | private float mIntensity; 52 | 53 | public GPUImageLookupFilter() { 54 | this(1.0f); 55 | } 56 | 57 | public GPUImageLookupFilter(final float intensity) { 58 | super(LOOKUP_FRAGMENT_SHADER); 59 | mIntensity = intensity; 60 | } 61 | 62 | @Override 63 | public void onInit() { 64 | super.onInit(); 65 | mIntensityLocation = GLES30.glGetUniformLocation(getProgram(), "intensity"); 66 | } 67 | 68 | @Override 69 | public void onInitialized() { 70 | super.onInitialized(); 71 | setIntensity(mIntensity); 72 | } 73 | 74 | public void setIntensity(final float intensity) { 75 | mIntensity = intensity; 76 | setFloat(mIntensityLocation, mIntensity); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/blend_mode_filter/mix_control_blend/GPUImageAlphaBlendFilter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.blend_mode_filter.mix_control_blend; 2 | 3 | /** 4 | * 混合控制滤镜:透明混合,通常用于在背景上应用前景的透明度,值范围 0.0~1.0,0.5为正常值 5 | * Mix ranges from 0.0 (only image 1) to 1.0 (only image 2), with 0.5 (half of either) as the normal level 6 | */ 7 | public class GPUImageAlphaBlendFilter extends GPUImageMixBlendFilter { 8 | 9 | public static final String ALPHA_BLEND_FRAGMENT_SHADER = "varying highp vec2 textureCoordinate;\n" + 10 | " varying highp vec2 textureCoordinate2;\n" + 11 | "\n" + 12 | " uniform sampler2D inputImageTexture;\n" + 13 | " uniform sampler2D inputImageTexture2;\n" + 14 | " \n" + 15 | " uniform lowp float mixturePercent;\n" + 16 | "\n" + 17 | " void main()\n" + 18 | " {\n" + 19 | " lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n" + 20 | " lowp vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);\n" + 21 | "\n" + 22 | " gl_FragColor = vec4(mix(textureColor.rgb, textureColor2.rgb, textureColor2.a * mixturePercent), textureColor.a);\n" + 23 | " }"; 24 | 25 | public GPUImageAlphaBlendFilter() { 26 | super(ALPHA_BLEND_FRAGMENT_SHADER); 27 | } 28 | 29 | public GPUImageAlphaBlendFilter(float mix) { 30 | super(ALPHA_BLEND_FRAGMENT_SHADER, mix); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/blend_mode_filter/mix_control_blend/GPUImageDissolveBlendFilter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.blend_mode_filter.mix_control_blend; 2 | 3 | /** 4 | * 混合控制滤镜:溶解混合,值范围 0.0~1.0,0.5为正常值(溶解一半) 5 | * Mix ranges from 0.0 (only image 1) to 1.0 (only image 2), with 0.5 (half of either) as the normal level 6 | */ 7 | public class GPUImageDissolveBlendFilter extends GPUImageMixBlendFilter { 8 | 9 | public static final String DISSOLVE_BLEND_FRAGMENT_SHADER = "varying highp vec2 textureCoordinate;\n" + 10 | " varying highp vec2 textureCoordinate2;\n" + 11 | "\n" + 12 | " uniform sampler2D inputImageTexture;\n" + 13 | " uniform sampler2D inputImageTexture2;\n" + 14 | " uniform lowp float mixturePercent;\n" + 15 | " \n" + 16 | " void main()\n" + 17 | " {\n" + 18 | " lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n" + 19 | " lowp vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);\n" + 20 | " \n" + 21 | " gl_FragColor = mix(textureColor, textureColor2, mixturePercent);\n" + 22 | " }"; 23 | 24 | public GPUImageDissolveBlendFilter() { 25 | super(DISSOLVE_BLEND_FRAGMENT_SHADER); 26 | } 27 | 28 | public GPUImageDissolveBlendFilter(float mix) { 29 | super(DISSOLVE_BLEND_FRAGMENT_SHADER, mix); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/blend_mode_filter/mix_control_blend/GPUImageMixBlendFilter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.blend_mode_filter.mix_control_blend; 2 | 3 | import android.opengl.GLES30; 4 | 5 | import cn.co.willow.android.ultimate.gpuimage.core_render_filter.blend_mode_filter.GPUImageTwoInputFilter; 6 | 7 | /** 8 | * 混合控制滤镜基类,用于控制两个图片混合时的对应比例混合情况 9 | * mix control, use to control 2 images directly mix with certain ratio. 10 | */ 11 | public class GPUImageMixBlendFilter extends GPUImageTwoInputFilter { 12 | 13 | private int mMixLocation; 14 | private float mMix; 15 | 16 | public GPUImageMixBlendFilter(String fragmentShader) { 17 | this(fragmentShader, 0.5f); 18 | } 19 | 20 | public GPUImageMixBlendFilter(String fragmentShader, float mix) { 21 | super(fragmentShader); 22 | mMix = mix; 23 | } 24 | 25 | @Override 26 | public void onInit() { 27 | super.onInit(); 28 | mMixLocation = GLES30.glGetUniformLocation(getProgram(), "mixturePercent"); 29 | } 30 | 31 | @Override 32 | public void onInitialized() { 33 | super.onInitialized(); 34 | setMix(mMix); 35 | } 36 | 37 | /** 38 | * @param mix ranges from 0.0 (only image 1) to 1.0 (only image 2), with 0.5 (half of either) as the normal level 39 | */ 40 | public void setMix(final float mix) { 41 | mMix = mix; 42 | setFloat(mMixLocation, mMix); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/color_enhance_filter/GPUImageCGAColorspaceFilter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.color_enhance_filter; 2 | 3 | import cn.co.willow.android.ultimate.gpuimage.core_render_filter.GPUImageFilter; 4 | 5 | /** 6 | * 增强滤镜:CGA色域着色效果,原有色泽被黑、浅蓝、紫色块替代,像素效果 7 | * use CGA Colorspace to replace original color of image, pxiel effect. 8 | */ 9 | public class GPUImageCGAColorspaceFilter extends GPUImageFilter { 10 | public static final String CGACOLORSPACE_FRAGMENT_SHADER = "" + 11 | "varying highp vec2 textureCoordinate;\n" + 12 | "\n" + 13 | "uniform sampler2D inputImageTexture;\n" + 14 | "\n" + 15 | "void main()\n" + 16 | "{\n" + 17 | "highp vec2 sampleDivisor = vec2(1.0 / 200.0, 1.0 / 320.0);\n" + 18 | "//highp vec4 colorDivisor = vec4(colorDepth);\n" + 19 | "\n" + 20 | "highp vec2 samplePos = textureCoordinate - mod(textureCoordinate, sampleDivisor);\n" + 21 | "highp vec4 color = texture2D(inputImageTexture, samplePos );\n" + 22 | "\n" + 23 | "//gl_FragColor = texture2D(inputImageTexture, samplePos );\n" + 24 | "mediump vec4 colorCyan = vec4(85.0 / 255.0, 1.0, 1.0, 1.0);\n" + 25 | "mediump vec4 colorMagenta = vec4(1.0, 85.0 / 255.0, 1.0, 1.0);\n" + 26 | "mediump vec4 colorWhite = vec4(1.0, 1.0, 1.0, 1.0);\n" + 27 | "mediump vec4 colorBlack = vec4(0.0, 0.0, 0.0, 1.0);\n" + 28 | "\n" + 29 | "mediump vec4 endColor;\n" + 30 | "highp float blackDistance = distance(color, colorBlack);\n" + 31 | "highp float whiteDistance = distance(color, colorWhite);\n" + 32 | "highp float magentaDistance = distance(color, colorMagenta);\n" + 33 | "highp float cyanDistance = distance(color, colorCyan);\n" + 34 | "\n" + 35 | "mediump vec4 finalColor;\n" + 36 | "\n" + 37 | "highp float colorDistance = min(magentaDistance, cyanDistance);\n" + 38 | "colorDistance = min(colorDistance, whiteDistance);\n" + 39 | "colorDistance = min(colorDistance, blackDistance); \n" + 40 | "\n" + 41 | "if (colorDistance == blackDistance) {\n" + 42 | "finalColor = colorBlack;\n" + 43 | "} else if (colorDistance == whiteDistance) {\n" + 44 | "finalColor = colorWhite;\n" + 45 | "} else if (colorDistance == cyanDistance) {\n" + 46 | "finalColor = colorCyan;\n" + 47 | "} else {\n" + 48 | "finalColor = colorMagenta;\n" + 49 | "}\n" + 50 | "\n" + 51 | "gl_FragColor = finalColor;\n" + 52 | "}\n"; 53 | 54 | public GPUImageCGAColorspaceFilter() { 55 | super(NO_FILTER_VERTEX_SHADER, CGACOLORSPACE_FRAGMENT_SHADER); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/color_enhance_filter/GPUImageColorInvertFilter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Willow 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.color_enhance_filter; 18 | 19 | import cn.co.willow.android.ultimate.gpuimage.core_render_filter.GPUImageFilter; 20 | 21 | /** 22 | * 增强滤镜:反色滤镜,所有颜色取反色 23 | * Invert all the colors in the image. 24 | */ 25 | public class GPUImageColorInvertFilter extends GPUImageFilter { 26 | public static final String COLOR_INVERT_FRAGMENT_SHADER = "" + 27 | "varying highp vec2 textureCoordinate;\n" + 28 | "\n" + 29 | "uniform sampler2D inputImageTexture;\n" + 30 | "\n" + 31 | "void main()\n" + 32 | "{\n" + 33 | " lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n" + 34 | " \n" + 35 | " gl_FragColor = vec4((1.0 - textureColor.rgb), textureColor.w);\n" + 36 | "}"; 37 | 38 | public GPUImageColorInvertFilter() { 39 | super(NO_FILTER_VERTEX_SHADER, COLOR_INVERT_FRAGMENT_SHADER); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/color_enhance_filter/GPUImageColorMatrixFilter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.color_enhance_filter; 2 | 3 | import android.opengl.GLES30; 4 | 5 | import cn.co.willow.android.ultimate.gpuimage.core_render_filter.GPUImageFilter; 6 | 7 | /** 8 | * 色泽增强滤镜:用指定的颜色矩阵来渲染图片,增强图片偏向色泽 9 | * Applies a ColorMatrix to the image. 10 | */ 11 | public class GPUImageColorMatrixFilter extends GPUImageFilter { 12 | public static final String COLOR_MATRIX_FRAGMENT_SHADER = "" + 13 | "varying highp vec2 textureCoordinate;\n" + 14 | "\n" + 15 | "uniform sampler2D inputImageTexture;\n" + 16 | "\n" + 17 | "uniform lowp mat4 colorMatrix;\n" + 18 | "uniform lowp float intensity;\n" + 19 | "\n" + 20 | "void main()\n" + 21 | "{\n" + 22 | " lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n" + 23 | " lowp vec4 outputColor = textureColor * colorMatrix;\n" + 24 | " \n" + 25 | " gl_FragColor = (intensity * outputColor) + ((1.0 - intensity) * textureColor);\n" + 26 | "}"; 27 | 28 | private float mIntensity; 29 | private float[] mColorMatrix; 30 | private int mColorMatrixLocation; 31 | private int mIntensityLocation; 32 | 33 | public GPUImageColorMatrixFilter() { 34 | this(1.0f, new float[]{ 35 | 1.0f, 0.0f, 0.0f, 0.0f, 36 | 0.0f, 1.0f, 0.0f, 0.0f, 37 | 0.0f, 0.0f, 1.0f, 0.0f, 38 | 0.0f, 0.0f, 0.0f, 1.0f 39 | }); 40 | } 41 | 42 | public GPUImageColorMatrixFilter(final float intensity, final float[] colorMatrix) { 43 | super(NO_FILTER_VERTEX_SHADER, COLOR_MATRIX_FRAGMENT_SHADER); 44 | mIntensity = intensity; 45 | mColorMatrix = colorMatrix; 46 | } 47 | 48 | @Override 49 | public void onInit() { 50 | super.onInit(); 51 | mColorMatrixLocation = GLES30.glGetUniformLocation(getProgram(), "colorMatrix"); 52 | mIntensityLocation = GLES30.glGetUniformLocation(getProgram(), "intensity"); 53 | } 54 | 55 | @Override 56 | public void onInitialized() { 57 | super.onInitialized(); 58 | setIntensity(mIntensity); 59 | setColorMatrix(mColorMatrix); 60 | } 61 | 62 | public void setIntensity(final float intensity) { 63 | mIntensity = intensity; 64 | setFloat(mIntensityLocation, intensity); 65 | } 66 | 67 | public void setColorMatrix(final float[] colorMatrix) { 68 | mColorMatrix = colorMatrix; 69 | setUniformMatrix4f(mColorMatrixLocation, colorMatrix); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/color_enhance_filter/GPUImageFalseColorFilter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.color_enhance_filter; 2 | 3 | import android.opengl.GLES30; 4 | 5 | import cn.co.willow.android.ultimate.gpuimage.core_render_filter.GPUImageFilter; 6 | 7 | /** 8 | * 色泽增强滤镜:色彩替换(替换亮部和暗部色彩) 9 | * replace color in the light and dark areas 10 | */ 11 | public class GPUImageFalseColorFilter extends GPUImageFilter { 12 | public static final String FALSECOLOR_FRAGMENT_SHADER = "" + 13 | "precision lowp float;\n" + 14 | "\n" + 15 | "varying highp vec2 textureCoordinate;\n" + 16 | "\n" + 17 | "uniform sampler2D inputImageTexture;\n" + 18 | "uniform float intensity;\n" + 19 | "uniform vec3 firstColor;\n" + 20 | "uniform vec3 secondColor;\n" + 21 | "\n" + 22 | "const mediump vec3 luminanceWeighting = vec3(0.2125, 0.7154, 0.0721);\n" + 23 | "\n" + 24 | "void main()\n" + 25 | "{\n" + 26 | "lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n" + 27 | "float luminance = dot(textureColor.rgb, luminanceWeighting);\n" + 28 | "\n" + 29 | "gl_FragColor = vec4( mix(firstColor.rgb, secondColor.rgb, luminance), textureColor.a);\n" + 30 | "}\n"; 31 | 32 | private float[] mFirstColor; 33 | private int mFirstColorLocation; 34 | private float[] mSecondColor; 35 | private int mSecondColorLocation; 36 | 37 | public GPUImageFalseColorFilter() { 38 | this(0f, 0f, 0.5f, 1f, 0f, 0f); 39 | } 40 | 41 | public GPUImageFalseColorFilter(float firstRed, float firstGreen, float firstBlue, float secondRed, float secondGreen, float secondBlue) { 42 | this(new float[]{firstRed, firstGreen, firstBlue}, new float[]{secondRed, secondGreen, secondBlue}); 43 | } 44 | 45 | public GPUImageFalseColorFilter(float[] firstColor, float[] secondColor) { 46 | super(NO_FILTER_VERTEX_SHADER, FALSECOLOR_FRAGMENT_SHADER); 47 | mFirstColor = firstColor; 48 | mSecondColor = secondColor; 49 | } 50 | 51 | @Override 52 | public void onInit() { 53 | super.onInit(); 54 | mFirstColorLocation = GLES30.glGetUniformLocation(getProgram(), "firstColor"); 55 | mSecondColorLocation = GLES30.glGetUniformLocation(getProgram(), "secondColor"); 56 | } 57 | 58 | @Override 59 | public void onInitialized() { 60 | super.onInitialized(); 61 | setFirstColor(mFirstColor); 62 | setSecondColor(mSecondColor); 63 | } 64 | 65 | public void setFirstColor(final float[] firstColor) { 66 | mFirstColor = firstColor; 67 | setFloatVec3(mFirstColorLocation, firstColor); 68 | } 69 | 70 | public void setSecondColor(final float[] secondColor) { 71 | mSecondColor = secondColor; 72 | setFloatVec3(mSecondColorLocation, secondColor); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/color_enhance_filter/GPUImageWhiteBalanceFilter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.color_enhance_filter; 2 | 3 | import android.opengl.GLES30; 4 | 5 | import cn.co.willow.android.ultimate.gpuimage.core_render_filter.GPUImageFilter; 6 | 7 | /** 8 | * 增强滤镜:白平衡滤镜,保证其他景物的影像就会接近人眼的色彩视觉习惯的一种处理滤镜 9 | * Adjusts the white balance of incoming image. To insure image adjust humans vision
10 | *
11 | * temperature: 12 | * tint: 13 | */ 14 | public class GPUImageWhiteBalanceFilter extends GPUImageFilter { 15 | public static final String WHITE_BALANCE_FRAGMENT_SHADER = "" + 16 | "uniform sampler2D inputImageTexture;\n" + 17 | "varying highp vec2 textureCoordinate;\n" + 18 | " \n" + 19 | "uniform lowp float temperature;\n" + 20 | "uniform lowp float tint;\n" + 21 | "\n" + 22 | "const lowp vec3 warmFilter = vec3(0.93, 0.54, 0.0);\n" + 23 | "\n" + 24 | "const mediump mat3 RGBtoYIQ = mat3(0.299, 0.587, 0.114, 0.596, -0.274, -0.322, 0.212, -0.523, 0.311);\n" + 25 | "const mediump mat3 YIQtoRGB = mat3(1.0, 0.956, 0.621, 1.0, -0.272, -0.647, 1.0, -1.105, 1.702);\n" + 26 | "\n" + 27 | "void main()\n" + 28 | "{\n" + 29 | " lowp vec4 source = texture2D(inputImageTexture, textureCoordinate);\n" + 30 | " \n" + 31 | " mediump vec3 yiq = RGBtoYIQ * source.rgb; //adjusting tint\n" + 32 | " yiq.b = clamp(yiq.b + tint*0.5226*0.1, -0.5226, 0.5226);\n" + 33 | " lowp vec3 rgb = YIQtoRGB * yiq;\n" + 34 | "\n" + 35 | " lowp vec3 processed = vec3(\n" + 36 | " (rgb.r < 0.5 ? (2.0 * rgb.r * warmFilter.r) : (1.0 - 2.0 * (1.0 - rgb.r) * (1.0 - warmFilter.r))), //adjusting temperature\n" + 37 | " (rgb.g < 0.5 ? (2.0 * rgb.g * warmFilter.g) : (1.0 - 2.0 * (1.0 - rgb.g) * (1.0 - warmFilter.g))), \n" + 38 | " (rgb.b < 0.5 ? (2.0 * rgb.b * warmFilter.b) : (1.0 - 2.0 * (1.0 - rgb.b) * (1.0 - warmFilter.b))));\n" + 39 | "\n" + 40 | " gl_FragColor = vec4(mix(rgb, processed, temperature), source.a);\n" + 41 | "}"; 42 | 43 | private int mTemperatureLocation; 44 | private float mTemperature; 45 | private int mTintLocation; 46 | private float mTint; 47 | 48 | public GPUImageWhiteBalanceFilter() { 49 | this(5000.0f, 0.0f); 50 | } 51 | 52 | public GPUImageWhiteBalanceFilter(final float temperature, final float tint) { 53 | super(NO_FILTER_VERTEX_SHADER, WHITE_BALANCE_FRAGMENT_SHADER); 54 | mTemperature = temperature; 55 | mTint = tint; 56 | } 57 | 58 | @Override 59 | public void onInit() { 60 | super.onInit(); 61 | mTemperatureLocation = GLES30.glGetUniformLocation(getProgram(), "temperature"); 62 | mTintLocation = GLES30.glGetUniformLocation(getProgram(), "tint"); 63 | 64 | setTemperature(mTemperature); 65 | setTint(mTint); 66 | } 67 | 68 | 69 | public void setTemperature(final float temperature) { 70 | mTemperature = temperature; 71 | setFloat(mTemperatureLocation, mTemperature < 5000 ? (float) (0.0004 * (mTemperature - 5000.0)) : (float) (0.00006 * (mTemperature - 5000.0))); 72 | } 73 | 74 | public void setTint(final float tint) { 75 | mTint = tint; 76 | setFloat(mTintLocation, (float) (mTint / 100.0)); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/filter_3x3_sampling/GPUImageDirectionalSobelEdgeDetectionFilter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.filter_3x3_sampling; 2 | 3 | /** 4 | * 索贝尔算子边缘检测滤镜 5 | */ 6 | public class GPUImageDirectionalSobelEdgeDetectionFilter extends GPUImage3x3TextureSamplingFilter { 7 | public static final String DIRECTIONAL_SOBEL_EDGE_DETECTION_FRAGMENT_SHADER = "" + 8 | "precision mediump float;\n" + 9 | "\n" + 10 | "varying vec2 textureCoordinate;\n" + 11 | "varying vec2 leftTextureCoordinate;\n" + 12 | "varying vec2 rightTextureCoordinate;\n" + 13 | "\n" + 14 | "varying vec2 topTextureCoordinate;\n" + 15 | "varying vec2 topLeftTextureCoordinate;\n" + 16 | "varying vec2 topRightTextureCoordinate;\n" + 17 | "\n" + 18 | "varying vec2 bottomTextureCoordinate;\n" + 19 | "varying vec2 bottomLeftTextureCoordinate;\n" + 20 | "varying vec2 bottomRightTextureCoordinate;\n" + 21 | "\n" + 22 | "uniform sampler2D inputImageTexture;\n" + 23 | "\n" + 24 | "void main()\n" + 25 | "{\n" + 26 | " float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r;\n" + 27 | " float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r;\n" + 28 | " float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r;\n" + 29 | " float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r;\n" + 30 | " float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r;\n" + 31 | " float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r;\n" + 32 | " float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r;\n" + 33 | " float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r;\n" + 34 | "\n" + 35 | " vec2 gradientDirection;\n" + 36 | " gradientDirection.x = -bottomLeftIntensity - 2.0 * leftIntensity - topLeftIntensity + bottomRightIntensity + 2.0 * rightIntensity + topRightIntensity;\n" + 37 | " gradientDirection.y = -topLeftIntensity - 2.0 * topIntensity - topRightIntensity + bottomLeftIntensity + 2.0 * bottomIntensity + bottomRightIntensity;\n" + 38 | "\n" + 39 | " float gradientMagnitude = length(gradientDirection);\n" + 40 | " vec2 normalizedDirection = normalize(gradientDirection);\n" + 41 | " normalizedDirection = sign(normalizedDirection) * floor(abs(normalizedDirection) + 0.617316); // Offset by 1-sin(pi/8) to set to 0 if near axis, 1 if away\n" + 42 | " normalizedDirection = (normalizedDirection + 1.0) * 0.5; // Place -1.0 - 1.0 within 0 - 1.0\n" + 43 | "\n" + 44 | " gl_FragColor = vec4(gradientMagnitude, normalizedDirection.x, normalizedDirection.y, 1.0);\n" + 45 | "}"; 46 | 47 | public GPUImageDirectionalSobelEdgeDetectionFilter() { 48 | super(DIRECTIONAL_SOBEL_EDGE_DETECTION_FRAGMENT_SHADER); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/filter_3x3_sampling/GPUImageNonMaximumSuppressionFilter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.filter_3x3_sampling; 2 | 3 | /** 4 | * 非极大值抑制,简称为NMS算法。是一种获取局部最大值的有效方法。 5 | * 用于局部筛选重点 6 | */ 7 | public class GPUImageNonMaximumSuppressionFilter extends GPUImage3x3TextureSamplingFilter { 8 | public static final String NMS_FRAGMENT_SHADER = "" + 9 | "uniform sampler2D inputImageTexture;\n" + 10 | "\n" + 11 | "varying highp vec2 textureCoordinate;\n" + 12 | "varying highp vec2 leftTextureCoordinate;\n" + 13 | "varying highp vec2 rightTextureCoordinate;\n" + 14 | "\n" + 15 | "varying highp vec2 topTextureCoordinate;\n" + 16 | "varying highp vec2 topLeftTextureCoordinate;\n" + 17 | "varying highp vec2 topRightTextureCoordinate;\n" + 18 | "\n" + 19 | "varying highp vec2 bottomTextureCoordinate;\n" + 20 | "varying highp vec2 bottomLeftTextureCoordinate;\n" + 21 | "varying highp vec2 bottomRightTextureCoordinate;\n" + 22 | "\n" + 23 | "void main()\n" + 24 | "{\n" + 25 | "lowp float bottomColor = texture2D(inputImageTexture, bottomTextureCoordinate).r;\n" + 26 | "lowp float bottomLeftColor = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r;\n" + 27 | "lowp float bottomRightColor = texture2D(inputImageTexture, bottomRightTextureCoordinate).r;\n" + 28 | "lowp vec4 centerColor = texture2D(inputImageTexture, textureCoordinate);\n" + 29 | "lowp float leftColor = texture2D(inputImageTexture, leftTextureCoordinate).r;\n" + 30 | "lowp float rightColor = texture2D(inputImageTexture, rightTextureCoordinate).r;\n" + 31 | "lowp float topColor = texture2D(inputImageTexture, topTextureCoordinate).r;\n" + 32 | "lowp float topRightColor = texture2D(inputImageTexture, topRightTextureCoordinate).r;\n" + 33 | "lowp float topLeftColor = texture2D(inputImageTexture, topLeftTextureCoordinate).r;\n" + 34 | "\n" + 35 | "// Use a tiebreaker for pixels to the left and immediately above this one\n" + 36 | "lowp float multiplier = 1.0 - step(centerColor.r, topColor);\n" + 37 | "multiplier = multiplier * 1.0 - step(centerColor.r, topLeftColor);\n" + 38 | "multiplier = multiplier * 1.0 - step(centerColor.r, leftColor);\n" + 39 | "multiplier = multiplier * 1.0 - step(centerColor.r, bottomLeftColor);\n" + 40 | "\n" + 41 | "lowp float maxValue = max(centerColor.r, bottomColor);\n" + 42 | "maxValue = max(maxValue, bottomRightColor);\n" + 43 | "maxValue = max(maxValue, rightColor);\n" + 44 | "maxValue = max(maxValue, topRightColor);\n" + 45 | "\n" + 46 | "gl_FragColor = vec4((centerColor.rgb * step(maxValue, centerColor.r) * multiplier), 1.0);\n" + 47 | "}\n"; 48 | 49 | public GPUImageNonMaximumSuppressionFilter() { 50 | super(NMS_FRAGMENT_SHADER); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/filter_3x3_sampling/GPUImageSobelThresholdFilter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.filter_3x3_sampling; 2 | 3 | import android.opengl.GLES30; 4 | 5 | /** 6 | * 严格索贝尔算子边缘检测滤镜 7 | */ 8 | public class GPUImageSobelThresholdFilter extends GPUImage3x3TextureSamplingFilter { 9 | 10 | public static final String SOBEL_THRESHOLD_EDGE_DETECTION = "" + 11 | "precision mediump float;\n" + 12 | "\n" + 13 | "varying vec2 textureCoordinate;\n" + 14 | "varying vec2 leftTextureCoordinate;\n" + 15 | "varying vec2 rightTextureCoordinate;\n" + 16 | "\n" + 17 | "varying vec2 topTextureCoordinate;\n" + 18 | "varying vec2 topLeftTextureCoordinate;\n" + 19 | "varying vec2 topRightTextureCoordinate;\n" + 20 | "\n" + 21 | "varying vec2 bottomTextureCoordinate;\n" + 22 | "varying vec2 bottomLeftTextureCoordinate;\n" + 23 | "varying vec2 bottomRightTextureCoordinate;\n" + 24 | "\n" + 25 | "uniform sampler2D inputImageTexture;\n" + 26 | "uniform lowp float threshold;\n" + 27 | "\n" + 28 | "const highp vec3 W = vec3(0.2125, 0.7154, 0.0721);\n" + 29 | "\n" + 30 | "void main()\n" + 31 | "{\n" + 32 | " float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r;\n" + 33 | " float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r;\n" + 34 | " float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r;\n" + 35 | " float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r;\n" + 36 | " float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r;\n" + 37 | " float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r;\n" + 38 | " float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r;\n" + 39 | " float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r;\n" + 40 | " float h = -topLeftIntensity - 2.0 * topIntensity - topRightIntensity + bottomLeftIntensity + 2.0 * bottomIntensity + bottomRightIntensity;\n" + 41 | " float v = -bottomLeftIntensity - 2.0 * leftIntensity - topLeftIntensity + bottomRightIntensity + 2.0 * rightIntensity + topRightIntensity;\n" + 42 | "\n" + 43 | " float mag = 1.0 - length(vec2(h, v));\n" + 44 | " mag = step(threshold, mag);\n" + 45 | "\n" + 46 | " gl_FragColor = vec4(vec3(mag), 1.0);\n" + 47 | "}\n"; 48 | 49 | private int mUniformThresholdLocation; 50 | private float mThreshold = 0.9f; 51 | 52 | public GPUImageSobelThresholdFilter() { 53 | this(0.9f); 54 | } 55 | 56 | public GPUImageSobelThresholdFilter(float threshold) { 57 | super(SOBEL_THRESHOLD_EDGE_DETECTION); 58 | mThreshold = threshold; 59 | } 60 | 61 | @Override 62 | public void onInit() { 63 | super.onInit(); 64 | mUniformThresholdLocation = GLES30.glGetUniformLocation(getProgram(), "threshold"); 65 | } 66 | 67 | @Override 68 | public void onInitialized() { 69 | super.onInitialized(); 70 | setThreshold(mThreshold); 71 | } 72 | 73 | public void setThreshold(final float threshold) { 74 | mThreshold = threshold; 75 | setFloat(mUniformThresholdLocation, threshold); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/filter_3x3_sampling/GPUImageWeakPixelInclusionFilter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.filter_3x3_sampling; 2 | 3 | /** 像素收缩滤镜 */ 4 | public class GPUImageWeakPixelInclusionFilter extends GPUImage3x3TextureSamplingFilter { 5 | public static final String WEAKPIXEL_FRAGMENT_SHADER = "" + 6 | "precision lowp float;\n" + 7 | "\n" + 8 | "varying vec2 textureCoordinate;\n" + 9 | "varying vec2 leftTextureCoordinate;\n" + 10 | "varying vec2 rightTextureCoordinate;\n" + 11 | "\n" + 12 | "varying vec2 topTextureCoordinate;\n" + 13 | "varying vec2 topLeftTextureCoordinate;\n" + 14 | "varying vec2 topRightTextureCoordinate;\n" + 15 | "\n" + 16 | "varying vec2 bottomTextureCoordinate;\n" + 17 | "varying vec2 bottomLeftTextureCoordinate;\n" + 18 | "varying vec2 bottomRightTextureCoordinate;\n" + 19 | "\n" + 20 | "uniform sampler2D inputImageTexture;\n" + 21 | "\n" + 22 | "void main()\n" + 23 | "{\n" + 24 | "float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r;\n" + 25 | "float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r;\n" + 26 | "float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r;\n" + 27 | "float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r;\n" + 28 | "float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r;\n" + 29 | "float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r;\n" + 30 | "float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r;\n" + 31 | "float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r;\n" + 32 | "float centerIntensity = texture2D(inputImageTexture, textureCoordinate).r;\n" + 33 | "\n" + 34 | "float pixelIntensitySum = bottomLeftIntensity + topRightIntensity + topLeftIntensity + bottomRightIntensity + leftIntensity + rightIntensity + bottomIntensity + topIntensity + centerIntensity;\n" + 35 | "float sumTest = step(1.5, pixelIntensitySum);\n" + 36 | "float pixelTest = step(0.01, centerIntensity);\n" + 37 | "\n" + 38 | "gl_FragColor = vec4(vec3(sumTest * pixelTest), 1.0);\n" + 39 | "}\n"; 40 | 41 | public GPUImageWeakPixelInclusionFilter() { 42 | super(WEAKPIXEL_FRAGMENT_SHADER); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/filter_dual_sampling/GPUImageTwoPassTextureSamplingFilter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.filter_dual_sampling; 2 | 3 | import android.opengl.GLES30; 4 | 5 | import cn.co.willow.android.ultimate.gpuimage.core_render_filter.GPUImageFilter; 6 | import cn.co.willow.android.ultimate.gpuimage.core_render_filter.GPUImageFilterGroup; 7 | 8 | /** 9 | * 双通纹理采样滤镜,双通滤波常用于高斯模糊等需要横纵向双重过滤的滤镜 10 | * two-pass filter, whitch is always use in some filter that needs x and y two way to deal in a single task. 11 | */ 12 | public class GPUImageTwoPassTextureSamplingFilter extends GPUImageFilterGroup { 13 | public GPUImageTwoPassTextureSamplingFilter(String firstVertexShader, String firstFragmentShader, 14 | String secondVertexShader, String secondFragmentShader) { 15 | super(null); 16 | addFilter(new GPUImageFilter(firstVertexShader, firstFragmentShader)); 17 | addFilter(new GPUImageFilter(secondVertexShader, secondFragmentShader)); 18 | } 19 | 20 | @Override 21 | public void onInit() { 22 | super.onInit(); 23 | initTexelOffsets(); 24 | } 25 | 26 | @Override 27 | public void onOutputSizeChanged(int width, int height) { 28 | super.onOutputSizeChanged(width, height); 29 | initTexelOffsets(); 30 | } 31 | 32 | protected void initTexelOffsets() { 33 | float ratio = getHorizontalTexelOffsetRatio(); 34 | GPUImageFilter filter = mFilters.get(0); 35 | int texelWidthOffsetLocation = GLES30.glGetUniformLocation(filter.getProgram(), "texelWidthOffset"); 36 | int texelHeightOffsetLocation = GLES30.glGetUniformLocation(filter.getProgram(), "texelHeightOffset"); 37 | filter.setFloat(texelWidthOffsetLocation, ratio / mOutputWidth); 38 | filter.setFloat(texelHeightOffsetLocation, 0); 39 | 40 | ratio = getVerticalTexelOffsetRatio(); 41 | filter = mFilters.get(1); 42 | texelWidthOffsetLocation = GLES30.glGetUniformLocation(filter.getProgram(), "texelWidthOffset"); 43 | texelHeightOffsetLocation = GLES30.glGetUniformLocation(filter.getProgram(), "texelHeightOffset"); 44 | filter.setFloat(texelWidthOffsetLocation, 0); 45 | filter.setFloat(texelHeightOffsetLocation, ratio / mOutputHeight); 46 | } 47 | 48 | public float getVerticalTexelOffsetRatio() { 49 | return 1f; 50 | } 51 | 52 | public float getHorizontalTexelOffsetRatio() { 53 | return 1f; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/recommend_effect_filter/GPUImageEmbossFilter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Willow 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.recommend_effect_filter; 18 | 19 | import cn.co.willow.android.ultimate.gpuimage.core_render_filter.filter_3x3_sampling.GPUImage3x3ConvolutionFilter; 20 | 21 | /** 22 | * 特效滤镜:浮雕效果,值范围 0.0~4.0,1.0为正常值 23 | * Applies an emboss effect to the image.
24 | *
25 | * Intensity ranges from 0.0 to 4.0, with 1.0 as the normal level 26 | */ 27 | public class GPUImageEmbossFilter extends GPUImage3x3ConvolutionFilter { 28 | private float mIntensity; 29 | 30 | public GPUImageEmbossFilter() { 31 | this(1.0f); 32 | } 33 | 34 | public GPUImageEmbossFilter(final float intensity) { 35 | super(); 36 | mIntensity = intensity; 37 | } 38 | 39 | @Override 40 | public void onInit() { 41 | super.onInit(); 42 | setIntensity(mIntensity); 43 | } 44 | 45 | public void setIntensity(final float intensity) { 46 | mIntensity = intensity; 47 | setConvolutionKernel(new float[]{ 48 | intensity * (-2.0f), -intensity, 0.0f, 49 | -intensity, 1.0f, intensity, 50 | 0.0f, intensity, intensity * 2.0f, 51 | }); 52 | } 53 | 54 | public float getIntensity() { 55 | return mIntensity; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/recommend_effect_filter/GPUImageHalftoneFilter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.recommend_effect_filter; 2 | 3 | import android.opengl.GLES30; 4 | 5 | import cn.co.willow.android.ultimate.gpuimage.core_render_filter.GPUImageFilter; 6 | 7 | /** 8 | * 特效滤镜:点染,图像黑白化,由黑点构成原图的大致图形 9 | * halftone effect 10 | */ 11 | public class GPUImageHalftoneFilter extends GPUImageFilter { 12 | public static final String HALFTONE_FRAGMENT_SHADER = "" + 13 | "varying highp vec2 textureCoordinate;\n" + 14 | 15 | "uniform sampler2D inputImageTexture;\n" + 16 | 17 | "uniform highp float fractionalWidthOfPixel;\n" + 18 | "uniform highp float aspectRatio;\n" + 19 | 20 | "const highp vec3 W = vec3(0.2125, 0.7154, 0.0721);\n" + 21 | 22 | "void main()\n" + 23 | "{\n" + 24 | " highp vec2 sampleDivisor = vec2(fractionalWidthOfPixel, fractionalWidthOfPixel / aspectRatio);\n" + 25 | " highp vec2 samplePos = textureCoordinate - mod(textureCoordinate, sampleDivisor) + 0.5 * sampleDivisor;\n" + 26 | " highp vec2 textureCoordinateToUse = vec2(textureCoordinate.x, (textureCoordinate.y * aspectRatio + 0.5 - 0.5 * aspectRatio));\n" + 27 | " highp vec2 adjustedSamplePos = vec2(samplePos.x, (samplePos.y * aspectRatio + 0.5 - 0.5 * aspectRatio));\n" + 28 | " highp float distanceFromSamplePoint = distance(adjustedSamplePos, textureCoordinateToUse);\n" + 29 | " lowp vec3 sampledColor = texture2D(inputImageTexture, samplePos).rgb;\n" + 30 | " highp float dotScaling = 1.0 - dot(sampledColor, W);\n" + 31 | " lowp float checkForPresenceWithinDot = 1.0 - step(distanceFromSamplePoint, (fractionalWidthOfPixel * 0.5) * dotScaling);\n" + 32 | " gl_FragColor = vec4(vec3(checkForPresenceWithinDot), 1.0);\n" + 33 | "}"; 34 | 35 | private int mFractionalWidthOfPixelLocation; 36 | private int mAspectRatioLocation; 37 | 38 | private float mFractionalWidthOfAPixel; 39 | private float mAspectRatio; 40 | 41 | public GPUImageHalftoneFilter() { 42 | this(0.01f); 43 | } 44 | 45 | public GPUImageHalftoneFilter(float fractionalWidthOfAPixel) { 46 | super(NO_FILTER_VERTEX_SHADER, HALFTONE_FRAGMENT_SHADER); 47 | mFractionalWidthOfAPixel = fractionalWidthOfAPixel; 48 | } 49 | 50 | @Override 51 | public void onInit() { 52 | super.onInit(); 53 | mFractionalWidthOfPixelLocation = GLES30.glGetUniformLocation(getProgram(), "fractionalWidthOfPixel"); 54 | mAspectRatioLocation = GLES30.glGetUniformLocation(getProgram(), "aspectRatio"); 55 | setFractionalWidthOfAPixel(mFractionalWidthOfAPixel); 56 | } 57 | 58 | @Override 59 | public void onOutputSizeChanged(final int width, final int height) { 60 | super.onOutputSizeChanged(width, height); 61 | setAspectRatio((float) height / (float) width); 62 | } 63 | 64 | public void setFractionalWidthOfAPixel(final float fractionalWidthOfAPixel) { 65 | mFractionalWidthOfAPixel = fractionalWidthOfAPixel; 66 | setFloat(mFractionalWidthOfPixelLocation, mFractionalWidthOfAPixel); 67 | } 68 | 69 | public void setAspectRatio(final float aspectRatio) { 70 | mAspectRatio = aspectRatio; 71 | setFloat(mAspectRatioLocation, mAspectRatio); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/recommend_effect_filter/GPUImageHazeFilter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.recommend_effect_filter; 2 | 3 | import android.opengl.GLES30; 4 | 5 | import cn.co.willow.android.ultimate.gpuimage.core_render_filter.GPUImageFilter; 6 | 7 | /** 8 | * 特效滤镜:朦胧加暗 9 | * The haze filter can be used to add or remove haze. 10 | *

11 | * This is similar to a UV filter. 12 | */ 13 | public class GPUImageHazeFilter extends GPUImageFilter { 14 | public static final String HAZE_FRAGMENT_SHADER = "" + 15 | "varying highp vec2 textureCoordinate;\n" + 16 | "\n" + 17 | "uniform sampler2D inputImageTexture;\n" + 18 | "\n" + 19 | "uniform lowp float distance;\n" + 20 | "uniform highp float slope;\n" + 21 | "\n" + 22 | "void main()\n" + 23 | "{\n" + 24 | " //todo reconsider precision modifiers \n" + 25 | " highp vec4 color = vec4(1.0);//todo reimplement as a parameter\n" + 26 | "\n" + 27 | " highp float d = textureCoordinate.y * slope + distance; \n" + 28 | "\n" + 29 | " highp vec4 c = texture2D(inputImageTexture, textureCoordinate) ; // consider using unpremultiply\n" + 30 | "\n" + 31 | " c = (c - d * color) / (1.0 -d);\n" + 32 | "\n" + 33 | " gl_FragColor = c; //consider using premultiply(c);\n" + 34 | "}\n"; 35 | 36 | private float mDistance; 37 | private int mDistanceLocation; 38 | private float mSlope; 39 | private int mSlopeLocation; 40 | 41 | public GPUImageHazeFilter() { 42 | this(0.2f, 0.0f); 43 | } 44 | 45 | public GPUImageHazeFilter(float distance, float slope) { 46 | super(NO_FILTER_VERTEX_SHADER, HAZE_FRAGMENT_SHADER); 47 | mDistance = distance; 48 | mSlope = slope; 49 | } 50 | 51 | @Override 52 | public void onInit() { 53 | super.onInit(); 54 | mDistanceLocation = GLES30.glGetUniformLocation(getProgram(), "distance"); 55 | mSlopeLocation = GLES30.glGetUniformLocation(getProgram(), "slope"); 56 | } 57 | 58 | @Override 59 | public void onInitialized() { 60 | super.onInitialized(); 61 | setDistance(mDistance); 62 | setSlope(mSlope); 63 | } 64 | 65 | /** 66 | * Strength of the color applied. Default 0. Values between -.3 and .3 are best. 67 | * 68 | * @param distance -0.3 to 0.3 are best, default 0 69 | */ 70 | public void setDistance(float distance) { 71 | mDistance = distance; 72 | setFloat(mDistanceLocation, distance); 73 | } 74 | 75 | /** 76 | * Amount of color change. Default 0. Values between -.3 and .3 are best. 77 | * 78 | * @param slope -0.3 to 0.3 are best, default 0 79 | */ 80 | public void setSlope(float slope) { 81 | mSlope = slope; 82 | setFloat(mSlopeLocation, slope); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/recommend_effect_filter/GPUImagePixelationFilter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Willow 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.recommend_effect_filter; 18 | 19 | import android.opengl.GLES30; 20 | 21 | import cn.co.willow.android.ultimate.gpuimage.core_render_filter.GPUImageFilter; 22 | 23 | /** 24 | * 特效滤镜:像素化滤镜 25 | * Applies a grayscale effect to the image. 26 | */ 27 | public class GPUImagePixelationFilter extends GPUImageFilter { 28 | public static final String PIXELATION_FRAGMENT_SHADER = "" + 29 | "precision highp float;\n" + 30 | 31 | "varying vec2 textureCoordinate;\n" + 32 | 33 | "uniform float imageWidthFactor;\n" + 34 | "uniform float imageHeightFactor;\n" + 35 | "uniform sampler2D inputImageTexture;\n" + 36 | "uniform float pixel;\n" + 37 | 38 | "void main()\n" + 39 | "{\n" + 40 | " vec2 uv = textureCoordinate.xy;\n" + 41 | " float dx = pixel * imageWidthFactor;\n" + 42 | " float dy = pixel * imageHeightFactor;\n" + 43 | " vec2 coord = vec2(dx * floor(uv.x / dx), dy * floor(uv.y / dy));\n" + 44 | " vec3 tc = texture2D(inputImageTexture, coord).xyz;\n" + 45 | " gl_FragColor = vec4(tc, 1.0);\n" + 46 | "}"; 47 | 48 | private int mImageWidthFactorLocation; 49 | private int mImageHeightFactorLocation; 50 | private float mPixel; 51 | private int mPixelLocation; 52 | 53 | public GPUImagePixelationFilter() { 54 | super(NO_FILTER_VERTEX_SHADER, PIXELATION_FRAGMENT_SHADER); 55 | mPixel = 1.0f; 56 | } 57 | 58 | @Override 59 | public void onInit() { 60 | super.onInit(); 61 | mImageWidthFactorLocation = GLES30.glGetUniformLocation(getProgram(), "imageWidthFactor"); 62 | mImageHeightFactorLocation = GLES30.glGetUniformLocation(getProgram(), "imageHeightFactor"); 63 | mPixelLocation = GLES30.glGetUniformLocation(getProgram(), "pixel"); 64 | setPixel(mPixel); 65 | } 66 | 67 | @Override 68 | public void onOutputSizeChanged(final int width, final int height) { 69 | super.onOutputSizeChanged(width, height); 70 | setFloat(mImageWidthFactorLocation, 1.0f / width); 71 | setFloat(mImageHeightFactorLocation, 1.0f / height); 72 | } 73 | 74 | public void setPixel(final float pixel) { 75 | mPixel = pixel; 76 | setFloat(mPixelLocation, mPixel); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/recommend_effect_filter/GPUImageSepiaFilter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.recommend_effect_filter; 2 | 3 | import cn.co.willow.android.ultimate.gpuimage.core_render_filter.color_enhance_filter.GPUImageColorMatrixFilter; 4 | 5 | /** 6 | * 一个简单的褐色老照片效果滤镜 7 | * Applies a simple sepia effect. 8 | */ 9 | public class GPUImageSepiaFilter extends GPUImageColorMatrixFilter { 10 | 11 | public GPUImageSepiaFilter() { 12 | this(1.0f); 13 | } 14 | 15 | public GPUImageSepiaFilter(final float intensity) { 16 | super(intensity, new float[]{ 17 | 0.3588f, 0.7044f, 0.1368f, 0.0f, 18 | 0.2990f, 0.5870f, 0.1140f, 0.0f, 19 | 0.2392f, 0.4696f, 0.0912f, 0.0f, 20 | 0f, 0f, 0f, 1.0f 21 | }); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/recommend_effect_filter_group/GPUImageSketchFilter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Willow 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.recommend_effect_filter_group; 18 | 19 | import cn.co.willow.android.ultimate.gpuimage.core_render_filter.GPUImageFilterGroup; 20 | import cn.co.willow.android.ultimate.gpuimage.core_render_filter.base_filter.GPUImageGrayscaleFilter; 21 | import cn.co.willow.android.ultimate.gpuimage.core_render_filter.filter_3x3_sampling.GPUImage3x3TextureSamplingFilter; 22 | 23 | /** 24 | * 素描滤镜,本滤镜为反色索贝尔算子算法结合灰度滤镜组成 25 | * Converts video to look like a sketch. 26 | * This is just the Sobel edge detection filter with the colors inverted. 27 | */ 28 | public class GPUImageSketchFilter extends GPUImageFilterGroup { 29 | public static final String SKETCH_FRAGMENT_SHADER = "" + 30 | "precision mediump float;\n" + 31 | "\n" + 32 | "varying vec2 textureCoordinate;\n" + 33 | "varying vec2 leftTextureCoordinate;\n" + 34 | "varying vec2 rightTextureCoordinate;\n" + 35 | "\n" + 36 | "varying vec2 topTextureCoordinate;\n" + 37 | "varying vec2 topLeftTextureCoordinate;\n" + 38 | "varying vec2 topRightTextureCoordinate;\n" + 39 | "\n" + 40 | "varying vec2 bottomTextureCoordinate;\n" + 41 | "varying vec2 bottomLeftTextureCoordinate;\n" + 42 | "varying vec2 bottomRightTextureCoordinate;\n" + 43 | "\n" + 44 | "uniform sampler2D inputImageTexture;\n" + 45 | "\n" + 46 | "void main()\n" + 47 | "{\n" + 48 | "float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r;\n" + 49 | "float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r;\n" + 50 | "float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r;\n" + 51 | "float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r;\n" + 52 | "float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r;\n" + 53 | "float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r;\n" + 54 | "float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r;\n" + 55 | "float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r;\n" + 56 | "float h = -topLeftIntensity - 2.0 * topIntensity - topRightIntensity + bottomLeftIntensity + 2.0 * bottomIntensity + bottomRightIntensity;\n" + 57 | "float v = -bottomLeftIntensity - 2.0 * leftIntensity - topLeftIntensity + bottomRightIntensity + 2.0 * rightIntensity + topRightIntensity;\n" + 58 | "\n" + 59 | "float mag = 1.0 - length(vec2(h, v));\n" + 60 | "\n" + 61 | "gl_FragColor = vec4(vec3(mag), 1.0);\n" + 62 | "}\n"; 63 | 64 | public GPUImageSketchFilter() { 65 | super(); 66 | addFilter(new GPUImageGrayscaleFilter()); 67 | addFilter(new GPUImage3x3TextureSamplingFilter(SKETCH_FRAGMENT_SHADER)); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/recommend_effect_filter_group/GPUImageSmoothCartoonFilter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.recommend_effect_filter_group; 2 | 3 | import cn.co.willow.android.ultimate.gpuimage.core_render_filter.GPUImageFilterGroup; 4 | import cn.co.willow.android.ultimate.gpuimage.core_render_filter.filter_dual_sampling.GPUImageGaussianBlurFilter; 5 | import cn.co.willow.android.ultimate.gpuimage.core_render_filter.recommend_effect_filter.GPUImageCartoonFilter; 6 | 7 | /** 8 | * 柔化的卡通效果滤镜,本滤镜为卡通滤镜结合高斯模糊滤镜组成 9 | * This uses a similar process as the GPUImageCartoonFilter, only it precedes the toon effect 10 | * with a Gaussian blur to smooth out noise. 11 | */ 12 | public class GPUImageSmoothCartoonFilter extends GPUImageFilterGroup { 13 | GPUImageGaussianBlurFilter blurFilter; 14 | GPUImageCartoonFilter toonFilter; 15 | 16 | /** 17 | * Setup and Tear down 18 | */ 19 | public GPUImageSmoothCartoonFilter() { 20 | // First pass: apply a variable Gaussian blur 21 | blurFilter = new GPUImageGaussianBlurFilter(); 22 | addFilter(blurFilter); 23 | 24 | // Second pass: run the Sobel edge detection on this blurred image, along with a posterization effect 25 | toonFilter = new GPUImageCartoonFilter(); 26 | addFilter(toonFilter); 27 | 28 | getFilters().add(blurFilter); 29 | 30 | setBlurSize(0.5f); 31 | setThreshold(0.2f); 32 | setQuantizationLevels(10.0f); 33 | } 34 | 35 | /** 36 | * Accessors 37 | */ 38 | public void setTexelWidth(float value) { 39 | toonFilter.setTexelWidth(value); 40 | } 41 | 42 | public void setTexelHeight(float value) { 43 | toonFilter.setTexelHeight(value); 44 | } 45 | 46 | public void setBlurSize(float value) { 47 | blurFilter.setBlurSize(value); 48 | } 49 | 50 | public void setThreshold(float value) { 51 | toonFilter.setThreshold(value); 52 | } 53 | 54 | public void setQuantizationLevels(float value) { 55 | toonFilter.setQuantizationLevels(value); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/core_render_filter/recommend_effect_filter_group/GPUImageThresholdEdgeDetection.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.core_render_filter.recommend_effect_filter_group; 2 | 3 | import cn.co.willow.android.ultimate.gpuimage.core_render_filter.GPUImageFilterGroup; 4 | import cn.co.willow.android.ultimate.gpuimage.core_render_filter.base_filter.GPUImageGrayscaleFilter; 5 | import cn.co.willow.android.ultimate.gpuimage.core_render_filter.filter_3x3_sampling.GPUImageSobelThresholdFilter; 6 | 7 | /** 8 | * 边缘检测滤镜,本滤镜为三重索贝尔算子算法结合灰度滤镜组成 9 | * 提供较普通索贝尔来说更严格的边缘检测 10 | * Applies sobel edge detection on the image. 11 | */ 12 | public class GPUImageThresholdEdgeDetection extends GPUImageFilterGroup { 13 | public GPUImageThresholdEdgeDetection() { 14 | super(); 15 | addFilter(new GPUImageGrayscaleFilter()); 16 | addFilter(new GPUImageSobelThresholdFilter()); 17 | } 18 | 19 | public void setLineSize(final float size) { 20 | ((GPUImageSobelThresholdFilter) getFilters().get(1)).setLineSize(size); 21 | } 22 | 23 | public void setThreshold(final float threshold) { 24 | ((GPUImageSobelThresholdFilter) getFilters().get(1)).setThreshold(threshold); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/manager/image_editor/image_loader/FileImageLoader.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.manager.image_editor.image_loader; 2 | 3 | import android.content.Context; 4 | import android.graphics.Bitmap; 5 | import android.graphics.BitmapFactory; 6 | import android.media.ExifInterface; 7 | 8 | import java.io.File; 9 | import java.io.IOException; 10 | 11 | import cn.co.willow.android.ultimate.gpuimage.core_render.PureImageRenderer; 12 | 13 | /** 14 | * get image from an exist file 15 | * 从已存在的文件来获取图片 16 | *

17 | * Created by willow.li on 2017/4/22. 18 | */ 19 | public class FileImageLoader extends BaseImageLoader { 20 | 21 | private final File mImageFile; 22 | 23 | public FileImageLoader(Context context, final PureImageRenderer mRenderer, File file) { 24 | super(context, mRenderer); 25 | mImageFile = file; 26 | } 27 | 28 | @Override 29 | protected Bitmap decode(BitmapFactory.Options options) { 30 | return BitmapFactory.decodeFile(mImageFile.getAbsolutePath(), options); 31 | } 32 | 33 | @Override 34 | protected int getImageOrientation() throws IOException { 35 | ExifInterface exif = new ExifInterface(mImageFile.getAbsolutePath()); 36 | int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1); 37 | switch (orientation) { 38 | case ExifInterface.ORIENTATION_NORMAL: 39 | return 0; 40 | case ExifInterface.ORIENTATION_ROTATE_90: 41 | return 90; 42 | case ExifInterface.ORIENTATION_ROTATE_180: 43 | return 180; 44 | case ExifInterface.ORIENTATION_ROTATE_270: 45 | return 270; 46 | default: 47 | return 0; 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/manager/image_editor/image_loader/UriImageLoader.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.manager.image_editor.image_loader; 2 | 3 | import android.content.Context; 4 | import android.database.Cursor; 5 | import android.graphics.Bitmap; 6 | import android.graphics.BitmapFactory; 7 | import android.net.Uri; 8 | import android.provider.MediaStore; 9 | 10 | import java.io.IOException; 11 | import java.io.InputStream; 12 | import java.net.URL; 13 | 14 | import cn.co.willow.android.ultimate.gpuimage.core_render.PureImageRenderer; 15 | 16 | /** 17 | * get image with uri 18 | * 根据传入 uri 来获取图片 19 | *

20 | * Created by willow.li on 2017/4/22. 21 | */ 22 | public class UriImageLoader extends BaseImageLoader { 23 | 24 | private final Uri mUri; 25 | 26 | public UriImageLoader(Context context, final PureImageRenderer mRenderer, Uri uri) { 27 | super(context,mRenderer); 28 | mUri = uri; 29 | } 30 | 31 | @Override 32 | protected Bitmap decode(BitmapFactory.Options options) { 33 | try { 34 | InputStream inputStream; 35 | if (mUri.getScheme().startsWith("http") || mUri.getScheme().startsWith("https")) { 36 | inputStream = new URL(mUri.toString()).openStream(); 37 | } else { 38 | inputStream = context.getContentResolver().openInputStream(mUri); 39 | } 40 | return BitmapFactory.decodeStream(inputStream, null, options); 41 | } catch (Exception e) { 42 | e.printStackTrace(); 43 | } 44 | return null; 45 | } 46 | 47 | @Override 48 | protected int getImageOrientation() throws IOException { 49 | Cursor cursor = context.getContentResolver().query(mUri, 50 | new String[]{MediaStore.Images.ImageColumns.ORIENTATION}, null, null, null); 51 | 52 | if (cursor == null || cursor.getCount() != 1) { 53 | return 0; 54 | } 55 | 56 | cursor.moveToFirst(); 57 | int orientation = cursor.getInt(0); 58 | cursor.close(); 59 | return orientation; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/manager/video_recorder/VideoRecordConstrain.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.manager.video_recorder; 2 | 3 | import java.io.File; 4 | 5 | /** 6 | * 通用录制接口约束 7 | */ 8 | public interface VideoRecordConstrain { 9 | 10 | void startRecord(File mOutputRecFile); 11 | 12 | void stopRecord(); 13 | 14 | void releaseRecord(); 15 | 16 | } 17 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/manager/video_recorder/VideoRecordManagerCallback.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.manager.video_recorder; 2 | 3 | import cn.co.willow.android.ultimate.gpuimage.core_config.RecorderMessageState; 4 | import cn.co.willow.android.ultimate.gpuimage.core_looper.meta.MetaData; 5 | import cn.co.willow.android.ultimate.gpuimage.ui.FilterRecoderView; 6 | 7 | public interface VideoRecordManagerCallback { 8 | 9 | void setCurrentItem(MetaData currentItemMetaData, FilterRecoderView currentRecorder); 10 | 11 | void setVideoRecorderState(VideoFilterManager mFilteManager, RecorderMessageState recorderMessageState); 12 | 13 | RecorderMessageState getCurrentPlayerState(); 14 | } 15 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/manager/video_recorder/record_messages/BaseMessage.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.manager.video_recorder.record_messages; 2 | 3 | /** 4 | * This generic interface for messages 5 | */ 6 | public interface BaseMessage { 7 | void runMessage(); 8 | void polledFromQueue(); 9 | void messageFinished(); 10 | } 11 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/manager/video_recorder/record_messages/BaseRecorderMessage.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.manager.video_recorder.record_messages; 2 | 3 | import cn.co.willow.android.ultimate.gpuimage.core_config.RecorderMessageState; 4 | import cn.co.willow.android.ultimate.gpuimage.manager.video_recorder.VideoFilterManager; 5 | import cn.co.willow.android.ultimate.gpuimage.manager.video_recorder.VideoRecordManagerCallback; 6 | 7 | /** 8 | * This is generic interface for RecordMessage 9 | */ 10 | public abstract class BaseRecorderMessage implements BaseMessage { 11 | 12 | private final VideoFilterManager mFilteManager; 13 | private final VideoRecordManagerCallback mCallback; 14 | 15 | public BaseRecorderMessage(VideoFilterManager mFilteManager, VideoRecordManagerCallback callback) { 16 | this.mFilteManager = mFilteManager; 17 | this.mCallback = callback; 18 | } 19 | 20 | protected final RecorderMessageState getCurrentState() { 21 | return mCallback.getCurrentPlayerState(); 22 | } 23 | 24 | @Override 25 | public final void polledFromQueue() { 26 | mCallback.setVideoRecorderState(mFilteManager, stateBefore()); 27 | } 28 | 29 | @Override 30 | public final void messageFinished() { 31 | mCallback.setVideoRecorderState(mFilteManager, stateAfter()); 32 | } 33 | 34 | public final void runMessage() { 35 | performAction(mFilteManager); 36 | } 37 | 38 | protected abstract void performAction(VideoFilterManager currentRecorder); 39 | protected abstract RecorderMessageState stateBefore(); 40 | protected abstract RecorderMessageState stateAfter(); 41 | 42 | } 43 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/manager/video_recorder/record_messages/ClearRecordInstance.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.manager.video_recorder.record_messages; 2 | 3 | import cn.co.willow.android.ultimate.gpuimage.core_config.RecorderMessageState; 4 | import cn.co.willow.android.ultimate.gpuimage.manager.video_recorder.VideoFilterManager; 5 | import cn.co.willow.android.ultimate.gpuimage.manager.video_recorder.VideoRecordManagerCallback; 6 | 7 | @Deprecated 8 | public class ClearRecordInstance extends BaseRecorderMessage { 9 | 10 | public ClearRecordInstance(VideoFilterManager mFilteManager, VideoRecordManagerCallback callback) { 11 | super(mFilteManager, callback); 12 | } 13 | 14 | @Override 15 | protected void performAction(VideoFilterManager currentRecorder) { 16 | //currentRecorder.clearRecorderInstance(); 17 | } 18 | 19 | @Override 20 | protected RecorderMessageState stateBefore() { 21 | return RecorderMessageState.CLEAR_ALL; 22 | } 23 | 24 | @Override 25 | protected RecorderMessageState stateAfter() { 26 | return RecorderMessageState.CLEAR_FINISH; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/manager/video_recorder/record_messages/CreateNewRecordInstance.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.manager.video_recorder.record_messages; 2 | 3 | import android.media.CamcorderProfile; 4 | 5 | import java.io.File; 6 | 7 | import cn.co.willow.android.ultimate.gpuimage.core_config.OutputConfig; 8 | import cn.co.willow.android.ultimate.gpuimage.core_config.RecorderMessageState; 9 | import cn.co.willow.android.ultimate.gpuimage.manager.video_recorder.VideoFilterManager; 10 | import cn.co.willow.android.ultimate.gpuimage.manager.video_recorder.VideoRecordManager; 11 | import cn.co.willow.android.ultimate.gpuimage.manager.video_recorder.VideoRecordManagerCallback; 12 | 13 | public class CreateNewRecordInstance extends BaseRecorderMessage { 14 | 15 | private final File mOutputRecFile; 16 | private final OutputConfig.VideoOutputConfig mVideoConfig; 17 | private final OutputConfig.AudioOutputConfig mAudioConfig; 18 | public CreateNewRecordInstance( 19 | VideoFilterManager currentRecorder, 20 | File mOutputRecFile, 21 | OutputConfig.VideoOutputConfig mVideoConfig, 22 | OutputConfig.AudioOutputConfig mAudioConfig, 23 | VideoRecordManagerCallback callback) { 24 | super(currentRecorder, callback); 25 | this.mOutputRecFile = mOutputRecFile; 26 | this.mVideoConfig = mVideoConfig; 27 | this.mAudioConfig = mAudioConfig; 28 | } 29 | 30 | @Override 31 | protected void performAction(VideoFilterManager currentRecorder) { 32 | currentRecorder.createNewRecorderInstance(mOutputRecFile, mVideoConfig, mAudioConfig); 33 | } 34 | 35 | @Override 36 | protected RecorderMessageState stateBefore() { 37 | return RecorderMessageState.INITIALIZING; 38 | } 39 | 40 | @Override 41 | protected RecorderMessageState stateAfter() { 42 | return RecorderMessageState.INITIALIZED; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/manager/video_recorder/record_messages/RecordPrepare.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.manager.video_recorder.record_messages; 2 | 3 | import cn.co.willow.android.ultimate.gpuimage.core_config.RecorderMessageState; 4 | import cn.co.willow.android.ultimate.gpuimage.manager.video_recorder.VideoFilterManager; 5 | import cn.co.willow.android.ultimate.gpuimage.manager.video_recorder.VideoRecordManagerCallback; 6 | 7 | @Deprecated 8 | public class RecordPrepare extends BaseRecorderMessage { 9 | 10 | private RecorderMessageState resultState; 11 | 12 | public RecordPrepare(VideoFilterManager currentRecorder, VideoRecordManagerCallback callback) { 13 | super(currentRecorder, callback); 14 | } 15 | 16 | @Override 17 | protected void performAction(VideoFilterManager currentRecorder) { 18 | /*currentRecorder.prepare(); 19 | RecorderState resultOfPrepare = currentRecorder.getCurrentState(); 20 | switch (resultOfPrepare) { 21 | case IDLE: 22 | case INITIALIZED: 23 | case RECORD: 24 | case STOP: 25 | throw new RuntimeException("unhandled state " + resultOfPrepare); 26 | case PREPARED: 27 | resultState = RecorderMessageState.PREPARED; 28 | break; 29 | case ERROR: 30 | resultState = RecorderMessageState.ERROR; 31 | break; 32 | }*/ 33 | } 34 | 35 | @Override 36 | protected RecorderMessageState stateBefore() { 37 | return RecorderMessageState.PREPARING; 38 | } 39 | 40 | @Override 41 | protected RecorderMessageState stateAfter() { 42 | return resultState; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/manager/video_recorder/record_messages/RecordRelease.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.manager.video_recorder.record_messages; 2 | 3 | import cn.co.willow.android.ultimate.gpuimage.core_config.RecorderMessageState; 4 | import cn.co.willow.android.ultimate.gpuimage.manager.video_recorder.VideoFilterManager; 5 | import cn.co.willow.android.ultimate.gpuimage.manager.video_recorder.VideoRecordManagerCallback; 6 | 7 | public class RecordRelease extends BaseRecorderMessage { 8 | 9 | public RecordRelease(VideoFilterManager currentRecorder, VideoRecordManagerCallback callback) { 10 | super(currentRecorder, callback); 11 | } 12 | 13 | @Override 14 | protected void performAction(VideoFilterManager currentRecorder) { 15 | currentRecorder.release(); 16 | } 17 | 18 | @Override 19 | protected RecorderMessageState stateBefore() { 20 | return RecorderMessageState.RELEASE; 21 | } 22 | 23 | @Override 24 | protected RecorderMessageState stateAfter() { 25 | return RecorderMessageState.IDLE; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/manager/video_recorder/record_messages/RecordStart.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.manager.video_recorder.record_messages; 2 | 3 | import cn.co.willow.android.ultimate.gpuimage.core_config.RecorderMessageState; 4 | import cn.co.willow.android.ultimate.gpuimage.manager.video_recorder.VideoFilterManager; 5 | import cn.co.willow.android.ultimate.gpuimage.manager.video_recorder.VideoRecordManagerCallback; 6 | 7 | public class RecordStart extends BaseRecorderMessage { 8 | 9 | public RecordStart(VideoFilterManager currentRecorder, VideoRecordManagerCallback callback) { 10 | super(currentRecorder, callback); 11 | } 12 | 13 | @Override 14 | protected void performAction(VideoFilterManager currentRecorder) { 15 | currentRecorder.start(); 16 | } 17 | 18 | @Override 19 | protected RecorderMessageState stateBefore() { 20 | return RecorderMessageState.START_RECORD; 21 | } 22 | 23 | @Override 24 | protected RecorderMessageState stateAfter() { 25 | return RecorderMessageState.RECORDING; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/manager/video_recorder/record_messages/RecordStop.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.manager.video_recorder.record_messages; 2 | 3 | import cn.co.willow.android.ultimate.gpuimage.core_config.RecorderMessageState; 4 | import cn.co.willow.android.ultimate.gpuimage.manager.video_recorder.VideoFilterManager; 5 | import cn.co.willow.android.ultimate.gpuimage.manager.video_recorder.VideoRecordManagerCallback; 6 | 7 | public class RecordStop extends BaseRecorderMessage { 8 | 9 | public RecordStop(VideoFilterManager currentRecorder, VideoRecordManagerCallback callback) { 10 | super(currentRecorder, callback); 11 | } 12 | 13 | @Override 14 | protected void performAction(VideoFilterManager currentRecorder) { 15 | currentRecorder.stop(); 16 | } 17 | 18 | @Override 19 | protected RecorderMessageState stateBefore() { 20 | return RecorderMessageState.STOPING; 21 | } 22 | 23 | @Override 24 | protected RecorderMessageState stateAfter() { 25 | return RecorderMessageState.IDLE; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/ui/ScalePlayerView.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.ui; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | import android.widget.VideoView; 6 | 7 | /** 8 | * 可拉伸的 VideoView 9 | * Created by willow.li on 17/1/18. 10 | */ 11 | public class ScalePlayerView extends VideoView { 12 | 13 | public ScalePlayerView(Context context) { 14 | super(context); 15 | } 16 | 17 | public ScalePlayerView(Context context, AttributeSet attrs) { 18 | super(context, attrs); 19 | } 20 | 21 | public ScalePlayerView(Context context, AttributeSet attrs, int defStyleAttr) { 22 | super(context, attrs, defStyleAttr); 23 | } 24 | 25 | @Override 26 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 27 | int width = getDefaultSize(0, widthMeasureSpec); 28 | int height = getDefaultSize(0, heightMeasureSpec); 29 | setMeasuredDimension(width, height); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/utils/GPUImageNativeLibrary.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.utils; 2 | 3 | public class GPUImageNativeLibrary { 4 | static { 5 | LogUtil.i("GPUImageNativeLibrary::", "yuv-decoder loading start"); 6 | System.loadLibrary("yuv-decoder"); 7 | LogUtil.i("GPUImageNativeLibrary::", "yuv-decoder loading finish"); 8 | } 9 | 10 | public static native void YUVtoRBGA(byte[] yuv, int width, int height, int[] out); 11 | 12 | public static native void YUVtoARBG(byte[] yuv, int width, int height, int[] out); 13 | } 14 | -------------------------------------------------------------------------------- /library/src/main/java/cn/co/willow/android/ultimate/gpuimage/utils/TextureRotationUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Willow 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cn.co.willow.android.ultimate.gpuimage.utils; 18 | 19 | import cn.co.willow.android.ultimate.gpuimage.core_config.Rotation; 20 | 21 | /** 22 | * 纹理矩阵旋转帮助类 23 | */ 24 | public class TextureRotationUtil { 25 | 26 | public static final float TEXTURE_NO_ROTATION[] = { 27 | 0.0f, 1.0f, 28 | 1.0f, 1.0f, 29 | 0.0f, 0.0f, 30 | 1.0f, 0.0f, 31 | }; 32 | 33 | public static final float TEXTURE_ROTATED_90[] = { 34 | 1.0f, 1.0f, 35 | 1.0f, 0.0f, 36 | 0.0f, 1.0f, 37 | 0.0f, 0.0f, 38 | }; 39 | public static final float TEXTURE_ROTATED_180[] = { 40 | 1.0f, 0.0f, 41 | 0.0f, 0.0f, 42 | 1.0f, 1.0f, 43 | 0.0f, 1.0f, 44 | }; 45 | public static final float TEXTURE_ROTATED_270[] = { 46 | 0.0f, 0.0f, 47 | 0.0f, 1.0f, 48 | 1.0f, 0.0f, 49 | 1.0f, 1.0f, 50 | }; 51 | 52 | private TextureRotationUtil() { 53 | } 54 | 55 | public static float[] getRotation(final Rotation rotation, final boolean flipHorizontal, 56 | final boolean flipVertical) { 57 | float[] rotatedTex; 58 | switch (rotation) { 59 | case ROTATION_90: 60 | rotatedTex = TEXTURE_ROTATED_90; 61 | break; 62 | case ROTATION_180: 63 | rotatedTex = TEXTURE_ROTATED_180; 64 | break; 65 | case ROTATION_270: 66 | rotatedTex = TEXTURE_ROTATED_270; 67 | break; 68 | case NORMAL: 69 | default: 70 | rotatedTex = TEXTURE_NO_ROTATION; 71 | break; 72 | } 73 | if (flipHorizontal) { 74 | rotatedTex = new float[]{ 75 | flip(rotatedTex[0]), rotatedTex[1], 76 | flip(rotatedTex[2]), rotatedTex[3], 77 | flip(rotatedTex[4]), rotatedTex[5], 78 | flip(rotatedTex[6]), rotatedTex[7], 79 | }; 80 | } 81 | if (flipVertical) { 82 | rotatedTex = new float[]{ 83 | rotatedTex[0], flip(rotatedTex[1]), 84 | rotatedTex[2], flip(rotatedTex[3]), 85 | rotatedTex[4], flip(rotatedTex[5]), 86 | rotatedTex[6], flip(rotatedTex[7]), 87 | }; 88 | } 89 | return rotatedTex; 90 | } 91 | 92 | 93 | private static float flip(final float i) { 94 | if (i == 0.0f) { 95 | return 1.0f; 96 | } 97 | return 0.0f; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /library/src/test/java/cn/co/willow/android/ultimate/gpuimage/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() throws Exception { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /sample/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /sample/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 26 5 | buildToolsVersion "26.0.2" 6 | 7 | defaultConfig { 8 | applicationId "cn.co.willow.android.ultimate.gpuimage.sample" 9 | minSdkVersion 21 10 | targetSdkVersion 26 11 | versionCode 1 12 | versionName "1.0" 13 | 14 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 15 | 16 | } 17 | buildTypes { 18 | release { 19 | minifyEnabled false 20 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 21 | } 22 | } 23 | } 24 | 25 | dependencies { 26 | compile fileTree(dir: 'libs', include: ['*.jar']) 27 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 28 | exclude group: 'com.android.support', module: 'support-annotations' 29 | }) 30 | compile project(path: ':library') 31 | compile 'com.android.support:appcompat-v7:26.1.0' 32 | compile 'com.android.support:cardview-v7:26.1.0' 33 | compile 'com.android.support:design:26.1.0' 34 | compile 'com.android.support:multidex:1.0.1' 35 | compile 'com.android.support.constraint:constraint-layout:1.0.2' 36 | compile 'io.reactivex:rxandroid:1.2.1' 37 | compile 'io.reactivex:rxjava:1.1.6' 38 | compile 'com.github.bumptech.glide:glide:3.7.0' 39 | compile 'com.github.bumptech.glide:okhttp-integration:1.4.0' 40 | testCompile 'junit:junit:4.12' 41 | } 42 | -------------------------------------------------------------------------------- /sample/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in C:\DeveloperKits\Android\sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /sample/src/androidTest/java/cn/co/willow/android/ultimate/gpuimage/sample/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.sample; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumentation test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("cn.co.willow.android.ultimate.gpuimage.sample", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /sample/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 21 | 24 | 25 | 26 | 27 | 28 | 29 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /sample/src/main/java/cn/co/willow/android/ultimate/gpuimage/sample/SampleApplication.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.sample; 2 | 3 | import android.content.Context; 4 | import android.os.Handler; 5 | import android.support.multidex.MultiDex; 6 | import android.support.multidex.MultiDexApplication; 7 | 8 | /** 9 | * App实际对象类 10 | */ 11 | public class SampleApplication extends MultiDexApplication { 12 | 13 | private static SampleApplication mApplicationContext; // 主线程的上下文 14 | private static Handler mMainThreadsHandler; // 主线程的Handler 15 | private static Thread mMainThread; // 主线程 16 | private static int mMainThreadId; // 主线程id 17 | 18 | /*变量获取======================================================================================*/ 19 | 20 | /** 获得应用上下文 */ 21 | public static SampleApplication getApplication() { 22 | return mApplicationContext; 23 | } 24 | 25 | /** 获得主线程Handler */ 26 | public static Handler getMainThreadHandler() { 27 | return mMainThreadsHandler; 28 | } 29 | 30 | /** 获得主线程 */ 31 | public static Thread getMainThread() { 32 | return mMainThread; 33 | } 34 | 35 | /** 获得主线程id */ 36 | public static int getMainThreadId() { 37 | return mMainThreadId; 38 | } 39 | 40 | 41 | /*生命周期======================================================================================*/ 42 | @Override 43 | protected void attachBaseContext(Context base) { 44 | super.attachBaseContext(base); 45 | MultiDex.install(this); 46 | } 47 | 48 | @Override 49 | public void onCreate() { 50 | // 堆栈分析 51 | /* if (LeakCanary.isInAnalyzerProcess(this)) return; 52 | LeakCanary.install(this);*/ 53 | // 基本数据初始化 54 | this.mApplicationContext = this; 55 | this.mMainThreadsHandler = new Handler(); 56 | this.mMainThread = Thread.currentThread(); 57 | this.mMainThreadId = android.os.Process.myTid(); 58 | super.onCreate(); 59 | // 网络请求提供者 60 | 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /sample/src/main/java/cn/co/willow/android/ultimate/gpuimage/sample/activity/SplashActivity.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.sample.activity; 2 | 3 | import android.annotation.TargetApi; 4 | import android.content.Intent; 5 | import android.os.Build; 6 | import android.os.Bundle; 7 | import android.support.v4.app.ActivityOptionsCompat; 8 | import android.support.v4.util.Pair; 9 | import android.support.v4.view.ViewCompat; 10 | import android.support.v7.app.AppCompatActivity; 11 | import android.transition.Transition; 12 | import android.transition.TransitionInflater; 13 | import android.view.View; 14 | import android.view.ViewGroup; 15 | import android.widget.Button; 16 | 17 | 18 | import cn.co.willow.android.ultimate.gpuimage.sample.R; 19 | 20 | /** 21 | * @author willow.li 22 | */ 23 | public class SplashActivity extends AppCompatActivity implements View.OnClickListener { 24 | 25 | private ViewGroup mCPVirtualCont; 26 | private Button mBtnJump2Video; 27 | 28 | @Override 29 | protected void onCreate(Bundle savedInstanceState) { 30 | super.onCreate(savedInstanceState); 31 | setContentView(R.layout.activity_splash); 32 | initView(); 33 | 34 | // set page animator 35 | initPageAnimator(); 36 | } 37 | 38 | @Override 39 | protected void onResume() { 40 | super.onResume(); 41 | } 42 | 43 | @Override 44 | protected void onPause() { 45 | super.onPause(); 46 | } 47 | 48 | 49 | /*init page UI & Logic==========================================================================*/ 50 | @TargetApi(Build.VERSION_CODES.KITKAT) 51 | private void initView() { 52 | mCPVirtualCont = (ViewGroup) findViewById(R.id.control_pannel); 53 | mBtnJump2Video = (Button) findViewById(R.id.btn_video_recorder); 54 | mBtnJump2Video.setOnClickListener(this); 55 | } 56 | 57 | private void initPageAnimator() { 58 | Transition shareTrans = TransitionInflater.from(this).inflateTransition(R.transition.trans_control_pannel); 59 | } 60 | 61 | @Override 62 | public void onClick(View v) { 63 | switch (v.getId()) { 64 | case R.id.btn_video_recorder: 65 | String sharedViewName = getString(R.string.trans_control_pannel); 66 | //ViewCompat.setTransitionName(mBtnJump2Video, sharedViewName); 67 | Intent intent = new Intent(this, SampleVideoActivity.class); 68 | ActivityOptionsCompat optionsCompat = ActivityOptionsCompat.makeSceneTransitionAnimation(this, 69 | new Pair(mBtnJump2Video, sharedViewName)); 70 | startActivity(intent, optionsCompat.toBundle()); 71 | break; 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /sample/src/main/java/cn/co/willow/android/ultimate/gpuimage/sample/function_holder/BaseHolder.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.sample.function_holder; 2 | 3 | import android.app.Activity; 4 | import android.view.View; 5 | 6 | /** 7 | * 模块基类 8 | *

9 | * Created by willow.li on 16/7/24. 10 | */ 11 | public abstract class BaseHolder { 12 | /*关键变量=======================================================================================*/ 13 | protected Activity context; // 上下文 14 | protected View view; // 视图 15 | protected T data; // 数据 16 | 17 | public BaseHolder(Activity context) { 18 | this.context = context; 19 | } 20 | 21 | 22 | /*初始化方法======================================================================================*/ 23 | 24 | /** 构造函数通用部分 */ 25 | protected void initWhenConstruct() { 26 | init(); 27 | view = initView(); 28 | } 29 | 30 | /** 初始化视图之前的准备 */ 31 | public void init() { 32 | } 33 | 34 | /** 初始化视图 */ 35 | public abstract View initView(); 36 | 37 | /** 销毁时清空资源 */ 38 | protected abstract void clearAllResource(); 39 | 40 | /*数据加载=======================================================================================*/ 41 | 42 | /** 设置数据 */ 43 | public void setData(T data) { 44 | if (context instanceof Activity && ((Activity) context).isFinishing()) return; 45 | this.data = data; 46 | refreshView(); 47 | } 48 | 49 | /** 刷新视图 */ 50 | public void refreshView() { 51 | 52 | } 53 | 54 | 55 | /*对外暴露方法====================================================================================*/ 56 | 57 | /** 获得所属的持有者View */ 58 | public View getRootView() { 59 | return view; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /sample/src/main/java/cn/co/willow/android/ultimate/gpuimage/sample/function_holder/VideoPlayerDialog.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.sample.function_holder; 2 | 3 | import android.app.AlertDialog; 4 | import android.content.Context; 5 | import android.media.MediaPlayer; 6 | import android.net.Uri; 7 | import android.transition.TransitionInflater; 8 | import android.view.View; 9 | import android.view.WindowManager; 10 | 11 | import cn.co.willow.android.ultimate.gpuimage.sample.R; 12 | import cn.co.willow.android.ultimate.gpuimage.sample.util.UIUtils; 13 | import cn.co.willow.android.ultimate.gpuimage.ui.ScalePlayerView; 14 | 15 | /** 16 | * 对话框:确认对话框-标准式(包括单纯确认、确认取消) 17 | *

18 | * Created by willow.li on 17/1/22. 19 | */ 20 | public class VideoPlayerDialog extends AlertDialog { 21 | 22 | /*关键参数======================================================================================*/ 23 | private Context mContext; 24 | private View mDialogsView; 25 | private ScalePlayerView mVideoPlayer; 26 | 27 | public VideoPlayerDialog(Context context) { 28 | super(context); 29 | mContext = context; 30 | init(); 31 | } 32 | 33 | 34 | /*初始化========================================================================================*/ 35 | private void init() { 36 | mDialogsView = View.inflate(mContext, R.layout.holder_video_player, null); 37 | mVideoPlayer = (ScalePlayerView) mDialogsView.findViewById(R.id.spv_video_player); 38 | //TransitionInflater.from(mContext); 39 | } 40 | 41 | public VideoPlayerDialog setIsCancelable(boolean cancelable) { 42 | setCancelable(cancelable); 43 | return this; 44 | } 45 | 46 | public VideoPlayerDialog setVideoUrl(String url) { 47 | startsPlay(url); 48 | return this; 49 | } 50 | 51 | 52 | /*视频播放逻辑====================================================================================*/ 53 | /** 初始化播放器 */ 54 | private void initPlayer() { 55 | mVideoPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { 56 | @Override 57 | public void onPrepared(MediaPlayer mp) { 58 | mp.start(); 59 | } 60 | }); 61 | mVideoPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { 62 | @Override 63 | public void onCompletion(MediaPlayer mp) { 64 | onPlayFinish(); 65 | } 66 | }); 67 | mVideoPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() { 68 | @Override 69 | public boolean onError(MediaPlayer mp, int what, int extra) { 70 | onPlayFinish(); 71 | return true; 72 | } 73 | }); 74 | } 75 | 76 | /** 播放视频 */ 77 | private void startsPlay(String url) { 78 | mVideoPlayer.setVideoURI(Uri.parse(url)); 79 | } 80 | 81 | private void onPlayFinish() { 82 | dismiss(); 83 | } 84 | 85 | 86 | /*对外暴露方法==================================================================================*/ 87 | @Override 88 | public void show() { 89 | super.show(); 90 | WindowManager.LayoutParams params = getWindow().getAttributes(); 91 | params.height = (int) (UIUtils.getScreenHeight() * 0.6f); 92 | params.width = (int) (UIUtils.getScreenWidth() * 0.8f); 93 | getWindow().setAttributes(params); 94 | getWindow().setBackgroundDrawable(UIUtils.getDrawable(R.drawable.rectangle_transparent)); 95 | setContentView(mDialogsView); 96 | mVideoPlayer.setZOrderOnTop(true); 97 | mVideoPlayer.start(); 98 | } 99 | 100 | public static VideoPlayerDialog getDefault(Context context) { 101 | return new VideoPlayerDialog(context) 102 | .setIsCancelable(true); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /sample/src/main/java/cn/co/willow/android/ultimate/gpuimage/sample/self_defined_filter/GPUImageFace01Filter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.sample.self_defined_filter; 2 | 3 | import android.graphics.Bitmap; 4 | import android.graphics.BitmapFactory; 5 | 6 | import cn.co.willow.android.ultimate.gpuimage.core_render_filter.blend_mode_filter.color_mapping_blend.GPUImageLookupFilter; 7 | import cn.co.willow.android.ultimate.gpuimage.sample.R; 8 | import cn.co.willow.android.ultimate.gpuimage.sample.SampleApplication; 9 | 10 | /** 11 | * Created by willow.li on 16/11/9. 12 | */ 13 | public class GPUImageFace01Filter extends GPUImageLookupFilter { 14 | 15 | public GPUImageFace01Filter() { 16 | super(); 17 | Bitmap bitmap = BitmapFactory.decodeResource(SampleApplication.getApplication().getResources(), R.drawable.filter_face01); 18 | setBitmap(bitmap); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /sample/src/main/java/cn/co/willow/android/ultimate/gpuimage/sample/self_defined_filter/GPUImageFace02Filter.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.sample.self_defined_filter; 2 | 3 | import android.graphics.Bitmap; 4 | import android.graphics.BitmapFactory; 5 | 6 | import cn.co.willow.android.ultimate.gpuimage.core_render_filter.blend_mode_filter.color_mapping_blend.GPUImageLookupFilter; 7 | import cn.co.willow.android.ultimate.gpuimage.sample.R; 8 | import cn.co.willow.android.ultimate.gpuimage.sample.SampleApplication; 9 | 10 | /** 11 | * Created by willow.li on 16/11/9. 12 | */ 13 | public class GPUImageFace02Filter extends GPUImageLookupFilter { 14 | 15 | public GPUImageFace02Filter() { 16 | super(); 17 | Bitmap bitmap = BitmapFactory.decodeResource(SampleApplication.getApplication().getResources(), R.drawable.filter_face02); 18 | setBitmap(bitmap); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /sample/src/main/java/cn/co/willow/android/ultimate/gpuimage/sample/util/TimeUtil.java: -------------------------------------------------------------------------------- 1 | package cn.co.willow.android.ultimate.gpuimage.sample.util; 2 | 3 | import java.text.SimpleDateFormat; 4 | import java.util.Date; 5 | import java.util.Locale; 6 | 7 | 8 | /** 9 | * 简单的时间格式化工具 10 | * a simple time format util 11 | *

12 | * Created by willow.li on 17/10/3. 13 | */ 14 | 15 | public class TimeUtil { 16 | 17 | /** 18 | * 标准时间格式化 19 | * 20 | * @param startTime 开始时间(单位:ms) 21 | * @return 格式化时长 22 | */ 23 | public static String formatDuration(long startTime) { 24 | if (startTime == 0) { 25 | return "--:--"; 26 | } 27 | long duration = System.currentTimeMillis() / 1000 - startTime; 28 | long hours = duration / 3600; 29 | long minutes = (duration % 3600) / 60; 30 | long seconds = duration % 60; 31 | if (duration < 0) { 32 | return "--:--"; 33 | } 34 | if (hours >= 100) { 35 | return String.format(Locale.CHINA, "%d:%02d:%02d", hours, minutes, seconds); 36 | } else if (hours > 0) { 37 | return String.format(Locale.CHINA, "%02d:%02d:%02d", hours, minutes, seconds); 38 | } else { 39 | return String.format(Locale.CHINA, "%02d:%02d", minutes, seconds); 40 | } 41 | } 42 | 43 | /** 44 | * 视频播放进度格式化 45 | * 46 | * @param position 时长(单位:秒) 47 | * @return 格式化时长 48 | */ 49 | public static String generateTime(long position) { 50 | if (position == 0) { 51 | return "--:--"; 52 | } 53 | 54 | int totalSeconds = (int) ((position / 1000.0) - 0.5); 55 | 56 | int seconds = totalSeconds % 60; 57 | int minutes = (totalSeconds / 60) % 60; 58 | int hours = totalSeconds / 3600; 59 | 60 | if (hours > 0) { 61 | return String.format(Locale.CHINA, "%02d:%02d:%02d", hours, minutes, seconds); 62 | } else { 63 | return String.format(Locale.CHINA, "%02d:%02d", minutes, seconds); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xxhdpi/filter_face01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Windsander/Android-UltimateGPUImage/0545cb66b1ad0fa74e495ed52877d7d6128061ba/sample/src/main/res/drawable-xxhdpi/filter_face01.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xxhdpi/filter_face02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Windsander/Android-UltimateGPUImage/0545cb66b1ad0fa74e495ed52877d7d6128061ba/sample/src/main/res/drawable-xxhdpi/filter_face02.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable/control_alert_camera_btn.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/control_default_camera_btn.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/oval_red_point.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/rectangle_black_radius_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/rectangle_green_radius_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/rectangle_green_radius_bg_p.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/rectangle_red_radius_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/rectangle_transparent.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/side_nav_bar.xml: -------------------------------------------------------------------------------- 1 | 3 | 9 | -------------------------------------------------------------------------------- /sample/src/main/res/layout/activity_sample.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | 28 | 29 | 30 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /sample/src/main/res/layout/activity_splash.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 |