Repository: zerochl/MagicShow Branch: master Commit: 52438cced13e Files: 248 Total size: 707.4 KB Directory structure: gitextract_f9toojvk/ ├── .gitignore ├── MagicShow/ │ ├── .gitignore │ ├── CMakeLists.txt │ ├── build.gradle │ ├── proguard-rules.pro │ └── src/ │ ├── androidTest/ │ │ └── java/ │ │ └── com/ │ │ └── zero/ │ │ └── magicshow/ │ │ └── core/ │ │ └── ApplicationTest.java │ ├── main/ │ │ ├── AndroidManifest.xml │ │ ├── cpp/ │ │ │ ├── MagicJni.cpp │ │ │ ├── beautify/ │ │ │ │ ├── MagicBeautify.cpp │ │ │ │ └── MagicBeautify.h │ │ │ └── bitmap/ │ │ │ ├── BitmapOperation.cpp │ │ │ ├── BitmapOperation.h │ │ │ ├── Conversion.cpp │ │ │ ├── Conversion.h │ │ │ └── JniBitmap.h │ │ ├── java/ │ │ │ └── com/ │ │ │ └── zero/ │ │ │ └── magicshow/ │ │ │ ├── MagicShowManager.java │ │ │ ├── activity/ │ │ │ │ ├── AlbumActivity.java │ │ │ │ └── CameraActivity.java │ │ │ ├── adapter/ │ │ │ │ └── FilterAdapter.java │ │ │ ├── common/ │ │ │ │ ├── base/ │ │ │ │ │ ├── BaseActivity.java │ │ │ │ │ └── MagicBaseView.java │ │ │ │ ├── config/ │ │ │ │ │ ├── CameraConfig.java │ │ │ │ │ └── PathConfig.java │ │ │ │ ├── entity/ │ │ │ │ │ └── MagicShowResultEntity.java │ │ │ │ ├── iface/ │ │ │ │ │ ├── CameraShootCallBack.java │ │ │ │ │ ├── DialogYesOrNoCallBack.java │ │ │ │ │ ├── GravityCallBack.java │ │ │ │ │ ├── ImageEditCallBack.java │ │ │ │ │ └── MagicListener.java │ │ │ │ └── utils/ │ │ │ │ ├── BaseUtil.java │ │ │ │ ├── CameraBitmapUtil.java │ │ │ │ ├── CameraParamUtil.java │ │ │ │ ├── Constants.java │ │ │ │ ├── DateUtils.java │ │ │ │ ├── FilterTypeHelper.java │ │ │ │ ├── GravityUtil.java │ │ │ │ ├── MagicParams.java │ │ │ │ ├── OpenGlUtils.java │ │ │ │ ├── Rotation.java │ │ │ │ ├── RxBus.java │ │ │ │ ├── SavePictureTask.java │ │ │ │ ├── TextureRotationUtil.java │ │ │ │ └── ZeroSubject.java │ │ │ ├── core/ │ │ │ │ ├── MagicEngine.java │ │ │ │ ├── beautify/ │ │ │ │ │ └── MagicJni.java │ │ │ │ ├── camera/ │ │ │ │ │ ├── CameraEngine.java │ │ │ │ │ └── utils/ │ │ │ │ │ ├── CameraInfo.java │ │ │ │ │ └── CameraUtils.java │ │ │ │ ├── encoder/ │ │ │ │ │ ├── gles/ │ │ │ │ │ │ ├── EglCore.java │ │ │ │ │ │ └── EglSurfaceBase.java │ │ │ │ │ └── video/ │ │ │ │ │ ├── TextureMovieEncoder.java │ │ │ │ │ ├── VideoEncoderCore.java │ │ │ │ │ └── WindowSurface.java │ │ │ │ ├── filter/ │ │ │ │ │ ├── advanced/ │ │ │ │ │ │ ├── MagicAmaroFilter.java │ │ │ │ │ │ ├── MagicAntiqueFilter.java │ │ │ │ │ │ ├── MagicBeautyFilter.java │ │ │ │ │ │ ├── MagicBlackCatFilter.java │ │ │ │ │ │ ├── MagicBrannanFilter.java │ │ │ │ │ │ ├── MagicBrooklynFilter.java │ │ │ │ │ │ ├── MagicCalmFilter.java │ │ │ │ │ │ ├── MagicCoolFilter.java │ │ │ │ │ │ ├── MagicCrayonFilter.java │ │ │ │ │ │ ├── MagicEarlyBirdFilter.java │ │ │ │ │ │ ├── MagicEmeraldFilter.java │ │ │ │ │ │ ├── MagicEvergreenFilter.java │ │ │ │ │ │ ├── MagicFairytaleFilter.java │ │ │ │ │ │ ├── MagicFreudFilter.java │ │ │ │ │ │ ├── MagicHealthyFilter.java │ │ │ │ │ │ ├── MagicHefeFilter.java │ │ │ │ │ │ ├── MagicHudsonFilter.java │ │ │ │ │ │ ├── MagicImageAdjustFilter.java │ │ │ │ │ │ ├── MagicInkwellFilter.java │ │ │ │ │ │ ├── MagicKevinFilter.java │ │ │ │ │ │ ├── MagicLatteFilter.java │ │ │ │ │ │ ├── MagicLomoFilter.java │ │ │ │ │ │ ├── MagicN1977Filter.java │ │ │ │ │ │ ├── MagicNashvilleFilter.java │ │ │ │ │ │ ├── MagicNostalgiaFilter.java │ │ │ │ │ │ ├── MagicPixarFilter.java │ │ │ │ │ │ ├── MagicRiseFilter.java │ │ │ │ │ │ ├── MagicRomanceFilter.java │ │ │ │ │ │ ├── MagicSakuraFilter.java │ │ │ │ │ │ ├── MagicSierraFilter.java │ │ │ │ │ │ ├── MagicSketchFilter.java │ │ │ │ │ │ ├── MagicSkinWhitenFilter.java │ │ │ │ │ │ ├── MagicSunriseFilter.java │ │ │ │ │ │ ├── MagicSunsetFilter.java │ │ │ │ │ │ ├── MagicSutroFilter.java │ │ │ │ │ │ ├── MagicSweetsFilter.java │ │ │ │ │ │ ├── MagicTenderFilter.java │ │ │ │ │ │ ├── MagicToasterFilter.java │ │ │ │ │ │ ├── MagicValenciaFilter.java │ │ │ │ │ │ ├── MagicWaldenFilter.java │ │ │ │ │ │ ├── MagicWarmFilter.java │ │ │ │ │ │ ├── MagicWhiteCatFilter.java │ │ │ │ │ │ └── MagicXproIIFilter.java │ │ │ │ │ ├── base/ │ │ │ │ │ │ ├── MagicBaseGroupFilter.java │ │ │ │ │ │ ├── MagicCameraInputFilter.java │ │ │ │ │ │ ├── MagicLookupFilter.java │ │ │ │ │ │ └── gpuimage/ │ │ │ │ │ │ ├── GPUImageBrightnessFilter.java │ │ │ │ │ │ ├── GPUImageContrastFilter.java │ │ │ │ │ │ ├── GPUImageExposureFilter.java │ │ │ │ │ │ ├── GPUImageFilter.java │ │ │ │ │ │ ├── GPUImageHueFilter.java │ │ │ │ │ │ ├── GPUImageSaturationFilter.java │ │ │ │ │ │ └── GPUImageSharpenFilter.java │ │ │ │ │ └── utils/ │ │ │ │ │ ├── MagicFilterFactory.java │ │ │ │ │ └── MagicFilterType.java │ │ │ │ └── widget/ │ │ │ │ ├── BubbleSeekBar.java │ │ │ │ ├── MagicCameraView.java │ │ │ │ ├── MagicImageView.java │ │ │ │ └── TwoLineSeekBar.java │ │ │ ├── view/ │ │ │ │ └── edit/ │ │ │ │ ├── ImageEditFragment.java │ │ │ │ ├── ImageEditManager.java │ │ │ │ ├── adjust/ │ │ │ │ │ └── ImageEditAdjustView.java │ │ │ │ ├── beauty/ │ │ │ │ │ └── ImageEditBeautyView.java │ │ │ │ ├── filter/ │ │ │ │ │ └── ImageEditFilterView.java │ │ │ │ ├── iface/ │ │ │ │ │ └── ImageEditNavListener.java │ │ │ │ └── navigation/ │ │ │ │ └── ImageEditNavigationView.java │ │ │ └── viewmanager/ │ │ │ └── CameraManager.java │ │ ├── libs/ │ │ │ └── zero.jar │ │ └── res/ │ │ ├── anim/ │ │ │ ├── bottom_sliding_in.xml │ │ │ └── bottom_sliding_out.xml │ │ ├── color/ │ │ │ ├── selector_image_back.xml │ │ │ ├── selector_image_edit.xml │ │ │ └── selector_image_edit_yellow.xml │ │ ├── drawable/ │ │ │ ├── btn_camera_beauty.xml │ │ │ ├── btn_camera_filter.xml │ │ │ ├── btn_camera_shutter.xml │ │ │ ├── btn_layout_filters_bar_close.xml │ │ │ ├── corners_yuanjiao_dialog.xml │ │ │ ├── seekbar_progress.xml │ │ │ ├── seekbar_progress_light.xml │ │ │ ├── seekbar_thumb.xml │ │ │ ├── seekbar_thumb_light.xml │ │ │ ├── selector_filter_favorite_btn.xml │ │ │ ├── selector_filter_selected.xml │ │ │ ├── selector_image_adds.xml │ │ │ ├── selector_image_back.xml │ │ │ ├── selector_image_beauty.xml │ │ │ ├── selector_image_edit.xml │ │ │ ├── selector_image_edit_adjust_bright.xml │ │ │ ├── selector_image_edit_adjust_contrast.xml │ │ │ ├── selector_image_edit_adjust_exposure.xml │ │ │ ├── selector_image_edit_adjust_hue.xml │ │ │ ├── selector_image_edit_adjust_saturation.xml │ │ │ ├── selector_image_edit_adjust_sharpness.xml │ │ │ ├── selector_image_edit_adjust_vibrance.xml │ │ │ ├── selector_image_filter.xml │ │ │ ├── selector_image_fragment_skin.xml │ │ │ ├── selector_image_frame.xml │ │ │ ├── selector_image_save.xml │ │ │ ├── selector_rewardcamera.xml │ │ │ └── take_filter_favorite_btn.xml │ │ ├── layout/ │ │ │ ├── activity_camera.xml │ │ │ ├── activity_image.xml │ │ │ ├── activity_main.xml │ │ │ ├── dialog_yes_or_no.xml │ │ │ ├── filter_item_layout.xml │ │ │ ├── filter_layout.xml │ │ │ ├── fragment_image_edit_adjust.xml │ │ │ ├── fragment_image_edit_beauty.xml │ │ │ └── fragment_image_edit_filter.xml │ │ ├── raw/ │ │ │ ├── amaro.glsl │ │ │ ├── antique.glsl │ │ │ ├── beauty.glsl │ │ │ ├── blackcat.glsl │ │ │ ├── brannan.glsl │ │ │ ├── brooklyn.glsl │ │ │ ├── calm.glsl │ │ │ ├── cool.glsl │ │ │ ├── crayon.glsl │ │ │ ├── default_fragment.glsl │ │ │ ├── default_vertex.glsl │ │ │ ├── earlybird.glsl │ │ │ ├── emerald.glsl │ │ │ ├── evergreen.glsl │ │ │ ├── freud.glsl │ │ │ ├── healthy.glsl │ │ │ ├── hefe.glsl │ │ │ ├── hudson.glsl │ │ │ ├── inkwell.glsl │ │ │ ├── kevin_new.glsl │ │ │ ├── latte.glsl │ │ │ ├── lomo.glsl │ │ │ ├── n1977.glsl │ │ │ ├── nashville.glsl │ │ │ ├── nostalgia.glsl │ │ │ ├── pixar.glsl │ │ │ ├── rise.glsl │ │ │ ├── romance.glsl │ │ │ ├── sakura.glsl │ │ │ ├── sierra.glsl │ │ │ ├── sketch.glsl │ │ │ ├── skinwhiten.glsl │ │ │ ├── suger_tablets.glsl │ │ │ ├── sunrise.glsl │ │ │ ├── sunset.glsl │ │ │ ├── sutro.glsl │ │ │ ├── sweets.glsl │ │ │ ├── tender.glsl │ │ │ ├── toaster2_filter_shader.glsl │ │ │ ├── valencia.glsl │ │ │ ├── walden.glsl │ │ │ ├── warm.glsl │ │ │ ├── whitecat.glsl │ │ │ └── xproii_filter_shader.glsl │ │ ├── values/ │ │ │ ├── colors.xml │ │ │ ├── dimens.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ │ ├── values-v11/ │ │ │ └── styles.xml │ │ ├── values-v14/ │ │ │ └── styles.xml │ │ ├── values-v21/ │ │ │ └── styles.xml │ │ ├── values-w820dp/ │ │ │ └── dimens.xml │ │ └── values-zh-rCN/ │ │ └── strings.xml │ └── test/ │ └── java/ │ └── com/ │ └── zero/ │ └── magicshow/ │ └── core/ │ └── ExampleUnitTest.java ├── README.md ├── app/ │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src/ │ ├── androidTest/ │ │ └── java/ │ │ └── com/ │ │ └── zero/ │ │ └── magicshow/ │ │ └── ApplicationTest.java │ ├── main/ │ │ ├── AndroidManifest.xml │ │ ├── java/ │ │ │ └── com/ │ │ │ └── zero/ │ │ │ └── magicshowsim/ │ │ │ └── MainActivity.java │ │ └── res/ │ │ ├── anim/ │ │ │ ├── bottom_sliding_in.xml │ │ │ └── bottom_sliding_out.xml │ │ ├── color/ │ │ │ ├── selector_image_back.xml │ │ │ ├── selector_image_edit.xml │ │ │ └── selector_image_edit_yellow.xml │ │ ├── layout/ │ │ │ └── activity_main.xml │ │ ├── values/ │ │ │ ├── colors.xml │ │ │ ├── dimens.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ │ ├── values-v11/ │ │ │ └── styles.xml │ │ ├── values-v14/ │ │ │ └── styles.xml │ │ ├── values-v21/ │ │ │ └── styles.xml │ │ ├── values-w820dp/ │ │ │ └── dimens.xml │ │ └── values-zh-rCN/ │ │ └── strings.xml │ └── test/ │ └── java/ │ └── com/ │ └── zero/ │ └── magicshow/ │ └── ExampleUnitTest.java ├── build.gradle ├── gradle/ │ └── wrapper/ │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradle.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── tools/ └── versions_configuration.gradle ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ *.iml .gradle /local.properties /.idea/workspace.xml /.idea/libraries .DS_Store /build /captures MagicShow/.externalNativeBuild .idea/* ================================================ FILE: MagicShow/.gitignore ================================================ /build ================================================ FILE: MagicShow/CMakeLists.txt ================================================ # For more information about using CMake with Android Studio, read the # documentation: https://d.android.com/studio/projects/add-native-code.html # Sets the minimum version of CMake required to build the native library. cmake_minimum_required(VERSION 3.4.1) #C 的编译选项是 CMAKE_C_FLAGS # 指定编译参数,可选 # SET(CMAKE_CXX_FLAGS "-Wno-error=format-security -Wno-error=pointer-sign") # Creates and names a library, sets it as either STATIC # or SHARED, and provides the relative paths to its source code. # You can define multiple libraries, and CMake builds them for you. # Gradle automatically packages shared libraries with your APK. add_library( # Sets the name of the library. MagicJni # Sets the library as a shared library. SHARED # Provides a relative path to your source file(s). src/main/cpp/beautify/MagicBeautify.cpp src/main/cpp/bitmap/BitmapOperation.cpp src/main/cpp/bitmap/Conversion.cpp src/main/cpp/MagicJni.cpp ) target_link_libraries( MagicJni log ) # Searches for a specified prebuilt library and stores the path as a # variable. Because CMake includes system libraries in the search path by # default, you only need to specify the name of the public NDK library # you want to add. CMake verifies that the library exists before # completing its build. find_library( # Sets the name of the path variable. log-lib # Specifies the name of the NDK library that # you want CMake to locate. log ) # Specifies libraries CMake should link to your target library. You # can link multiple libraries, such as libraries you define in this # build script, prebuilt third-party libraries, or system libraries. # 设置生成的so动态库最后输出的路径 set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/../jniLibs/${ANDROID_ABI}) target_link_libraries( # Specifies the target library. MagicJni # Links the target library to the log library # included in the NDK. #加入该依赖库 jnigraphics ${log-lib} ) ================================================ FILE: MagicShow/build.gradle ================================================ apply plugin: 'com.android.library' //apply from: "$project.rootDir/tools/versions_configuration.gradle" // JitPack Maven apply plugin: 'com.github.dcendents.android-maven' // Your Group group='com.github.zerochl' android { compileSdkVersion 28 buildToolsVersion "28.0.0" defaultConfig { minSdkVersion 18 targetSdkVersion 28 versionCode 1 versionName "1.0" externalNativeBuild { cmake { cppFlags "-std=c++11" // cppFlags "-DANDROID_NDK","-D_DEBUG" } } ndk{ moduleName "MagicJni" abiFilters "armeabi-v7a","arm64-v8a","x86","x86_64" // stl = "stlport_static" } } lintOptions { abortOnError false } externalNativeBuild { cmake { path "CMakeLists.txt" } } sourceSets{ main{ jniLibs.srcDirs = ['src/main/jniLibs'] } } buildTypes { release { minifyEnabled = false proguardFiles.add(file('proguard-rules.txt')) } } } dependencies { api fileTree(include: ['*.jar'], dir: 'libs') testImplementation 'junit:junit:4.12' api files('src/main/libs/zero.jar') api "com.android.support:design:27.1.1" api "com.android.support:appcompat-v7:27.1.1" api 'io.reactivex:rxjava:latest.integration' api 'io.reactivex:rxandroid:latest.integration' } ================================================ FILE: MagicShow/proguard-rules.pro ================================================ # Add project specific ProGuard rules here. # By default, the flags in this file are appended to flags specified # in D:\android-sdk-windows/tools/proguard/proguard-android.txt # You can edit the include path and order by changing the proguardFiles # directive in build.gradle. # # For more details, see # http://developer.android.com/guide/developing/tools/proguard.html # Add any project specific keep options here: # If your project uses WebView with JS, uncomment the following # and specify the fully qualified class name to the JavaScript interface # class: #-keepclassmembers class fqcn.of.javascript.interface.for.webview { # public *; #} ================================================ FILE: MagicShow/src/androidTest/java/com/zero/magicshow/core/ApplicationTest.java ================================================ package com.zero.magicshow.core; import android.app.Application; import android.test.ApplicationTestCase; /** * Testing Fundamentals */ public class ApplicationTest extends ApplicationTestCase { public ApplicationTest() { super(Application.class); } } ================================================ FILE: MagicShow/src/main/AndroidManifest.xml ================================================ ================================================ FILE: MagicShow/src/main/cpp/MagicJni.cpp ================================================ #include #include #include #include "bitmap/BitmapOperation.h" #include "beautify/MagicBeautify.h" #define LOG_TAG "MagicJni" #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__) #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) #ifdef __cplusplus extern "C" { #endif JNIEXPORT void JNICALL Java_com_zero_magicshow_core_beautify_MagicJni_jniInitMagicBeautify(JNIEnv *env, jobject instance, jobject handler) { //LOGE("in jniInitMagicBeautify"); JniBitmap* jniBitmap = (JniBitmap*) env->GetDirectBufferAddress(handler); if (jniBitmap->_storedBitmapPixels == NULL){ LOGE("no bitmap data was stored. returning null..."); return; } MagicBeautify::getInstance()->initMagicBeautify(jniBitmap); } JNIEXPORT void JNICALL Java_com_zero_magicshow_core_beautify_MagicJni_jniStartWhiteSkin(JNIEnv *env, jobject instance, jfloat whiteLevel){ MagicBeautify::getInstance()->startWhiteSkin(whiteLevel); } JNIEXPORT void JNICALL Java_com_zero_magicshow_core_beautify_MagicJni_jniStartSkinSmooth(JNIEnv *env, jobject instance, jobject obj, jfloat DenoiseLevel){ float sigema = 10 + DenoiseLevel * DenoiseLevel * 5; MagicBeautify::getInstance()->startSkinSmooth(sigema); } JNIEXPORT void JNICALL Java_com_zero_magicshow_core_beautify_MagicJni_jniUnInitMagicBeautify(JNIEnv *env, jobject instance){ MagicBeautify::getInstance()->unInitMagicBeautify(); } JNIEXPORT jobject JNICALL Java_com_zero_magicshow_core_beautify_MagicJni_jniStoreBitmapData(JNIEnv *env, jobject instance, jobject bitmap){ //LOGE("in jniStoreBitmapData"); return BitmapOperation::jniStoreBitmapData(env, instance, bitmap); } JNIEXPORT void JNICALL Java_com_zero_magicshow_core_beautify_MagicJni_jniFreeBitmapData(JNIEnv *env, jobject instance, jobject handle){ BitmapOperation::jniFreeBitmapData(env, instance, handle); } JNIEXPORT jobject JNICALL Java_com_zero_magicshow_core_beautify_MagicJni_jniGetBitmapFromStoredBitmapData(JNIEnv *env, jobject instance, jobject handle){ return BitmapOperation::jniGetBitmapFromStoredBitmapData(env, instance, handle); } #ifdef __cplusplus } #endif ================================================ FILE: MagicShow/src/main/cpp/beautify/MagicBeautify.cpp ================================================ #include "MagicBeautify.h" #include "Math.h" #include "../bitmap/BitmapOperation.h" #include "../bitmap/Conversion.h" #include //多线程相关操作头文件,可移植众多平台 #define LOG_TAG "MagicBeautify" #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__) #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) #define div255(x) (x * 0.003921F) #define abs(x) (x>=0 ? x:(-x)) MagicBeautify* MagicBeautify::instance; MagicBeautify* MagicBeautify::getInstance() { if (instance == NULL) instance = new MagicBeautify(); return instance; } MagicBeautify::MagicBeautify() { LOGE("MagicBeautify"); mIntegralMatrix = NULL; mIntegralMatrixSqr = NULL; mImageData_yuv = NULL; mSkinMatrix = NULL; mImageData_rgb = NULL; mSmoothLevel = 0.0; mWhitenLevel = 0.0; } MagicBeautify::~MagicBeautify() { LOGE("~MagicBeautify"); if(mIntegralMatrix != NULL) delete[] mIntegralMatrix; if(mIntegralMatrixSqr != NULL) delete[] mIntegralMatrixSqr; if(mImageData_yuv != NULL) delete[] mImageData_yuv; if(mSkinMatrix != NULL) delete[] mSkinMatrix; if(mImageData_rgb != NULL) delete[] mImageData_rgb; } void MagicBeautify::initMagicBeautify(JniBitmap* jniBitmap){ LOGE("initMagicBeautify"); storedBitmapPixels = jniBitmap->_storedBitmapPixels; mImageWidth = jniBitmap->_bitmapInfo.width; mImageHeight = jniBitmap->_bitmapInfo.height; if(mImageData_rgb == NULL) mImageData_rgb = new uint32_t[mImageWidth*mImageHeight]; memcpy(mImageData_rgb, jniBitmap->_storedBitmapPixels, sizeof(uint32_t) * mImageWidth * mImageHeight); if(mImageData_yuv == NULL) mImageData_yuv = new uint8_t[mImageWidth * mImageHeight * 3]; Conversion::RGBToYCbCr((uint8_t*)mImageData_rgb, mImageData_yuv, mImageWidth * mImageHeight); initSkinMatrix(); initIntegral(); } void MagicBeautify::unInitMagicBeautify(){ if(instance != NULL) delete instance; instance = NULL; } void MagicBeautify::startSkinSmooth(float smoothlevel){ _startBeauty(smoothlevel,mWhitenLevel); } void MagicBeautify::startWhiteSkin(float whitenlevel){ _startBeauty(mSmoothLevel,whitenlevel); } void MagicBeautify::_startBeauty(float smoothlevel, float whitenlevel){ LOGE("smoothlevel=%f---whitenlevel=%f",smoothlevel,whitenlevel); if(smoothlevel >= 10.0 && smoothlevel <= 510.0 && mSmoothLevel != smoothlevel){ mSmoothLevel = smoothlevel; _startSkinSmooth(mSmoothLevel); } if(whitenlevel >= 1.0 && whitenlevel <= 5.0 && whitenlevel != mWhitenLevel){ mWhitenLevel = whitenlevel; _startWhiteSkin(mWhitenLevel); } } void MagicBeautify::_startWhiteSkin(float whitenlevel){ float a = log(whitenlevel); pthread_t tids[4]; //线程id float threadFirstParams[2] = {whitenlevel,1}; // LOGE("_FirstPart=%f---second part=%f",threadFirstParams[0],threadFirstParams[1]); pthread_create(&tids[0], NULL, _startWhiteSkinAsync, (void*)&threadFirstParams); //参数:创建的线程id,线程参数,线程运行函数的起始地址,运行函数的参数 float threadSecondParams[2] = {whitenlevel,2}; pthread_create(&tids[1], NULL, _startWhiteSkinAsync, (void*)&threadSecondParams); float threadThirdParams[2] = {whitenlevel,3}; pthread_create(&tids[2], NULL, _startWhiteSkinAsync, (void*)&threadThirdParams); float threadFourthParams[2] = {whitenlevel,4}; pthread_create(&tids[3], NULL, _startWhiteSkinAsync, (void*)&threadFourthParams); pthread_join (tids[0], NULL); pthread_join (tids[1], NULL); pthread_join (tids[2], NULL); pthread_join (tids[3], NULL); } void* MagicBeautify::_startWhiteSkinAsync( void* args ) { float *p=(float *)args; float whitenlevel= p[0]; int partSecion = (int)p[1]; int startHeight = partSecion == 1 ? 0 : partSecion == 2 ? getInstance()->mImageHeight / 4 : partSecion == 3 ? getInstance()->mImageHeight / 2 : partSecion == 4 ? getInstance()->mImageHeight / 4 * 3 : 0; int endHeight = partSecion == 1 ? getInstance()->mImageHeight / 4 : partSecion == 2 ? getInstance()->mImageHeight / 2 : partSecion == 3 ? getInstance()->mImageHeight / 4 * 3 : partSecion == 4 ? getInstance()->mImageHeight : 0; // float whitenlevel = *( (float*)args ); float a = log(whitenlevel); for(int i = startHeight; i < endHeight; i++){ for(int j = 0; j < getInstance()->mImageWidth; j++){ //calculate the point location int offset = i*getInstance()->mImageWidth+j; ARGB RGB; BitmapOperation::convertIntToArgb(getInstance()->mImageData_rgb[offset],&RGB); if(a != 0){ RGB.red = 255 * (log(div255(RGB.red) * (whitenlevel - 1) + 1) / a); RGB.green = 255 * (log(div255(RGB.green) * (whitenlevel - 1) + 1) / a); RGB.blue = 255 * (log(div255(RGB.blue) * (whitenlevel - 1) + 1) / a); } getInstance()->storedBitmapPixels[offset] = BitmapOperation::convertArgbToInt(RGB); } } pthread_exit(nullptr); } //函数返回的是函数指针,便于后面作为参数 void MagicBeautify::_startSkinSmooth(float smoothlevel){ if(mIntegralMatrix == NULL || mIntegralMatrixSqr == NULL || mSkinMatrix == NULL){ LOGE("not init correctly"); return; } Conversion::RGBToYCbCr((uint8_t*)mImageData_rgb, mImageData_yuv, mImageWidth * mImageHeight); int radius = mImageWidth > mImageHeight ? mImageWidth * 0.02 : mImageHeight * 0.02; for(int i = 1; i < mImageHeight; i++){ for(int j = 1; j < mImageWidth; j++){ int offset = i * mImageWidth + j; if(mSkinMatrix[offset] == 255){ int iMax = i + radius >= mImageHeight-1 ? mImageHeight-1 : i + radius; int jMax = j + radius >= mImageWidth-1 ? mImageWidth-1 :j + radius; int iMin = i - radius <= 1 ? 1 : i - radius; int jMin = j - radius <= 1 ? 1 : j - radius; int squar = (iMax - iMin + 1)*(jMax - jMin + 1); int i4 = iMax*mImageWidth+jMax; int i3 = (iMin-1)*mImageWidth+(jMin-1); int i2 = iMax*mImageWidth+(jMin-1); int i1 = (iMin-1)*mImageWidth+jMax; float m = (mIntegralMatrix[i4] + mIntegralMatrix[i3] - mIntegralMatrix[i2] - mIntegralMatrix[i1]) / squar; float v = (mIntegralMatrixSqr[i4] + mIntegralMatrixSqr[i3] - mIntegralMatrixSqr[i2] - mIntegralMatrixSqr[i1]) / squar - m*m; float k = v / (v + smoothlevel); mImageData_yuv[offset * 3] = ceil(m - k * m + k * mImageData_yuv[offset * 3]); } } } Conversion::YCbCrToRGB(mImageData_yuv, (uint8_t*)storedBitmapPixels, mImageWidth * mImageHeight); } void MagicBeautify::initSkinMatrix(){ LOGE("initSkinMatrix"); if(mSkinMatrix == NULL) mSkinMatrix = new uint8_t[mImageWidth * mImageHeight]; for(int i = 0; i < mImageHeight; i++){ for(int j = 0; j < mImageWidth; j++){ int offset = i*mImageWidth+j; ARGB RGB; BitmapOperation::convertIntToArgb(mImageData_rgb[offset],&RGB); if ((RGB.blue>95 && RGB.green>40 && RGB.red>20 && RGB.blue-RGB.red>15 && RGB.blue-RGB.green>15)|| (RGB.blue>200 && RGB.green>210 && RGB.red>170 && abs(RGB.blue-RGB.red)<=15 && RGB.blue>RGB.red&& RGB.green>RGB.red)) mSkinMatrix[offset] = 255; else mSkinMatrix[offset] = 0; } } } void MagicBeautify::initIntegral(){ LOGE("initIntegral"); if(mIntegralMatrix == NULL) mIntegralMatrix = new uint64_t[mImageWidth * mImageHeight]; if(mIntegralMatrixSqr == NULL) mIntegralMatrixSqr = new uint64_t[mImageWidth * mImageHeight]; uint64_t *columnSum = new uint64_t[mImageWidth]; uint64_t *columnSumSqr = new uint64_t[mImageWidth]; columnSum[0] = mImageData_yuv[0]; columnSumSqr[0] = mImageData_yuv[0] * mImageData_yuv[0]; mIntegralMatrix[0] = columnSum[0]; mIntegralMatrixSqr[0] = columnSumSqr[0]; for(int i = 1;i < mImageWidth;i++){ columnSum[i] = mImageData_yuv[3*i]; columnSumSqr[i] = mImageData_yuv[3*i] * mImageData_yuv[3*i]; mIntegralMatrix[i] = columnSum[i]; mIntegralMatrix[i] += mIntegralMatrix[i-1]; mIntegralMatrixSqr[i] = columnSumSqr[i]; mIntegralMatrixSqr[i] += mIntegralMatrixSqr[i-1]; } for (int i = 1;i < mImageHeight; i++){ int offset = i * mImageWidth; columnSum[0] += mImageData_yuv[3*offset]; columnSumSqr[0] += mImageData_yuv[3*offset] * mImageData_yuv[3*offset]; mIntegralMatrix[offset] = columnSum[0]; mIntegralMatrixSqr[offset] = columnSumSqr[0]; for(int j = 1; j < mImageWidth; j++){ columnSum[j] += mImageData_yuv[3*(offset+j)]; columnSumSqr[j] += mImageData_yuv[3*(offset+j)] * mImageData_yuv[3*(offset+j)]; mIntegralMatrix[offset+j] = mIntegralMatrix[offset+j-1] + columnSum[j]; mIntegralMatrixSqr[offset+j] = mIntegralMatrixSqr[offset+j-1] + columnSumSqr[j]; } } delete[] columnSum; delete[] columnSumSqr; LOGE("initIntegral~end"); } ================================================ FILE: MagicShow/src/main/cpp/beautify/MagicBeautify.h ================================================ #ifndef _MAGIC_BEAUTIFY_H_ #define _MAGIC_BEAUTIFY_H_ #include "../bitmap/JniBitmap.h" class MagicBeautify { public: void initMagicBeautify(JniBitmap* jniBitmap); void unInitMagicBeautify(); void startSkinSmooth(float smoothlevel); void startWhiteSkin(float whitenlevel); static MagicBeautify* getInstance(); ~MagicBeautify(); static void* _startWhiteSkinAsync(void* args); private: static MagicBeautify * instance; MagicBeautify(); uint64_t *mIntegralMatrix; uint64_t *mIntegralMatrixSqr; uint32_t *storedBitmapPixels; uint32_t *mImageData_rgb; uint8_t *mImageData_yuv; uint8_t *mSkinMatrix; int mImageWidth; int mImageHeight; float mSmoothLevel; float mWhitenLevel; void initIntegral(); void initSkinMatrix(); void _startBeauty(float smoothlevel, float whitenlevel); void _startSkinSmooth(float smoothlevel); void _startWhiteSkin(float whitenlevel); }; #endif ================================================ FILE: MagicShow/src/main/cpp/bitmap/BitmapOperation.cpp ================================================ #include "BitmapOperation.h" #include "Conversion.h" #define LOG_TAG "BitmapOperation" #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__) #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) int32_t BitmapOperation::convertArgbToInt(ARGB argb) { return (argb.alpha << 24) | (argb.red << 16) | (argb.green << 8) | argb.blue; } void BitmapOperation::convertIntToArgb(uint32_t pixel, ARGB* argb) { argb->red = ((pixel >> 16) & 0xff); argb->green = ((pixel >> 8) & 0xff); argb->blue = (pixel & 0xff); argb->alpha = (pixel >> 24); } /**store java bitmap as JNI data*/ // jobject BitmapOperation::jniStoreBitmapData( JNIEnv * env, jobject obj, jobject bitmap) { //LOGE("reading bitmap info..."); AndroidBitmapInfo bitmapInfo; uint32_t* storedBitmapPixels = NULL; int ret; if ((ret = AndroidBitmap_getInfo(env, bitmap, &bitmapInfo)) < 0) { LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret); return NULL; } //LOGE("width:%d height:%d stride:%d", bitmapInfo.width, bitmapInfo.height, bitmapInfo.stride); if (bitmapInfo.format != ANDROID_BITMAP_FORMAT_RGBA_8888) { LOGE("Bitmap format is not RGBA_8888!"); return NULL; } // //read pixels of bitmap into native memory : // void* bitmapPixels; if ((ret = AndroidBitmap_lockPixels(env, bitmap, &bitmapPixels)) < 0) { LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret); return NULL; } uint32_t* src = (uint32_t*) bitmapPixels; storedBitmapPixels = new uint32_t[bitmapInfo.height * bitmapInfo.width]; int pixelsCount = bitmapInfo.height * bitmapInfo.width; memcpy(storedBitmapPixels, src, sizeof(uint32_t) * pixelsCount); AndroidBitmap_unlockPixels(env, bitmap); JniBitmap *jniBitmap = new JniBitmap(); jniBitmap->_bitmapInfo = bitmapInfo; jniBitmap->_storedBitmapPixels = storedBitmapPixels; //LOGE("return NewDirectByteBuffer"); return env->NewDirectByteBuffer(jniBitmap, 0); } /**free bitmap*/ // void BitmapOperation::jniFreeBitmapData( JNIEnv * env, jobject obj, jobject handle) { JniBitmap* jniBitmap = (JniBitmap*) env->GetDirectBufferAddress(handle); if (jniBitmap->_storedBitmapPixels == NULL) return; delete[] jniBitmap->_storedBitmapPixels; jniBitmap->_storedBitmapPixels = NULL; delete jniBitmap; } /**restore java bitmap (from JNI data)*/ // jobject BitmapOperation::jniGetBitmapFromStoredBitmapData( JNIEnv * env, jobject obj, jobject handle) { JniBitmap* jniBitmap = (JniBitmap*) env->GetDirectBufferAddress(handle); if (jniBitmap->_storedBitmapPixels == NULL) { LOGD("no bitmap data was stored. returning null..."); return NULL; } // //creating a new bitmap to put the pixels into it - using Bitmap Bitmap.createBitmap (int width, int height, Bitmap.Config config) : // jclass bitmapCls = env->FindClass("android/graphics/Bitmap"); jmethodID createBitmapFunction = env->GetStaticMethodID(bitmapCls, "createBitmap", "(IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;"); jstring configName = env->NewStringUTF("ARGB_8888"); jclass bitmapConfigClass = env->FindClass("android/graphics/Bitmap$Config"); jmethodID valueOfBitmapConfigFunction = env->GetStaticMethodID( bitmapConfigClass, "valueOf", "(Ljava/lang/String;)Landroid/graphics/Bitmap$Config;"); jobject bitmapConfig = env->CallStaticObjectMethod(bitmapConfigClass, valueOfBitmapConfigFunction, configName); jobject newBitmap = env->CallStaticObjectMethod(bitmapCls, createBitmapFunction, jniBitmap->_bitmapInfo.width, jniBitmap->_bitmapInfo.height, bitmapConfig); // // putting the pixels into the new bitmap: // int ret; void* bitmapPixels; if ((ret = AndroidBitmap_lockPixels(env, newBitmap, &bitmapPixels)) < 0) { LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret); return NULL; } uint32_t* newBitmapPixels = (uint32_t*) bitmapPixels; int pixelsCount = jniBitmap->_bitmapInfo.height * jniBitmap->_bitmapInfo.width; memcpy(newBitmapPixels, jniBitmap->_storedBitmapPixels, sizeof(uint32_t) * pixelsCount); AndroidBitmap_unlockPixels(env, newBitmap); //LOGD("returning the new bitmap"); return newBitmap; } ================================================ FILE: MagicShow/src/main/cpp/bitmap/BitmapOperation.h ================================================ #ifndef _BITMAP_OPERATION_H_ #define _BITMAP_OPERATION_H_ #include #include #include #include #include #include #include "JniBitmap.h" class BitmapOperation { public: static int32_t convertArgbToInt(ARGB argb); static void convertIntToArgb(uint32_t pixel, ARGB* argb); static jobject jniStoreBitmapData( JNIEnv * env, jobject obj, jobject bitmap); static void jniFreeBitmapData( JNIEnv * env, jobject obj, jobject handle); static jobject jniGetBitmapFromStoredBitmapData( JNIEnv * env, jobject obj, jobject handle); }; #endif ================================================ FILE: MagicShow/src/main/cpp/bitmap/Conversion.cpp ================================================ #include "Conversion.h" void Conversion::YCbCrToRGB(uint8_t* From, uint8_t* To, int length) { if (length < 1) return; int Red, Green, Blue; int Y, Cb, Cr; int i,offset; for(i = 0; i < length; i++) { offset = (i << 1) + i; Y = From[offset]; Cb = From[offset+1] - 128; Cr = From[offset+2] - 128; Red = Y + ((RGBRCrI * Cr + HalfShiftValue) >> Shift); Green = Y + ((RGBGCbI * Cb + RGBGCrI * Cr + HalfShiftValue) >> Shift); Blue = Y + ((RGBBCbI * Cb + HalfShiftValue) >> Shift); if (Red > 255) Red = 255; else if (Red < 0) Red = 0; if (Green > 255) Green = 255; else if (Green < 0) Green = 0; if (Blue > 255) Blue = 255; else if (Blue < 0) Blue = 0; offset = i << 2; To[offset] = (uint8_t)Blue; To[offset+1] = (uint8_t)Green; To[offset+2] = (uint8_t)Red; To[offset+3] = 0xff; } } void Conversion::RGBToYCbCr(uint8_t* From, uint8_t* To, int length) { if (length < 1) return; int Red, Green, Blue; int i,offset; for(i = 0; i < length; i++) { offset = i << 2; Blue = From[offset]; Green = From[offset+1]; Red = From[offset+2]; offset = (i << 1) + i; To[offset] = (uint8_t)((YCbCrYRI * Red + YCbCrYGI * Green + YCbCrYBI * Blue + HalfShiftValue) >> Shift); To[offset+1] = (uint8_t)(128 + ((YCbCrCbRI * Red + YCbCrCbGI * Green + YCbCrCbBI * Blue + HalfShiftValue) >> Shift)); To[offset+2] = (uint8_t)(128 + ((YCbCrCrRI * Red + YCbCrCrGI * Green + YCbCrCrBI * Blue + HalfShiftValue) >> Shift)); } } ================================================ FILE: MagicShow/src/main/cpp/bitmap/Conversion.h ================================================ #ifndef _CONVERSION_H_ #define _CONVERSION_H_ #include #include const float YCbCrYRF = 0.299F; const float YCbCrYGF = 0.587F; const float YCbCrYBF = 0.114F; const float YCbCrCbRF = -0.168736F; const float YCbCrCbGF = -0.331264F; const float YCbCrCbBF = 0.500000F; const float YCbCrCrRF = 0.500000F; const float YCbCrCrGF = -0.418688F; const float YCbCrCrBF = -0.081312F; const float RGBRYF = 1.00000F; const float RGBRCbF = 0.0000F; const float RGBRCrF = 1.40200F; const float RGBGYF = 1.00000F; const float RGBGCbF = -0.34414F; const float RGBGCrF = -0.71414F; const float RGBBYF = 1.00000F; const float RGBBCbF = 1.77200F; const float RGBBCrF = 0.00000F; const int Shift = 20; const int HalfShiftValue = 1 << (Shift - 1); const int YCbCrYRI = (int)(YCbCrYRF * (1 << Shift) + 0.5); const int YCbCrYGI = (int)(YCbCrYGF * (1 << Shift) + 0.5); const int YCbCrYBI = (int)(YCbCrYBF * (1 << Shift) + 0.5); const int YCbCrCbRI = (int)(YCbCrCbRF * (1 << Shift) + 0.5); const int YCbCrCbGI = (int)(YCbCrCbGF * (1 << Shift) + 0.5); const int YCbCrCbBI = (int)(YCbCrCbBF * (1 << Shift) + 0.5); const int YCbCrCrRI = (int)(YCbCrCrRF * (1 << Shift) + 0.5); const int YCbCrCrGI = (int)(YCbCrCrGF * (1 << Shift) + 0.5); const int YCbCrCrBI = (int)(YCbCrCrBF * (1 << Shift) + 0.5); const int RGBRYI = (int)(RGBRYF * (1 << Shift) + 0.5); const int RGBRCbI = (int)(RGBRCbF * (1 << Shift) + 0.5); const int RGBRCrI = (int)(RGBRCrF * (1 << Shift) + 0.5); const int RGBGYI = (int)(RGBGYF * (1 << Shift) + 0.5); const int RGBGCbI = (int)(RGBGCbF * (1 << Shift) + 0.5); const int RGBGCrI = (int)(RGBGCrF * (1 << Shift) + 0.5); const int RGBBYI = (int)(RGBBYF * (1 << Shift) + 0.5); const int RGBBCbI = (int)(RGBBCbF * (1 << Shift) + 0.5); const int RGBBCrI = (int)(RGBBCrF * (1 << Shift) + 0.5); class Conversion { public: static void YCbCrToRGB(uint8_t* From, uint8_t* To, int Length); static void RGBToYCbCr(uint8_t* From, uint8_t* To, int Length); private: }; #endif ================================================ FILE: MagicShow/src/main/cpp/bitmap/JniBitmap.h ================================================ #ifndef _JNI_BITMAP_H_ #define _JNI_BITMAP_H_ #include typedef struct { uint8_t alpha, red, green, blue; } ARGB; class JniBitmap { public: uint32_t* _storedBitmapPixels; AndroidBitmapInfo _bitmapInfo; JniBitmap() { _storedBitmapPixels = NULL; } }; #endif ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/MagicShowManager.java ================================================ package com.zero.magicshow; import android.Manifest; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.support.v4.app.ActivityCompat; import android.support.v4.content.PermissionChecker; import android.text.TextUtils; import android.util.Log; import com.zero.magicshow.activity.AlbumActivity; import com.zero.magicshow.activity.CameraActivity; import com.zero.magicshow.common.entity.MagicShowResultEntity; import com.zero.magicshow.common.iface.CameraShootCallBack; import com.zero.magicshow.common.iface.ImageEditCallBack; import com.zero.magicshow.common.utils.Constants; import com.zero.magicshow.common.utils.RxBus; import com.zero.magicshow.common.config.PathConfig; import com.zero.zerolib.util.FileUtil; import rx.functions.Action1; /** * Created by hongli on 2017/8/31. */ public class MagicShowManager { private static final String TAG = "MagicShowManager"; private static final MagicShowManager magicShowManager = new MagicShowManager(); private MagicShowManager(){} public static MagicShowManager getInstance(){ return magicShowManager; } public void setCachePath(String cachePath){ PathConfig.setTempCache(cachePath); } /** * 执行照片编辑 * @param context * @param imagePath * @param imageEditCallBack */ public void openEdit(Context context,String imagePath, final ImageEditCallBack imageEditCallBack){ if(null == context || TextUtils.isEmpty(imagePath) || !FileUtil.isExist(imagePath)){ Log.e(TAG,"in open edit data error."); return; } RxBus.getInstance().unregisterMain(Constants.RX_JAVA_TYPE_IMAGE_EDIT); RxBus.getInstance().registerMain(Constants.RX_JAVA_TYPE_IMAGE_EDIT, new Action1() { @Override public void call(MagicShowResultEntity magicShowResultEntity) { imageEditCallBack.onCompentFinished(magicShowResultEntity); RxBus.getInstance().unregisterMain(Constants.RX_JAVA_TYPE_IMAGE_EDIT); } }); Intent intent = new Intent(context, AlbumActivity.class); intent.putExtra(Constants.TRANSMIT_IMAGE_URL,imagePath); context.startActivity(intent); } /** * 执行拍照 * @param context * @param cameraShootCallBack */ public void openCamera(Activity context,final CameraShootCallBack cameraShootCallBack){ if(null == context){ Log.e(TAG,"in open edit data error."); return; } if (PermissionChecker.checkSelfPermission(context, Manifest.permission.CAMERA) == PackageManager.PERMISSION_DENIED) { ActivityCompat.requestPermissions(context, new String[] { Manifest.permission.CAMERA },1); return; } RxBus.getInstance().unregisterMain(Constants.RX_JAVA_TYPE_CAMERA_SHOOT); RxBus.getInstance().registerMain(Constants.RX_JAVA_TYPE_CAMERA_SHOOT, new Action1() { @Override public void call(MagicShowResultEntity magicShowResultEntity) { cameraShootCallBack.onCompentFinished(magicShowResultEntity); RxBus.getInstance().unregisterMain(Constants.RX_JAVA_TYPE_CAMERA_SHOOT); } }); Intent intent = new Intent(context, CameraActivity.class); context.startActivity(intent); } /** * 打开拍照,然后直接对拍照图片进行编辑 * @param context * @param imageEditCallBack */ public void openCameraAndEdit(final Activity context, final ImageEditCallBack imageEditCallBack){ openCamera(context, new CameraShootCallBack() { @Override public void onCompentFinished(MagicShowResultEntity magicShowResultEntity) { openEdit(context,magicShowResultEntity.getFilePath(),imageEditCallBack); } }); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/activity/AlbumActivity.java ================================================ package com.zero.magicshow.activity; import android.content.Context; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentTransaction; import android.util.Log; import android.view.View; import android.view.animation.Animation; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import com.zero.magicshow.R; import com.zero.magicshow.common.base.BaseActivity; import com.zero.magicshow.common.base.MagicBaseView; import com.zero.magicshow.common.entity.MagicShowResultEntity; import com.zero.magicshow.common.utils.BaseUtil; import com.zero.magicshow.common.utils.Constants; import com.zero.magicshow.common.utils.RxBus; import com.zero.magicshow.common.utils.SavePictureTask; import com.zero.magicshow.core.MagicEngine; import com.zero.magicshow.core.widget.MagicImageView; import com.zero.magicshow.view.edit.ImageEditFragment; import com.zero.magicshow.view.edit.ImageEditManager; import com.zero.magicshow.view.edit.iface.ImageEditNavListener; import com.zero.zerolib.util.AnimationUtils; import com.zero.zerolib.util.StringUtil; import java.util.HashMap; import java.util.Iterator; import java.util.Map; /** * Created by zero on 2016/3/18. */ public class AlbumActivity extends BaseActivity{ private ImageView btnBack, btnNext,btnModifyClose,btnModifySave; private TextView tvTitle; private MagicImageView magicImageView; private LinearLayout blockNavigation; private View blockModifyController,blockTopBar; private HashMap fragmentHashMap = new HashMap<>(); public static final String IMAGE_EDIT_TYPE_BEAUTY = "beauty";//美颜 public static final String IMAGE_EDIT_TYPE_ADJUST = "adjust";//编辑 public static final String IMAGE_EDIT_TYPE_FILTER = "filter";//滤镜 private Context context; private MagicEngine magicEngine; private String imageUrl; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); context = this; setContentView(R.layout.activity_image); init(); } private void init(){ initView(); initData(); initListener(); } private void initView(){ btnBack = (ImageView)findViewById(R.id.image_edit_back); btnNext = (ImageView)findViewById(R.id.image_edit_save); tvTitle = (TextView)findViewById(R.id.image_edit_title); magicImageView = (MagicImageView)findViewById(R.id.image_edit_magicimageview); blockNavigation = (LinearLayout)findViewById(R.id.image_edit_navigation); blockModifyController = findViewById(R.id.image_edit_modify_controller_block); blockTopBar = findViewById(R.id.image_edit_topbar); btnModifyClose = (ImageView)findViewById(R.id.image_edit_modify_controller_close); btnModifySave = (ImageView)findViewById(R.id.image_edit_modify_controller_save); } private void initData(){ imageUrl = getIntent().getStringExtra(Constants.TRANSMIT_IMAGE_URL); // MagicEngine.Builder builder = new MagicEngine.Builder(); magicEngine = new MagicEngine.Builder().build(magicImageView); initFragments(); magicImageView.setGLScaleType(MagicBaseView.ScaleType.CENTER_INSIDE); if(StringUtil.isEmpty(imageUrl)){ magicImageView.setImageBitmap(BaseUtil.getImageFromAssetsFile(context,"dark.jpg")); }else{ magicImageView.setImageBitmap(BaseUtil.getBitmapBySimpleSize(imageUrl,BaseUtil.dipToPix(context,640),BaseUtil.dipToPix(context,640))); } } private void initListener(){ btnBack.setOnClickListener(onClickListener); btnNext.setOnClickListener(onClickListener); btnModifyClose.setOnClickListener(onClickListener); btnModifySave.setOnClickListener(onClickListener); } private void initFragments(){ ImageEditManager.initAdjustView(context,fragmentHashMap,blockNavigation,onHideListener,imageEditNavListener); ImageEditManager.initBeautyView(context,fragmentHashMap,blockNavigation,onHideListener,imageEditNavListener); ImageEditManager.initFilterView(context,fragmentHashMap,blockNavigation,onHideListener,imageEditNavListener); } @Override protected void doFinishAction() { Fragment showFragment = getShowFragment(); if(null != showFragment){ ((ImageEditFragment)showFragment).doFinishAction(); return; } super.doFinishAction(); } private Fragment getShowFragment(){ Iterator> iterator = fragmentHashMap.entrySet().iterator(); while (iterator.hasNext()){ Map.Entry item = iterator.next(); if(item.getValue().isVisible()){ return item.getValue(); } } return null; } private void doClickModifyCloseAction(){ Fragment showFragment = getShowFragment(); if(null != showFragment){ ((ImageEditFragment)showFragment).doFinishAction(); } } private void doClickModifySaveAction(){ Fragment showFragment = getShowFragment(); if(null != showFragment){ ((ImageEditFragment)showFragment).doSaveConfigeAction(); } } private void doBackAction(){ doFinishAction(); } private void doNextAction(){ MagicEngine.getInstance().savePicture(BaseUtil.getRandomTempImageFile(), new SavePictureTask.OnPictureSaveListener() { @Override public void onSaved(MagicShowResultEntity resultEntity) { RxBus.getInstance().post(resultEntity,Constants.RX_JAVA_TYPE_IMAGE_EDIT); doFinishAction(); } }); } private View.OnClickListener onClickListener = new View.OnClickListener() { @Override public void onClick(View v) { if(v == btnModifyClose){ doClickModifyCloseAction(); }else if(v == btnModifySave){ doClickModifySaveAction(); }else if(v == btnBack){ doBackAction(); }else if(v == btnNext){ doNextAction(); } } }; private ImageEditFragment.onHideListener onHideListener = new ImageEditFragment.onHideListener() { @Override public void onAfterHide() { Log.e("HongLi","in onAfterHide"); Fragment showFragment = getShowFragment(); if(null != showFragment){ hiddenFragment(showFragment); } } }; private ImageEditNavListener imageEditNavListener = new ImageEditNavListener() { @Override public void onClick(View view, String type) { showFragment(fragmentHashMap.get(type)); } }; private void showFragment(Fragment fragment){ FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); fragmentTransaction.setCustomAnimations(R.anim.bottom_sliding_in,R.anim.bottom_sliding_out); if(!fragment.isAdded()){ fragmentTransaction.add(R.id.image_edit_fragment_container, fragment).show(fragment).commit(); }else{ fragmentTransaction.show(fragment).commit(); } blockModifyController.setVisibility(View.VISIBLE); AnimationUtils.doSlidingInFromBottom(blockModifyController,blockModifyController.getHeight(),false); com.zero.magicshow.common.utils.BaseUtil.fadeOutView(blockTopBar); } private void hiddenFragment(Fragment fragment){ FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); fragmentTransaction.setCustomAnimations(R.anim.bottom_sliding_in,R.anim.bottom_sliding_out); fragmentTransaction.hide(fragment).commit(); AnimationUtils.doSlidingOutFromBottom(blockModifyController, blockModifyController.getHeight(), false, new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) {} @Override public void onAnimationEnd(Animation animation) { blockModifyController.setVisibility(View.GONE); } @Override public void onAnimationRepeat(Animation animation) {} }); com.zero.magicshow.common.utils.BaseUtil.fadeInView(blockTopBar); } @Override protected void onDestroy() { super.onDestroy(); RxBus.getInstance().unregisterMain(Constants.RX_JAVA_TYPE_IMAGE_EDIT); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/activity/CameraActivity.java ================================================ package com.zero.magicshow.activity; import android.Manifest; import android.animation.ObjectAnimator; import android.app.AlertDialog; import android.content.DialogInterface; import android.content.pm.PackageManager; import android.os.Bundle; import android.support.v4.app.ActivityCompat; import android.support.v4.content.PermissionChecker; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.View; import android.view.animation.Animation; import android.widget.ImageView; import android.widget.LinearLayout; import com.zero.magicshow.R; import com.zero.magicshow.adapter.FilterAdapter; import com.zero.magicshow.common.base.BaseActivity; import com.zero.magicshow.common.entity.MagicShowResultEntity; import com.zero.magicshow.common.utils.BaseUtil; import com.zero.magicshow.common.utils.Constants; import com.zero.magicshow.common.utils.GravityUtil; import com.zero.magicshow.common.utils.MagicParams; import com.zero.magicshow.common.utils.RxBus; import com.zero.magicshow.common.utils.SavePictureTask; import com.zero.magicshow.core.MagicEngine; import com.zero.magicshow.core.camera.CameraEngine; import com.zero.magicshow.core.filter.utils.MagicFilterType; import com.zero.magicshow.core.widget.MagicCameraView; import com.zero.magicshow.viewmanager.CameraManager; import com.zero.zerolib.util.AnimationUtils; /** * Created by zero on 2016/3/17. */ public class CameraActivity extends BaseActivity{ private LinearLayout filterLayout; private RecyclerView filterListView; private MagicCameraView magicCameraView; private FilterAdapter filterAdapter; private MagicEngine magicEngine; private boolean isRecording = false; private final int MODE_PIC = 1; private final int MODE_VIDEO = 2; private int mode = MODE_PIC; private ImageView btnShutter,btnMode,btnFilter,btnFilterClose,btnCameraSwitch;//,btnBeauty; private ObjectAnimator animator; private final static int PERMISSION_REQUEST_WRITE = 1001; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_camera); init(); } private void init(){ initView(); initData(); initListener(); } private void initView(){ filterLayout = (LinearLayout)findViewById(R.id.layout_filter); filterListView = (RecyclerView) findViewById(R.id.filter_listView); btnShutter = (ImageView)findViewById(R.id.camera_shutter); btnMode = (ImageView)findViewById(R.id.camera_mode); btnFilter = (ImageView)findViewById(R.id.camera_filter); btnFilterClose = (ImageView)findViewById(R.id.camera_closefilter); btnCameraSwitch = (ImageView)findViewById(R.id.camera_switch); // btnBeauty = (ImageView)findViewById(R.id.camera_beauty); magicCameraView = (MagicCameraView)findViewById(R.id.camera_camera_view); } private void initData(){ magicEngine = new MagicEngine.Builder().build(magicCameraView); initFilterView(); animator = CameraManager.getShutterAnim(btnShutter); } private void initListener(){ btnFilter.setOnClickListener(btn_listener); btnFilterClose.setOnClickListener(btn_listener); btnShutter.setOnClickListener(btn_listener); btnCameraSwitch.setOnClickListener(btn_listener); btnMode.setOnClickListener(btn_listener); // btnBeauty.setOnClickListener(btn_listener); } private void initFilterView(){ LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this); linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); filterListView.setLayoutManager(linearLayoutManager); filterAdapter = new FilterAdapter(this, Constants.FILTER_TYPES); filterListView.setAdapter(filterAdapter); filterAdapter.setOnFilterChangeListener(onFilterChangeListener); } private FilterAdapter.onFilterChangeListener onFilterChangeListener = new FilterAdapter.onFilterChangeListener(){ @Override public void onFilterChanged(MagicFilterType filterType) { magicEngine.setFilter(filterType); } }; // @Override // public void onRequestPermissionsResult(int requestCode, String[] permissions,int[] grantResults) { // if (grantResults.length != 1 || grantResults[0] == PackageManager.PERMISSION_GRANTED) { // if(mode == MODE_PIC){ // takePhoto(); // }else{ // takeVideo(); // } // } else { // super.onRequestPermissionsResult(requestCode, permissions, grantResults); // } // } private void doClickShutterAction(View view){ if (PermissionChecker.checkSelfPermission(CameraActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) { ActivityCompat.requestPermissions(CameraActivity.this, new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE }, PERMISSION_REQUEST_WRITE); } else { if(mode == MODE_PIC){ takePhoto(); }else{ takeVideo(); } } } private void doClickBeautyAction(){ new AlertDialog.Builder(CameraActivity.this) .setSingleChoiceItems(new String[] { "关闭", "1", "2", "3", "4", "5"}, MagicParams.beautyLevel, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { magicEngine.setBeautyLevel(which); dialog.dismiss(); } }) .setNegativeButton("取消", null) .show(); } private View.OnClickListener btn_listener = new View.OnClickListener() { @Override public void onClick(View v) { if(v == btnMode){ switchMode(); }else if(v == btnShutter){ doClickShutterAction(v); }else if(v == btnFilter){ showFilters(); }else if(v == btnCameraSwitch){ magicEngine.switchCamera(); } // else if(v == btnBeauty){ // doClickBeautyAction(); // } else if(v == btnFilterClose){ hideFilters(); } } }; private void switchMode(){ if(mode == MODE_PIC){ mode = MODE_VIDEO; btnMode.setImageResource(R.drawable.icon_camera); }else{ mode = MODE_PIC; btnMode.setImageResource(R.drawable.icon_video); } } private void takePhoto(){ // final long startTime = System.nanoTime() / 1000000; magicEngine.savePicture(BaseUtil.getRandomTempImageFile(), new SavePictureTask.OnPictureSaveListener() { @Override public void onSaved(MagicShowResultEntity resultEntity) { // Log.e("HongLi","保存成功:" + (System.nanoTime() / 1000000 - startTime)); RxBus.getInstance().post(resultEntity,Constants.RX_JAVA_TYPE_CAMERA_SHOOT); doFinishAction(); } }); } private void takeVideo(){ if(isRecording) { animator.end(); magicEngine.stopRecord(); }else { animator.start(); magicEngine.startRecord(); } isRecording = !isRecording; } @Override protected void doFinishAction() { if(filterLayout.getVisibility() == View.VISIBLE){ hideFilters(); return; } super.doFinishAction(); } private void showFilters(){ btnShutter.setClickable(false); filterLayout.setVisibility(View.VISIBLE); AnimationUtils.doSlidingInFromBottom(filterLayout, filterLayout.getHeight(),false); } private void hideFilters(){ AnimationUtils.doSlidingOutFromBottom(filterLayout, filterLayout.getHeight(), false, new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) {} @Override public void onAnimationEnd(Animation animation) { filterLayout.setVisibility(View.INVISIBLE); btnShutter.setClickable(true); } @Override public void onAnimationRepeat(Animation animation) {} }); } @Override protected void onDestroy() { super.onDestroy(); CameraEngine.releaseCamera(true); GravityUtil.getInstance().stop(); RxBus.getInstance().unregisterMain(Constants.RX_JAVA_TYPE_CAMERA_SHOOT); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/adapter/FilterAdapter.java ================================================ package com.zero.magicshow.adapter; import android.content.Context; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.TextView; import com.zero.magicshow.R; import com.zero.magicshow.common.utils.FilterTypeHelper; import com.zero.magicshow.core.filter.utils.MagicFilterType; /** * Created by why8222 on 2016/3/17. */ public class FilterAdapter extends RecyclerView.Adapter{ private MagicFilterType[] filters; private Context context; private int selected = 0; public FilterAdapter(Context context, MagicFilterType[] filters) { this.filters = filters; this.context = context; } @Override public FilterHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(context).inflate(R.layout.filter_item_layout, parent, false); FilterHolder viewHolder = new FilterHolder(view); viewHolder.thumbImage = (ImageView) view .findViewById(R.id.filter_thumb_image); viewHolder.filterName = (TextView) view .findViewById(R.id.filter_thumb_name); viewHolder.filterRoot = (FrameLayout)view .findViewById(R.id.filter_root); viewHolder.thumbSelected = (FrameLayout) view .findViewById(R.id.filter_thumb_selected); viewHolder.thumbSelected_bg = view. findViewById(R.id.filter_thumb_selected_bg); return viewHolder; } @Override public void onBindViewHolder(FilterHolder holder,final int position) { holder.thumbImage.setImageResource(FilterTypeHelper.FilterType2Thumb(filters[position])); holder.filterName.setText(FilterTypeHelper.FilterType2Name(filters[position])); holder.filterName.setBackgroundColor(context.getResources().getColor( FilterTypeHelper.FilterType2Color(filters[position]))); if(position == selected){ holder.thumbSelected.setVisibility(View.VISIBLE); holder.thumbSelected_bg.setBackgroundColor(context.getResources().getColor( FilterTypeHelper.FilterType2Color(filters[position]))); holder.thumbSelected_bg.setAlpha(0.7f); }else { holder.thumbSelected.setVisibility(View.GONE); } holder.filterRoot.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(selected == position) return; int lastSelected = selected; selected = position; notifyItemChanged(lastSelected); notifyItemChanged(position); onFilterChangeListener.onFilterChanged(filters[position]); } }); } public void refreshList(){ selected = 0; notifyDataSetChanged(); } @Override public int getItemCount() { return filters == null ? 0 : filters.length; } class FilterHolder extends RecyclerView.ViewHolder { ImageView thumbImage; TextView filterName; FrameLayout thumbSelected; FrameLayout filterRoot; View thumbSelected_bg; public FilterHolder(View itemView) { super(itemView); } } public interface onFilterChangeListener{ void onFilterChanged(MagicFilterType filterType); } private onFilterChangeListener onFilterChangeListener; public void setOnFilterChangeListener(onFilterChangeListener onFilterChangeListener){ this.onFilterChangeListener = onFilterChangeListener; } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/common/base/BaseActivity.java ================================================ package com.zero.magicshow.common.base; import android.support.v4.app.FragmentActivity; import android.view.KeyEvent; /** * Created by hongli on 2017/8/22. */ public abstract class BaseActivity extends FragmentActivity{ protected void doFinishAction(){ finish(); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) { doFinishAction(); return true; } return super.onKeyDown(keyCode, event); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/common/base/MagicBaseView.java ================================================ package com.zero.magicshow.common.base; import android.content.Context; import android.graphics.Bitmap; import android.opengl.GLES20; import android.opengl.GLSurfaceView; import android.util.AttributeSet; import android.util.Log; import com.zero.magicshow.common.iface.MagicListener; import com.zero.magicshow.common.utils.OpenGlUtils; import com.zero.magicshow.common.utils.Rotation; import com.zero.magicshow.common.utils.SavePictureTask; import com.zero.magicshow.common.utils.TextureRotationUtil; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.core.filter.utils.MagicFilterFactory; import com.zero.magicshow.core.filter.utils.MagicFilterType; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import java.nio.IntBuffer; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; /** * Created by why8222 on 2016/2/25. */ public abstract class MagicBaseView extends GLSurfaceView implements GLSurfaceView.Renderer{ /** * 所选择的滤镜,类型为MagicBaseGroupFilter * 1.mCameraInputFilter将SurfaceTexture中YUV数据绘制到FrameBuffer * 2.filter将FrameBuffer中的纹理绘制到屏幕中 */ protected GPUImageFilter filter; /** * SurfaceTexure纹理id */ protected int textureId = OpenGlUtils.NO_TEXTURE; /** * 顶点坐标 */ protected final FloatBuffer gLCubeBuffer; /** * 纹理坐标 */ protected final FloatBuffer gLTextureBuffer; /** * GLSurfaceView的宽高 */ protected int surfaceWidth, surfaceHeight; /** * 图像宽高 */ protected int imageWidth, imageHeight; protected ScaleType scaleType = ScaleType.FIT_XY; protected MagicListener magicListener; public MagicBaseView(Context context) { this(context, null); } public MagicBaseView(Context context, AttributeSet attrs) { super(context, attrs); gLCubeBuffer = ByteBuffer.allocateDirect(TextureRotationUtil.CUBE.length * 4) .order(ByteOrder.nativeOrder()) .asFloatBuffer(); gLCubeBuffer.put(TextureRotationUtil.CUBE).position(0); gLTextureBuffer = ByteBuffer.allocateDirect(TextureRotationUtil.TEXTURE_NO_ROTATION.length * 4) .order(ByteOrder.nativeOrder()) .asFloatBuffer(); gLTextureBuffer.put(TextureRotationUtil.TEXTURE_NO_ROTATION).position(0); setEGLContextClientVersion(2); setRenderer(this); setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); } @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { GLES20.glDisable(GL10.GL_DITHER); GLES20.glClearColor(0,0, 0, 0); GLES20.glEnable(GL10.GL_CULL_FACE); GLES20.glEnable(GL10.GL_DEPTH_TEST); } @Override public void onSurfaceChanged(GL10 gl, int width, int height) { GLES20.glViewport(0,0,width, height); surfaceWidth = width; surfaceHeight = height; Log.e("HongLi","surfaceWidth:" + surfaceWidth + ";surfaceHeight:" + surfaceHeight); onFilterChanged(); } @Override public void onDrawFrame(GL10 gl) { GLES20.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); } protected void setMagicListener(MagicListener magicListener){ this.magicListener = magicListener; } protected void onFilterChanged(){ if(filter != null) { filter.onDisplaySizeChanged(surfaceWidth, surfaceHeight); filter.onInputSizeChanged(imageWidth, imageHeight); } } public void setGLScaleType(ScaleType scaleType){ this.scaleType = scaleType; } public void setFilter(final MagicFilterType type){ queueEvent(new Runnable() { @Override public void run() { if (filter != null) filter.destroy(); filter = null; filter = MagicFilterFactory.initFilters(type); if (filter != null) filter.init(); onFilterChanged(); } }); requestRender(); } public MagicFilterType getFilterType(){ if(null == filter){ return MagicFilterType.NONE; } return MagicFilterFactory.getCurrentFilterType(); } public void reftreshDisplay(){ deleteTextures(); requestRender(); } protected void deleteTextures() { if(textureId != OpenGlUtils.NO_TEXTURE){ queueEvent(new Runnable() { @Override public void run() { GLES20.glDeleteTextures(1, new int[]{ textureId }, 0); textureId = OpenGlUtils.NO_TEXTURE; } }); } } public abstract void savePicture(SavePictureTask savePictureTask); protected void adjustSize(int rotation, boolean flipHorizontal, boolean flipVertical){ float[] textureCords = TextureRotationUtil.getRotation(Rotation.fromInt(rotation), flipHorizontal, flipVertical); float[] cube = TextureRotationUtil.CUBE; float ratio1 = (float)surfaceWidth / imageWidth; float ratio2 = (float)surfaceHeight / imageHeight; float ratioMax = Math.max(ratio1, ratio2); int imageWidthNew = Math.round(imageWidth * ratioMax); int imageHeightNew = Math.round(imageHeight * ratioMax); float ratioWidth = imageWidthNew / (float)surfaceWidth; float ratioHeight = imageHeightNew / (float)surfaceHeight; if(scaleType == ScaleType.CENTER_INSIDE){ cube = new float[]{ TextureRotationUtil.CUBE[0] / ratioHeight, TextureRotationUtil.CUBE[1] / ratioWidth, TextureRotationUtil.CUBE[2] / ratioHeight, TextureRotationUtil.CUBE[3] / ratioWidth, TextureRotationUtil.CUBE[4] / ratioHeight, TextureRotationUtil.CUBE[5] / ratioWidth, TextureRotationUtil.CUBE[6] / ratioHeight, TextureRotationUtil.CUBE[7] / ratioWidth, }; }else if(scaleType == ScaleType.FIT_XY){ }else if(scaleType == ScaleType.CENTER_CROP){ float distHorizontal = (1 - 1 / ratioWidth) / 2; float distVertical = (1 - 1 / ratioHeight) / 2; textureCords = new float[]{ addDistance(textureCords[0], distVertical), addDistance(textureCords[1], distHorizontal), addDistance(textureCords[2], distVertical), addDistance(textureCords[3], distHorizontal), addDistance(textureCords[4], distVertical), addDistance(textureCords[5], distHorizontal), addDistance(textureCords[6], distVertical), addDistance(textureCords[7], distHorizontal), }; } gLCubeBuffer.clear(); gLCubeBuffer.put(cube).position(0); gLTextureBuffer.clear(); gLTextureBuffer.put(textureCords).position(0); } protected void getBitmapFromGL(final Bitmap bitmap, final boolean newTexture){ queueEvent(new Runnable() { @Override public void run() { int width = bitmap.getWidth(); int height = bitmap.getHeight(); int[] mFrameBuffers = new int[1]; int[] mFrameBufferTextures = new int[1]; GLES20.glGenFramebuffers(1, mFrameBuffers, 0); GLES20.glGenTextures(1, mFrameBufferTextures, 0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mFrameBufferTextures[0]); GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, width, height, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, mFrameBuffers[0]); GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, mFrameBufferTextures[0], 0); GLES20.glViewport(0, 0, width, height); filter.onInputSizeChanged(width, height); // filter.onOutputSizeChanged(width,height); filter.onDisplaySizeChanged(imageWidth, imageHeight); // filter.onDisplaySizeChanged(surfaceWidth, surfaceHeight); int textureId; if(newTexture){ textureId = OpenGlUtils.loadTexture(bitmap, OpenGlUtils.NO_TEXTURE, true); }else{ textureId = MagicBaseView.this.textureId; } GLES20.glViewport(0, 0, width, height); long startTime = System.nanoTime() / 1000000; filter.onDrawFrame(textureId); // filter.onDrawFrameNormal(textureId,width, height); IntBuffer ib = IntBuffer.allocate(width * height); GLES20.glReadPixels(0, 0, width, height, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, ib); Bitmap mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); mBitmap.copyPixelsFromBuffer(IntBuffer.wrap(ib.array())); Log.e("HongLi","消耗的时间:" + (System.nanoTime() / 1000000 - startTime)); // BaseUtil.saveBitmap(mBitmap,"/sdcard/DCIM/test2.jpg"); if(newTexture) GLES20.glDeleteTextures(1, new int[]{textureId}, 0); GLES20.glDeleteFramebuffers(1, mFrameBuffers, 0); GLES20.glDeleteTextures(1, mFrameBufferTextures, 0); GLES20.glViewport(0, 0, surfaceWidth, surfaceHeight); filter.destroy(); filter.init(); filter.onInputSizeChanged(imageWidth, imageHeight); onGetBitmapFromGL(mBitmap); } }); } protected void onGetBitmapFromGL(Bitmap bitmap){ } private float addDistance(float coordinate, float distance) { return coordinate == 0.0f ? distance : 1 - distance; } public enum ScaleType{ CENTER_INSIDE, CENTER_CROP, FIT_XY; } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/common/config/CameraConfig.java ================================================ package com.zero.magicshow.common.config; /** * Created by hongli on 2017/9/1. */ public class CameraConfig { public static int orientation; public static int pictureWidth = 1280; public static int pictureHeight = 720; public static void setCameraConfig(int pictureWidth,int pictureHeight){ CameraConfig.pictureWidth = pictureWidth; CameraConfig.pictureHeight = pictureHeight; } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/common/config/PathConfig.java ================================================ package com.zero.magicshow.common.config; import android.os.Environment; /** * Created by hongli on 2017/8/30. */ public class PathConfig { private static String SD_DIRECTORY = "/Android/data/com.zero.lib/cache"; private static String tempCache = Environment.getExternalStorageDirectory().getAbsolutePath() + SD_DIRECTORY; public static void setTempCache(String path){ tempCache = path; } public static String getTempPath(){ return tempCache; } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/common/entity/MagicShowResultEntity.java ================================================ package com.zero.magicshow.common.entity; /** * Created by hongli on 2017/8/31. */ public class MagicShowResultEntity { private int resultCode; private String resultMsg; private String filePath; private int imageWidth; private int imageHeight; private int angle; public int getAngle() { return angle; } public void setAngle(int angle) { this.angle = angle; } public int getResultCode() { return resultCode; } public void setResultCode(int resultCode) { this.resultCode = resultCode; } public String getResultMsg() { return resultMsg; } public void setResultMsg(String resultMsg) { this.resultMsg = resultMsg; } public String getFilePath() { return filePath; } public void setFilePath(String filePath) { this.filePath = filePath; } public int getImageWidth() { return imageWidth; } public void setImageWidth(int imageWidth) { this.imageWidth = imageWidth; } public int getImageHeight() { return imageHeight; } public void setImageHeight(int imageHeight) { this.imageHeight = imageHeight; } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/common/iface/CameraShootCallBack.java ================================================ package com.zero.magicshow.common.iface; import com.zero.magicshow.common.entity.MagicShowResultEntity; /** * Created by hongli on 2017/9/1. */ public interface CameraShootCallBack { public abstract void onCompentFinished(MagicShowResultEntity magicShowResultEntity); } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/common/iface/DialogYesOrNoCallBack.java ================================================ package com.zero.magicshow.common.iface; /** * Created by hongli on 2017/8/30. */ public interface DialogYesOrNoCallBack { public void onYesClick(); public void onNoClick(); } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/common/iface/GravityCallBack.java ================================================ package com.zero.magicshow.common.iface; /** * Created by hongli on 2017/9/1. */ public interface GravityCallBack { public void onGravityChange(int direction); } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/common/iface/ImageEditCallBack.java ================================================ package com.zero.magicshow.common.iface; import com.zero.magicshow.common.entity.MagicShowResultEntity; /** * Created by hongli on 2017/8/31. */ public interface ImageEditCallBack { public abstract void onCompentFinished(MagicShowResultEntity magicShowResultEntity); } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/common/iface/MagicListener.java ================================================ package com.zero.magicshow.common.iface; /** * Created by hongli on 2017/8/23. */ public interface MagicListener { public void onEnd(); } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/common/utils/BaseUtil.java ================================================ package com.zero.magicshow.common.utils; import android.app.Activity; import android.app.Dialog; import android.content.Context; import android.content.DialogInterface; import android.content.res.AssetManager; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Matrix; import android.media.ExifInterface; import android.text.TextUtils; import android.util.DisplayMetrics; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.animation.Animation; import android.widget.ImageView; import android.widget.TextView; import com.zero.magicshow.R; import com.zero.magicshow.common.config.PathConfig; import com.zero.magicshow.common.iface.DialogYesOrNoCallBack; import com.zero.zerolib.util.AnimationUtils; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; /** * Created by hongli on 2017/8/30. */ public class BaseUtil extends com.zero.zerolib.util.BaseUtil { // public static void scanFile(String filePath){ // MediaScannerConnection.scanFile(MagicParams.context, // new String[] {filePath}, null, // new MediaScannerConnection.OnScanCompletedListener() { // @Override // public void onScanCompleted(final String path, final Uri uri) { // // } // }); // } public static Bitmap rotateBitmapByDegree(Bitmap bm, int degree) { Bitmap returnBm = null; // 根据旋转角度,生成旋转矩阵 Matrix matrix = new Matrix(); matrix.postRotate(degree); try { // 将原始图片按照旋转矩阵进行旋转,并得到新的图片 returnBm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true); } catch (OutOfMemoryError e) { } if (returnBm == null) { returnBm = bm; } if (bm != returnBm) { bm.recycle(); } return returnBm; } public static boolean isPortrait(Activity activity) { DisplayMetrics dm = new DisplayMetrics(); activity.getWindowManager().getDefaultDisplay().getMetrics(dm); return dm.widthPixels < dm.heightPixels; } /** * 读取照片exif信息中的旋转角度 * * @param path 照片路径 * @return角度 */ public static int readPictureDegree(String path) { int degree = 0; try { ExifInterface exifInterface = new ExifInterface(path); int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); switch (orientation) { case ExifInterface.ORIENTATION_ROTATE_90: degree = 90; break; case ExifInterface.ORIENTATION_ROTATE_180: degree = 180; break; case ExifInterface.ORIENTATION_ROTATE_270: degree = 270; break; } } catch (IOException e) { e.printStackTrace(); } return degree; } public static void fadeOutView(final View view) { if (view.getVisibility() != View.VISIBLE) { return; } AnimationUtils.doFadeOut(view, new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { view.setVisibility(View.GONE); } @Override public void onAnimationRepeat(Animation animation) { } }); } public static void fadeInView(View view) { if (view.getVisibility() == View.VISIBLE) { return; } view.setVisibility(View.VISIBLE); AnimationUtils.doFadeIn(view); } public static void openYesOrNoDialog(final Activity activity, String title, String content, String yesText, String noText, final DialogYesOrNoCallBack yesOrNoCallBack) { final Dialog shopTipDialog = new Dialog(activity, R.style.loading_dialog); View view = LayoutInflater.from(activity).inflate(R.layout.dialog_yes_or_no, null); final ImageView btnClose = (ImageView) view.findViewById(R.id.gift_balance_lack_close); final TextView btnYes = (TextView) view.findViewById(R.id.dialog_yes_or_no_btnyes); final TextView tvTitle = (TextView) view.findViewById(R.id.dialog_yes_or_no_title); final TextView tvCon = (TextView) view.findViewById(R.id.dialog_yes_or_no_con); final TextView btnNo = (TextView) view.findViewById(R.id.dialog_yes_or_no_btnno); tvTitle.setText(title); if (TextUtils.isEmpty(title)) { tvTitle.setVisibility(View.GONE); } tvCon.setText(content); if (TextUtils.isEmpty(content)) { tvCon.setVisibility(View.GONE); } if (!TextUtils.isEmpty(yesText)) { btnYes.setText(yesText); } if (!TextUtils.isEmpty(noText)) { btnNo.setText(noText); } View.OnClickListener onClickListener = new View.OnClickListener() { @Override public void onClick(View v) { if (v == btnClose) { shopTipDialog.dismiss(); } else if (v == btnYes) { yesOrNoCallBack.onYesClick(); shopTipDialog.dismiss(); } else if (v == btnNo) { yesOrNoCallBack.onNoClick(); shopTipDialog.dismiss(); } } }; shopTipDialog.setOnCancelListener(new DialogInterface.OnCancelListener() { @Override public void onCancel(DialogInterface dialog) { yesOrNoCallBack.onNoClick(); } }); btnClose.setOnClickListener(onClickListener); btnYes.setOnClickListener(onClickListener); btnNo.setOnClickListener(onClickListener); // shopTipDialog.setCanceledOnTouchOutside(true); shopTipDialog.setContentView(view, new ViewGroup.LayoutParams(dipToPix(activity, 267), dipToPix(activity, 100))); //try catch防止activity已经销毁 try { shopTipDialog.show(); } catch (Exception e) { e.printStackTrace(); } } public static File getRandomTempImageFile() { return new File(getRandomTempImagePath()); } public static String getRandomTempImagePath() { return PathConfig.getTempPath() + "/" + getRandomStr() + ".jpg"; } public static String getRandomStr() { int randInt = (int) (Math.random() * 100000); if (randInt < 10000) { randInt = randInt + 10000; } return DateUtils.getTimeStamp() + randInt; } /** * 保存bitmap到本地 * * @param bitmap * @param distancePath */ public static void saveBitmap(Bitmap bitmap, String distancePath) { if (TextUtils.isEmpty(distancePath) || null == bitmap || bitmap.isRecycled()) { Log.e("BaseUtil", "in saveBitmap bitmap is null or recycles or distancePath is empty."); return; } File file = new File(distancePath); if (file.exists()) { file.delete(); } try { FileOutputStream out = new FileOutputStream(file); //压缩20%,否则保存的文件会变大 bitmap.compress(Bitmap.CompressFormat.JPEG, 75, out); out.flush(); out.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } public static Bitmap getImageFromAssetsFile(Context context, String fileName) { Bitmap image = null; AssetManager am = context.getResources().getAssets(); try { InputStream is = am.open(fileName); image = BitmapFactory.decodeStream(is); is.close(); } catch (IOException e) { e.printStackTrace(); } return image; } /** * according to the width to get bitmap,if image's width more than width, * than compress the image's width and height * * @param path * @param width the width which need to be * @param height */ public static Bitmap getBitmapBySimpleSize( String path, float width, float height) { if (TextUtils.isEmpty(path)) { return null; } BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; // 通过这个bitmap获取图片的宽和高 Bitmap bitmap = BitmapFactory.decodeFile(path, options); setBitmapNormalOptions(options, width, height); // 注意这次要把options.inJustDecodeBounds 设为 false,这次图片是要读取出来的。 // MyLogUtil.e("HongLi", "path:" + path); bitmap = BitmapFactory.decodeFile(path, options); // MyLogUtil.e("HongLi", "image width:" + bitmap.getWidth() + ";height:" + bitmap.getHeight()); return bitmap; } /** * 设置bitmap的缩放比 * * @param options * @param width * @param height */ private static void setBitmapNormalOptions( BitmapFactory.Options options, float width, float height) { if (null == options) { return; } if (options.outWidth > width) { float scale = (options.outWidth / width); //如果按照宽度缩放比例导致高度小于原定高度,则按照高度的缩放比例来缩放 if (options.outHeight / scale < height) { scale = (options.outHeight / height); } int realScale = scale - (int) scale >= 0.2 ? (int) scale + 1 : (int) scale; realScale = realScale <= 0 ? 1 : realScale; options.inSampleSize = realScale; options.outWidth = options.outWidth / options.inSampleSize; options.outHeight = options.outHeight / options.inSampleSize; } else { options.inSampleSize = 1; } if (options.outHeight > 3500) { int realScale = options.outHeight / 3500; options.inSampleSize = options.inSampleSize < realScale ? realScale : options.inSampleSize; } if (options.outWidth > 3500) { int realScale = options.outWidth / 3500; options.inSampleSize = options.inSampleSize < realScale ? realScale : options.inSampleSize; } options.inJustDecodeBounds = false; options.inPurgeable = true; options.inInputShareable = true; //RGB会造成透明PNG显示黑色背景 options.inPreferredConfig = Bitmap.Config.ARGB_8888; } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/common/utils/CameraBitmapUtil.java ================================================ package com.zero.magicshow.common.utils; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.Matrix; import android.hardware.Camera; import android.view.Surface; /** * Created by hongli on 2017/12/14. */ public class CameraBitmapUtil { public static Bitmap handlerCameraBitmap(Activity activity, Bitmap takeBitmap,int cameraId) { Matrix matrix = new Matrix(); matrix.postRotate(getCameraDisplayOrientation(activity, cameraId)); matrix.postScale(1, cameraId == 1 ? -1 : 1); Bitmap cropRotateScaled = Bitmap.createBitmap(takeBitmap, 0, 0, takeBitmap.getWidth(), takeBitmap.getHeight(), matrix, true); if (cropRotateScaled != takeBitmap) { takeBitmap.recycle(); } return cropRotateScaled; } public static int getCameraDisplayOrientation(Activity activity,int cameraId) { int result = 90; try { android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo(); android.hardware.Camera.getCameraInfo(cameraId, info); int rotation = activity.getWindowManager().getDefaultDisplay().getRotation(); int degrees = 0; switch (rotation) { case Surface.ROTATION_0: degrees = 0; break; case Surface.ROTATION_90: degrees = 90; break; case Surface.ROTATION_180: degrees = 180; break; case Surface.ROTATION_270: degrees = 270; break; } if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { result = (info.orientation + degrees) % 360; result = (360 - result) % 360; // compensate the mirror } else { // back-facing result = (info.orientation - degrees + 360) % 360; } } catch (Exception e) { e.printStackTrace(); } return result; } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/common/utils/CameraParamUtil.java ================================================ package com.zero.magicshow.common.utils; import android.hardware.Camera; import android.util.Log; import java.util.Collections; import java.util.Comparator; import java.util.List; /** * Created by hongli on 2017/9/1. */ public class CameraParamUtil { private static final String TAG = "JCameraView"; private CameraSizeComparator sizeComparator = new CameraSizeComparator(); private static CameraParamUtil cameraParamUtil = null; private CameraParamUtil() { } public static CameraParamUtil getInstance() { if (cameraParamUtil == null) { cameraParamUtil = new CameraParamUtil(); return cameraParamUtil; } else { return cameraParamUtil; } } public Camera.Size getPreviewSize(List list, int th, float rate) { Collections.sort(list, sizeComparator); int i = 0; for (Camera.Size s : list) { if ((s.width > th) && equalRate(s, rate)) { Log.i(TAG, "MakeSure Preview :w = " + s.width + " h = " + s.height); break; } i++; } if (i == list.size()) { return getBestSize(list, rate); } else { return list.get(i); } } public Camera.Size getPictureSize(List list, int th, float rate) { Collections.sort(list, sizeComparator); int i = 0; for (Camera.Size s : list) { if ((s.width > th) && equalRate(s, rate)) { Log.i(TAG, "MakeSure Picture :w = " + s.width + " h = " + s.height); break; } i++; } if (i == list.size()) { return getBestSize(list, rate); } else { return list.get(i); } } public Camera.Size getBestSize(List list, float rate) { float previewDisparity = 100; int index = 0; for (int i = 0; i < list.size(); i++) { Camera.Size cur = list.get(i); float prop = (float) cur.width / (float) cur.height; if (Math.abs(rate - prop) < previewDisparity) { previewDisparity = Math.abs(rate - prop); index = i; } } return list.get(index); } public boolean equalRate(Camera.Size s, float rate) { float r = (float) (s.width) / (float) (s.height); if (Math.abs(r - rate) <= 0.2) { return true; } else { return false; } } public boolean isSupportedFocusMode(List focusList, String focusMode) { for (int i = 0; i < focusList.size(); i++) { if (focusMode.equals(focusList.get(i))) { Log.i(TAG, "FocusMode supported " + focusMode); return true; } } Log.i(TAG, "FocusMode not supported " + focusMode); return false; } public boolean isSupportedPictureFormats(List supportedPictureFormats, int jpeg) { for (int i = 0; i < supportedPictureFormats.size(); i++) { if (jpeg == supportedPictureFormats.get(i)) { Log.i(TAG, "Formats supported " + jpeg); return true; } } Log.i(TAG, "Formats not supported " + jpeg); return false; } public class CameraSizeComparator implements Comparator { public int compare(Camera.Size lhs, Camera.Size rhs) { if (lhs.width == rhs.width) { return 0; } else if (lhs.width > rhs.width) { return 1; } else { return -1; } } } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/common/utils/Constants.java ================================================ package com.zero.magicshow.common.utils; import android.os.Environment; import android.util.Log; import com.zero.magicshow.core.filter.utils.MagicFilterType; import java.io.File; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; /** * Created by hongli on 2017/8/22. */ public class Constants { public static final String TRANSMIT_IMAGE_URL = "imageUrl"; public static final MagicFilterType[] FILTER_TYPES = new MagicFilterType[]{ MagicFilterType.NONE, MagicFilterType.FAIRYTALE, MagicFilterType.SUNRISE, MagicFilterType.SUNSET, MagicFilterType.WHITECAT, MagicFilterType.BLACKCAT, MagicFilterType.SKINWHITEN, MagicFilterType.HEALTHY, MagicFilterType.SWEETS, MagicFilterType.ROMANCE, MagicFilterType.SAKURA, MagicFilterType.WARM, MagicFilterType.ANTIQUE, MagicFilterType.NOSTALGIA, MagicFilterType.CALM, MagicFilterType.LATTE, MagicFilterType.TENDER, MagicFilterType.COOL, MagicFilterType.EMERALD, MagicFilterType.EVERGREEN, MagicFilterType.CRAYON, MagicFilterType.SKETCH, MagicFilterType.AMARO, MagicFilterType.BRANNAN, MagicFilterType.BROOKLYN, MagicFilterType.EARLYBIRD, MagicFilterType.FREUD, MagicFilterType.HEFE, MagicFilterType.HUDSON, MagicFilterType.INKWELL, MagicFilterType.KEVIN, // MagicFilterType.LOMO, MagicFilterType.N1977, MagicFilterType.NASHVILLE, MagicFilterType.PIXAR, MagicFilterType.RISE, MagicFilterType.SIERRA, MagicFilterType.SUTRO, MagicFilterType.TOASTER2, MagicFilterType.VALENCIA, MagicFilterType.WALDEN, MagicFilterType.XPROII }; public static int mScreenWidth; public static int mScreenHeight; public static File getOutputMediaFile() { // To be safe, you should check that the SDCard is mounted // using Environment.getExternalStorageState() before doing this. File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_PICTURES), "MagicCamera"); // This location works best if you want the created images to be shared // between applications and persist after your app has been uninstalled. // Create the storage directory if it does not exist if (!mediaStorageDir.exists()) { if (!mediaStorageDir.mkdirs()) { Log.d("MyCameraApp", "failed to create directory"); return null; } } // Create a media file name String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",Locale.CHINESE).format(new Date()); File mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg"); return mediaFile; } public static final int RX_JAVA_TYPE_IMAGE_EDIT = 10001;//图片编译 public static final int RX_JAVA_TYPE_CAMERA_SHOOT = 10002;//照片拍摄 } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/common/utils/DateUtils.java ================================================ package com.zero.magicshow.common.utils; import com.zero.zerolib.util.DateUtil; import java.text.SimpleDateFormat; import java.util.Date; /** * Created by hongli on 2017/8/30. */ public class DateUtils extends DateUtil{ /** * 获取时间戳 * @return 20180521172011 */ public static String getTimeStamp(){ SimpleDateFormat sim = new SimpleDateFormat("yyyyMMddHHmmss"); try { return sim.format(new Date()); }catch(Exception e){ e.printStackTrace(); } return ""; } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/common/utils/FilterTypeHelper.java ================================================ package com.zero.magicshow.common.utils; import com.zero.magicshow.R; import com.zero.magicshow.core.filter.utils.MagicFilterType; public class FilterTypeHelper { public static int FilterType2Color(MagicFilterType filterType){ switch (filterType) { case NONE: return R.color.filter_color_grey_light; case WHITECAT: case BLACKCAT: case SUNRISE: case SUNSET: return R.color.filter_color_brown_light; case COOL: return R.color.filter_color_blue_dark; case EMERALD: case EVERGREEN: return R.color.filter_color_blue_dark_dark; case FAIRYTALE: return R.color.filter_color_blue; case ROMANCE: case SAKURA: case WARM: return R.color.filter_color_pink; case AMARO: case BRANNAN: case BROOKLYN: case EARLYBIRD: case FREUD: case HEFE: case HUDSON: case INKWELL: case KEVIN: case LOMO: case N1977: case NASHVILLE: case PIXAR: case RISE: case SIERRA: case SUTRO: case TOASTER2: case VALENCIA: case WALDEN: case XPROII: return R.color.filter_color_brown_dark; case ANTIQUE: case NOSTALGIA: return R.color.filter_color_green_dark; case SKINWHITEN: case HEALTHY: return R.color.filter_color_red; case SWEETS: return R.color.filter_color_red_dark; case CALM: case LATTE: case TENDER: return R.color.filter_color_brown; default: return R.color.filter_color_grey_light; } } public static int FilterType2Thumb(MagicFilterType filterType){ switch (filterType) { case NONE: return R.drawable.filter_thumb_original; case WHITECAT: return R.drawable.filter_thumb_whitecat; case BLACKCAT: return R.drawable.filter_thumb_blackcat; case ROMANCE: return R.drawable.filter_thumb_romance; case SAKURA: return R.drawable.filter_thumb_sakura; case AMARO: return R.drawable.filter_thumb_amoro; case BRANNAN: return R.drawable.filter_thumb_brannan; case BROOKLYN: return R.drawable.filter_thumb_brooklyn; case EARLYBIRD: return R.drawable.filter_thumb_earlybird; case FREUD: return R.drawable.filter_thumb_freud; case HEFE: return R.drawable.filter_thumb_hefe; case HUDSON: return R.drawable.filter_thumb_hudson; case INKWELL: return R.drawable.filter_thumb_inkwell; case KEVIN: return R.drawable.filter_thumb_kevin; case LOMO: return R.drawable.filter_thumb_lomo; case N1977: return R.drawable.filter_thumb_1977; case NASHVILLE: return R.drawable.filter_thumb_nashville; case PIXAR: return R.drawable.filter_thumb_piaxr; case RISE: return R.drawable.filter_thumb_rise; case SIERRA: return R.drawable.filter_thumb_sierra; case SUTRO: return R.drawable.filter_thumb_sutro; case TOASTER2: return R.drawable.filter_thumb_toastero; case VALENCIA: return R.drawable.filter_thumb_valencia; case WALDEN: return R.drawable.filter_thumb_walden; case XPROII: return R.drawable.filter_thumb_xpro; case ANTIQUE: return R.drawable.filter_thumb_antique; case SKINWHITEN: return R.drawable.filter_thumb_beauty; case CALM: return R.drawable.filter_thumb_calm; case COOL: return R.drawable.filter_thumb_cool; case EMERALD: return R.drawable.filter_thumb_emerald; case EVERGREEN: return R.drawable.filter_thumb_evergreen; case FAIRYTALE: return R.drawable.filter_thumb_fairytale; case HEALTHY: return R.drawable.filter_thumb_healthy; case NOSTALGIA: return R.drawable.filter_thumb_nostalgia; case TENDER: return R.drawable.filter_thumb_tender; case SWEETS: return R.drawable.filter_thumb_sweets; case LATTE: return R.drawable.filter_thumb_latte; case WARM: return R.drawable.filter_thumb_warm; case SUNRISE: return R.drawable.filter_thumb_sunrise; case SUNSET: return R.drawable.filter_thumb_sunset; case CRAYON: return R.drawable.filter_thumb_crayon; case SKETCH: return R.drawable.filter_thumb_sketch; default: return R.drawable.filter_thumb_original; } } public static int FilterType2Name(MagicFilterType filterType){ switch (filterType) { case NONE: return R.string.filter_none; case WHITECAT: return R.string.filter_whitecat; case BLACKCAT: return R.string.filter_blackcat; case ROMANCE: return R.string.filter_romance; case SAKURA: return R.string.filter_sakura; case AMARO: return R.string.filter_amaro; case BRANNAN: return R.string.filter_brannan; case BROOKLYN: return R.string.filter_brooklyn; case EARLYBIRD: return R.string.filter_Earlybird; case FREUD: return R.string.filter_freud; case HEFE: return R.string.filter_hefe; case HUDSON: return R.string.filter_hudson; case INKWELL: return R.string.filter_inkwell; case KEVIN: return R.string.filter_kevin; case LOMO: return R.string.filter_lomo; case N1977: return R.string.filter_n1977; case NASHVILLE: return R.string.filter_nashville; case PIXAR: return R.string.filter_pixar; case RISE: return R.string.filter_rise; case SIERRA: return R.string.filter_sierra; case SUTRO: return R.string.filter_sutro; case TOASTER2: return R.string.filter_toastero; case VALENCIA: return R.string.filter_valencia; case WALDEN: return R.string.filter_walden; case XPROII: return R.string.filter_xproii; case ANTIQUE: return R.string.filter_antique; case CALM: return R.string.filter_calm; case COOL: return R.string.filter_cool; case EMERALD: return R.string.filter_emerald; case EVERGREEN: return R.string.filter_evergreen; case FAIRYTALE: return R.string.filter_fairytale; case HEALTHY: return R.string.filter_healthy; case NOSTALGIA: return R.string.filter_nostalgia; case TENDER: return R.string.filter_tender; case SWEETS: return R.string.filter_sweets; case LATTE: return R.string.filter_latte; case WARM: return R.string.filter_warm; case SUNRISE: return R.string.filter_sunrise; case SUNSET: return R.string.filter_sunset; case SKINWHITEN: return R.string.filter_skinwhiten; case CRAYON: return R.string.filter_crayon; case SKETCH: return R.string.filter_sketch; default: return R.string.filter_none; } } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/common/utils/GravityUtil.java ================================================ package com.zero.magicshow.common.utils; import android.app.Activity; import android.content.Context; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.os.Handler; import android.os.Message; import android.util.Log; import com.zero.magicshow.common.iface.GravityCallBack; /** * Created by hongli on 2017/9/1. */ public class GravityUtil { private static final String TAG = GravityUtil.class.getSimpleName(); public static final int DIRECTION_LAND_LEFT = 1; public static final int DIRECTION_PORTRAIT_POSITIVE = 2; public static final int DIRECTION_LAND_RIGHT = 3; public static final int DIRECTION_PORTRAIT_NEGATIVE = 4; public static final int DIRECTION_LAND = 5;//手动选择横屏 public static final int DIRECTION_PORTRAIT = 6;//手动选择竖屏 private volatile static GravityUtil gravityUtil = new GravityUtil(); private GravityCallBack gravityCallBack; private Activity mActivity; // 是否是竖屏 private boolean isPortrait = true; //是否是左面倾斜横屏还是右面倾斜 private boolean isLeftCrossScreen = true; private SensorManager sm; private GravityUtil.OrientationSensorListener listener; private Sensor sensor; private SensorManager sm1; private Sensor sensor1; private GravityUtil.OrientationSensorListener1 listener1; private final int MAX_RETRY_COUNT = 10; private int retryLandLeftCount = 0;//并非已判断是横或者竖就立即发送消息,持续MAX_RETRY_COUNT次之后才会发送 private int retryLandRightCount = 0; private int retryPorPositiveCount = 0; private int retryPorNegtiveCount = 0; public static GravityUtil getInstance(){ return gravityUtil; } private GravityUtil(){ } /** * 返回ScreenSwitchUtils单例 **/ public void init(Context context, GravityCallBack gravityCallBack) { Log.d(TAG, "init orientation listener."); if(null == sm){ // 注册重力感应器,监听屏幕旋转 sm = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); sensor = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); listener = new GravityUtil.OrientationSensorListener(mHandler); // 根据 旋转之后/点击全屏之后 两者方向一致,激活sm. sm1 = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); sensor1 = sm1.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); listener1 = new GravityUtil.OrientationSensorListener1(); } this.gravityCallBack = gravityCallBack; } private Handler mHandler = new Handler() { public void handleMessage(Message msg) { switch (msg.what) { case 888: int orientation = msg.arg1; if (orientation > 45 && orientation < 135) { if (isPortrait && retryLandRightCount >= MAX_RETRY_COUNT) { Log.e("test", "切换成右横屏"); isLeftCrossScreen = false; gravityCallBack.onGravityChange(DIRECTION_LAND_RIGHT); // mActivity.setRequestedOrientation(0); isPortrait = false; retryLandRightCount = 0; }else{ retryLandRightCount++; retryLandLeftCount = 0; retryPorNegtiveCount = 0; retryPorPositiveCount = 0; } } else if (orientation > 135 && orientation < 225) { if (!isPortrait && retryPorNegtiveCount >= MAX_RETRY_COUNT) { Log.e("test", "切换成反竖屏"); // mActivity.setRequestedOrientation(1); gravityCallBack.onGravityChange(DIRECTION_PORTRAIT_NEGATIVE); isPortrait = true; retryPorNegtiveCount = 0; }else{ retryPorNegtiveCount++; retryLandRightCount = 0; retryLandLeftCount = 0; retryPorPositiveCount = 0; } } else if (orientation > 225 && orientation < 315) { if (isPortrait && retryLandLeftCount >= MAX_RETRY_COUNT) { Log.e("test", "切换成左横屏"); isLeftCrossScreen = true; gravityCallBack.onGravityChange(DIRECTION_LAND_LEFT); // mActivity.setRequestedOrientation(0); isPortrait = false; retryLandLeftCount = 0; }else{ retryLandLeftCount++; retryPorNegtiveCount = 0; retryLandRightCount = 0; retryPorPositiveCount = 0; } } else if ((orientation > 315 && orientation < 360) || (orientation > 0 && orientation < 45)) { if (!isPortrait && retryPorPositiveCount >+MAX_RETRY_COUNT) { Log.e("test", "切换成竖屏"); // mActivity.setRequestedOrientation(1); gravityCallBack.onGravityChange(DIRECTION_PORTRAIT_POSITIVE); isPortrait = true; retryPorPositiveCount = 0; }else{ retryPorPositiveCount++; retryPorNegtiveCount = 0; retryLandRightCount = 0; retryLandLeftCount = 0; } } break; default: break; } } }; /** * 开始监听 */ public void start(Activity activity) { Log.d(TAG, "start orientation listener."); mActivity = activity; sm.registerListener(listener, sensor, SensorManager.SENSOR_DELAY_UI); } /** * 停止监听 */ public void stop() { Log.d(TAG, "stop orientation listener."); sm.unregisterListener(listener); sm1.unregisterListener(listener1); } /** * 手动横竖屏切换方向 */ public void toggleScreen() { // sm.unregisterListener(listener); // sm1.registerListener(listener1, sensor1,SensorManager.SENSOR_DELAY_UI); // if (isPortrait) { // isPortrait = false; // // 切换成横屏 // mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); // } else { // isPortrait = true; // // 切换成竖屏 // mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); // } } public boolean isPortrait() { return this.isPortrait; } public boolean isLeftCrossScreen() { return this.isLeftCrossScreen; } /** * 重力感应监听者 */ public class OrientationSensorListener implements SensorEventListener { private static final int _DATA_X = 0; private static final int _DATA_Y = 1; private static final int _DATA_Z = 2; public static final int ORIENTATION_UNKNOWN = -1; private Handler rotateHandler; public OrientationSensorListener(Handler handler) { rotateHandler = handler; } public void onAccuracyChanged(Sensor arg0, int arg1) { } public void onSensorChanged(SensorEvent event) { float[] values = event.values; int orientation = ORIENTATION_UNKNOWN; float X = -values[_DATA_X]; float Y = -values[_DATA_Y]; float Z = -values[_DATA_Z]; float magnitude = X * X + Y * Y; // Don't trust the angle if the magnitude is small compared to the y // value if (magnitude * 4 >= Z * Z) { // 屏幕旋转时 float OneEightyOverPi = 57.29577957855f; float angle = (float) Math.atan2(-Y, X) * OneEightyOverPi; orientation = 90 - (int) Math.round(angle); // normalize to 0 - 359 range while (orientation >= 360) { orientation -= 360; } while (orientation < 0) { orientation += 360; } } if (rotateHandler != null) { rotateHandler.obtainMessage(888, orientation, 0).sendToTarget(); } } } public class OrientationSensorListener1 implements SensorEventListener { private static final int _DATA_X = 0; private static final int _DATA_Y = 1; private static final int _DATA_Z = 2; public static final int ORIENTATION_UNKNOWN = -1; public OrientationSensorListener1() { } public void onAccuracyChanged(Sensor arg0, int arg1) { } public void onSensorChanged(SensorEvent event) { float[] values = event.values; int orientation = ORIENTATION_UNKNOWN; float X = -values[_DATA_X]; float Y = -values[_DATA_Y]; float Z = -values[_DATA_Z]; float magnitude = X * X + Y * Y; // Don't trust the angle if the magnitude is small compared to the y // value if (magnitude * 4 >= Z * Z) { // 屏幕旋转时 float OneEightyOverPi = 57.29577957855f; float angle = (float) Math.atan2(-Y, X) * OneEightyOverPi; orientation = 90 - (int) Math.round(angle); // normalize to 0 - 359 range while (orientation >= 360) { orientation -= 360; } while (orientation < 0) { orientation += 360; } } if (orientation > 225 && orientation < 315) {// 检测到当前实际是横屏 if (!isPortrait) { sm.registerListener(listener, sensor, SensorManager.SENSOR_DELAY_UI); sm1.unregisterListener(listener1); } } else if ((orientation > 315 && orientation < 360) || (orientation > 0 && orientation < 45)) {// 检测到当前实际是竖屏 if (isPortrait) { sm.registerListener(listener, sensor, SensorManager.SENSOR_DELAY_UI); sm1.unregisterListener(listener1); } } } } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/common/utils/MagicParams.java ================================================ package com.zero.magicshow.common.utils; import android.content.Context; import android.os.Environment; import com.zero.magicshow.common.base.MagicBaseView; /** * Created by why8222 on 2016/2/26. */ public class MagicParams { public static Context context; public static MagicBaseView magicBaseView; public static String videoPath = Environment.getExternalStorageDirectory().getPath(); public static String videoName = "MagicCamera_test.mp4"; public static int beautyLevel = 0; public MagicParams() { } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/common/utils/OpenGlUtils.java ================================================ package com.zero.magicshow.common.utils; import android.content.Context; import android.content.res.AssetManager; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.opengl.GLES11Ext; import android.opengl.GLES20; import android.opengl.GLUtils; import android.util.Log; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.Buffer; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import java.nio.IntBuffer; import javax.microedition.khronos.opengles.GL10; public class OpenGlUtils { public static final int NO_TEXTURE = -1; public static final int NOT_INIT = -1; public static final int ON_DRAWN = 1; public static int loadTexture(final Bitmap img, final int usedTexId) { return loadTexture(img, usedTexId, false); } public static int loadTexture(final Bitmap img, final int usedTexId, boolean recyled) { if(img == null) return NO_TEXTURE; int textures[] = new int[1]; if (usedTexId == NO_TEXTURE) { GLES20.glGenTextures(1, textures, 0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, img, 0); } else { GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, usedTexId); GLUtils.texSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0, img); textures[0] = usedTexId; } if(recyled) img.recycle(); return textures[0]; } public static int loadTexture(final Buffer data, final int width,final int height, final int usedTexId) { if(data == null) return NO_TEXTURE; int textures[] = new int[1]; if (usedTexId == NO_TEXTURE) { GLES20.glGenTextures(1, textures, 0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, width, height, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, data); } else { GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, usedTexId); GLES20.glTexSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0, width, height, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, data); textures[0] = usedTexId; } return textures[0]; } public static int loadTexture(final Buffer data, final int width,final int height, final int usedTexId,final int type) { if(data == null) return NO_TEXTURE; int textures[] = new int[1]; if (usedTexId == NO_TEXTURE) { GLES20.glGenTextures(1, textures, 0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, width, height, 0, GLES20.GL_RGBA, type, data); } else { GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, usedTexId); GLES20.glTexSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0, width, height, GLES20.GL_RGBA, type, data); textures[0] = usedTexId; } return textures[0]; } public static int loadTexture(final Context context, final String name){ final int[] textureHandle = new int[1]; GLES20.glGenTextures(1, textureHandle, 0); if (textureHandle[0] != 0){ // Read in the resource final Bitmap bitmap = getImageFromAssetsFile(context,name); // Bind to the texture in OpenGL GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[0]); // Set filtering GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); // Load the bitmap into the bound texture. GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0); // Recycle the bitmap, since its data has been loaded into OpenGL. bitmap.recycle(); } if (textureHandle[0] == 0){ throw new RuntimeException("Error loading texture."); } return textureHandle[0]; } private static Bitmap getImageFromAssetsFile(Context context,String fileName){ Bitmap image = null; AssetManager am = context.getResources().getAssets(); try{ InputStream is = am.open(fileName); image = BitmapFactory.decodeStream(is); is.close(); }catch (IOException e){ e.printStackTrace(); } return image; } public static int loadProgram(final String strVSource, final String strFSource) { int iVShader; int iFShader; int iProgId; int[] link = new int[1]; iVShader = loadShader(strVSource, GLES20.GL_VERTEX_SHADER); if (iVShader == 0) { Log.d("Load Program", "Vertex Shader Failed"); return 0; } iFShader = loadShader(strFSource, GLES20.GL_FRAGMENT_SHADER); if (iFShader == 0) { Log.d("Load Program", "Fragment Shader Failed"); return 0; } iProgId = GLES20.glCreateProgram(); GLES20.glAttachShader(iProgId, iVShader); GLES20.glAttachShader(iProgId, iFShader); GLES20.glLinkProgram(iProgId); GLES20.glGetProgramiv(iProgId, GLES20.GL_LINK_STATUS, link, 0); if (link[0] <= 0) { Log.d("Load Program", "Linking Failed"); return 0; } GLES20.glDeleteShader(iVShader); GLES20.glDeleteShader(iFShader); return iProgId; } private static int loadShader(final String strSource, final int iType) { int[] compiled = new int[1]; int iShader = GLES20.glCreateShader(iType); GLES20.glShaderSource(iShader, strSource); GLES20.glCompileShader(iShader); GLES20.glGetShaderiv(iShader, GLES20.GL_COMPILE_STATUS, compiled, 0); if (compiled[0] == 0) { Log.e("Load Shader Failed", "Compilation\n" + GLES20.glGetShaderInfoLog(iShader)); return 0; } return iShader; } public static int getExternalOESTextureID(){ int[] texture = new int[1]; GLES20.glGenTextures(1, texture, 0); GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, texture[0]); GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_LINEAR); GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR); GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE); GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE); return texture[0]; } public static String readShaderFromRawResource(final int resourceId){ final InputStream inputStream = MagicParams.context.getResources().openRawResource( resourceId); final InputStreamReader inputStreamReader = new InputStreamReader( inputStream); final BufferedReader bufferedReader = new BufferedReader( inputStreamReader); String nextLine; final StringBuilder body = new StringBuilder(); try{ while ((nextLine = bufferedReader.readLine()) != null){ body.append(nextLine); body.append('\n'); } } catch (IOException e){ return null; } return body.toString(); } public static Bitmap drawToBitmapByFilter(Bitmap bitmap, GPUImageFilter filter, int displayWidth, int displayHeight, boolean rotate){ if(filter == null) return null; int width = bitmap.getWidth(); int height = bitmap.getHeight(); int[] mFrameBuffers = new int[1]; int[] mFrameBufferTextures = new int[1]; GLES20.glGenFramebuffers(1, mFrameBuffers, 0); GLES20.glGenTextures(1, mFrameBufferTextures, 0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mFrameBufferTextures[0]); GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, width, height, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, mFrameBuffers[0]); GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, mFrameBufferTextures[0], 0); GLES20.glViewport(0, 0, width, height); filter.onInputSizeChanged(width, height); filter.onDisplaySizeChanged(displayWidth, displayHeight); int textureId = OpenGlUtils.loadTexture(bitmap, OpenGlUtils.NO_TEXTURE, true); if(rotate){ FloatBuffer gLCubeBuffer = ByteBuffer.allocateDirect(TextureRotationUtil.CUBE.length * 4) .order(ByteOrder.nativeOrder()) .asFloatBuffer(); gLCubeBuffer.put(TextureRotationUtil.CUBE).position(0); FloatBuffer gLTextureBuffer = ByteBuffer.allocateDirect(TextureRotationUtil.TEXTURE_NO_ROTATION.length * 4) .order(ByteOrder.nativeOrder()) .asFloatBuffer(); gLTextureBuffer.put(TextureRotationUtil.getRotation(Rotation.ROTATION_90, true, false)).position(0); filter.onDrawFrame(textureId, gLCubeBuffer, gLTextureBuffer); }else { filter.onDrawFrame(textureId); } IntBuffer ib = IntBuffer.allocate(width * height); GLES20.glReadPixels(0, 0, width, height, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, ib); Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); result.copyPixelsFromBuffer(IntBuffer.wrap(ib.array())); GLES20.glDeleteTextures(1, new int[]{textureId}, 0); GLES20.glDeleteFramebuffers(1, mFrameBuffers, 0); GLES20.glDeleteTextures(1, mFrameBufferTextures, 0); filter.onInputSizeChanged(displayWidth, displayHeight); return result; } /** * Checks to see if a GLES error has been raised. */ public static void checkGlError(String op) { int error = GLES20.glGetError(); if (error != GLES20.GL_NO_ERROR) { String msg = op + ": glError 0x" + Integer.toHexString(error); Log.e("OpenGlUtils", msg); throw new RuntimeException(msg); } } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/common/utils/Rotation.java ================================================ /* * Copyright (C) 2012 CyberAgent * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.zero.magicshow.common.utils; public enum Rotation { NORMAL, ROTATION_90, ROTATION_180, ROTATION_270; /** * Retrieves the int representation of the Rotation. * * @return 0, 90, 180 or 270 */ public int asInt() { switch (this) { case NORMAL: return 0; case ROTATION_90: return 90; case ROTATION_180: return 180; case ROTATION_270: return 270; default: throw new IllegalStateException("Unknown Rotation!"); } } /** * Create a Rotation from an integer. Needs to be either 0, 90, 180 or 270. * * @param rotation 0, 90, 180 or 270 * @return Rotation object */ public static Rotation fromInt(int rotation) { switch (rotation) { case 0: return NORMAL; case 90: return ROTATION_90; case 180: return ROTATION_180; case 270: return ROTATION_270; case 360: return NORMAL; default: throw new IllegalStateException( rotation + " is an unknown rotation. Needs to be either 0, 90, 180 or 270!"); } } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/common/utils/RxBus.java ================================================ package com.zero.magicshow.common.utils; import android.support.annotation.NonNull; import android.util.Log; import com.zero.zerolib.manager.PostManager; import java.util.Vector; import rx.android.schedulers.AndroidSchedulers; import rx.functions.Action1; import rx.functions.Actions; import rx.internal.util.ActionSubscriber; import rx.subjects.PublishSubject; import rx.subjects.Subject; /** * Created by hongli on 2017/8/31. */ public class RxBus { private static RxBus instance; private Vector subjectList = new Vector<>(); private RxBus() { } public static synchronized RxBus getInstance() { if (null == instance) { instance = new RxBus(); } return instance; } // public synchronized ZeroSubject register(int actionType) { // Subject subject = PublishSubject.create(); // ZeroSubject zeroSubject = new ZeroSubject(subject,actionType,null); // subjectList.add(zeroSubject); // return zeroSubject; // } // // public synchronized void unregister(Object object) { // subjectList.remove(object); // } public synchronized void registerMain(int actionType, Action1 action){ Subject subject = PublishSubject.create(); subject.observeOn(AndroidSchedulers.mainThread()).doOnError(new Action1() { @Override public void call(Throwable throwable) { throwable.printStackTrace(); Log.e("RxBus","post error"); } }).subscribe(new ActionSubscriber(action, new Action1() { @Override public void call(Throwable throwable) { throwable.printStackTrace(); Log.e("RxBus","post error"); } }, Actions.empty())); ZeroSubject zeroSubject = new ZeroSubject(subject,actionType,action); subjectList.add(zeroSubject); } public synchronized void unregisterMain(Action1 action) { for(ZeroSubject zeroSubject : subjectList){ if(zeroSubject.getAction() == action){ subjectList.remove(zeroSubject); break; } } } public synchronized void unregisterMain(int actionType) { for(ZeroSubject zeroSubject : subjectList){ if(zeroSubject.getActionType() == actionType){ subjectList.remove(zeroSubject); break; } } } public synchronized void unregisterAllMain(int actionType) { Vector subjectRemoveList = new Vector<>(); for(ZeroSubject zeroSubject : subjectList){ if(zeroSubject.getActionType() == actionType){ subjectRemoveList.add(zeroSubject); } } subjectList.removeAll(subjectRemoveList); } public synchronized void unregisterCategory(int actionType) { for(ZeroSubject zeroSubject : subjectList){ if(zeroSubject.getActionType() == actionType){ subjectList.remove(zeroSubject); break; } } } public void post(@NonNull final Object content, final int actionType) { PostManager.getInstance().postMain(new Runnable() { @Override public void run() { synchronized (this) { try{ for (ZeroSubject subject : subjectList) { if (subject != null && subject.getActionType() == actionType) { try{ subject.getSubject().onNext(content); }catch (Exception e){ e.printStackTrace(); } } } }catch (Exception e){ e.printStackTrace(); } } } },0); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/common/utils/SavePictureTask.java ================================================ package com.zero.magicshow.common.utils; import android.graphics.Bitmap; import android.os.AsyncTask; import com.zero.magicshow.common.entity.MagicShowResultEntity; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class SavePictureTask extends AsyncTask{ private OnPictureSaveListener onPictureSaveListener; private File file; public SavePictureTask(File file, OnPictureSaveListener listener){ this.onPictureSaveListener = listener; this.file = file; } @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected void onPostExecute(final MagicShowResultEntity result) { if(result != null){ if (onPictureSaveListener != null){ onPictureSaveListener.onSaved(result); } // BaseUtil.scanFile(result); } } @Override protected MagicShowResultEntity doInBackground(Bitmap... params) { if(file == null) return null; MagicShowResultEntity resultEntity = new MagicShowResultEntity(); resultEntity.setAngle(params[0].getHeight() > params[0].getWidth() ? 90 : 0); resultEntity.setFilePath(saveBitmap(params[0])); return resultEntity; } private String saveBitmap(Bitmap bitmap) { if (file.exists()) { file.delete(); } try { // Log.e("HongLi","bitmap degree:" + bitmap.getConfig()); FileOutputStream out = new FileOutputStream(file); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out); out.flush(); out.close(); bitmap.recycle(); return file.toString(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; } public interface OnPictureSaveListener{ void onSaved(MagicShowResultEntity resultEntity); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/common/utils/TextureRotationUtil.java ================================================ /* * Copyright (C) 2012 CyberAgent * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.zero.magicshow.common.utils; public class TextureRotationUtil { public static final float TEXTURE_NO_ROTATION[] = { 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, }; public static final float TEXTURE_ROTATED_90[] = { 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, }; public static final float TEXTURE_ROTATED_180[] = { 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, }; public static final float TEXTURE_ROTATED_270[] = { 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, }; public static final float CUBE[] = { -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, }; private TextureRotationUtil() {} public static float[] getRotation(final Rotation rotation, final boolean flipHorizontal, final boolean flipVertical) { float[] rotatedTex; switch (rotation) { case ROTATION_90: rotatedTex = TEXTURE_ROTATED_90; break; case ROTATION_180: rotatedTex = TEXTURE_ROTATED_180; break; case ROTATION_270: rotatedTex = TEXTURE_ROTATED_270; break; case NORMAL: default: rotatedTex = TEXTURE_NO_ROTATION; break; } if (flipHorizontal) { rotatedTex = new float[]{ flip(rotatedTex[0]), rotatedTex[1], flip(rotatedTex[2]), rotatedTex[3], flip(rotatedTex[4]), rotatedTex[5], flip(rotatedTex[6]), rotatedTex[7], }; } if (flipVertical) { rotatedTex = new float[]{ rotatedTex[0], flip(rotatedTex[1]), rotatedTex[2], flip(rotatedTex[3]), rotatedTex[4], flip(rotatedTex[5]), rotatedTex[6], flip(rotatedTex[7]), }; } return rotatedTex; } private static float flip(final float i) { if (i == 0.0f) { return 1.0f; } return 0.0f; } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/common/utils/ZeroSubject.java ================================================ package com.zero.magicshow.common.utils; import rx.functions.Action1; import rx.subjects.Subject; /** * Created by hongli on 2017/8/31. */ public class ZeroSubject{ private int actionType; private Subject subject; private Action1 action; public ZeroSubject(Subject subject, int actionType, Action1 action) { this.actionType = actionType; this.subject = subject; this.action = action; } public int getActionType(){ return actionType; } public Subject getSubject(){ return subject; } public Action1 getAction() { return action; } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/MagicEngine.java ================================================ package com.zero.magicshow.core; import com.zero.magicshow.core.camera.CameraEngine; import com.zero.magicshow.core.filter.utils.MagicFilterType; import com.zero.magicshow.common.utils.SavePictureTask; import com.zero.magicshow.common.utils.MagicParams; import com.zero.magicshow.core.widget.MagicCameraView; import com.zero.magicshow.core.widget.MagicImageView; import com.zero.magicshow.common.base.MagicBaseView; import com.zero.zerolib.manager.PostManager; import java.io.File; /** * Created by why8222 on 2016/2/25. */ public class MagicEngine { private static MagicEngine magicEngine; private float skinSmoothLevel; private float whiteSkinLevel; public static MagicEngine getInstance(){ if(magicEngine == null) throw new NullPointerException("MagicEngine must be built first"); else return magicEngine; } private MagicEngine(Builder builder){ } public void setFilter(MagicFilterType type){ MagicParams.magicBaseView.setFilter(type); } public MagicFilterType getFilterType(){ return MagicParams.magicBaseView.getFilterType(); } public void adjustFilter(float rang, MagicFilterType type){ if(MagicParams.magicBaseView instanceof MagicImageView) { ((MagicImageView) MagicParams.magicBaseView).adjustFilter(rang,type); } } public void savePicture(File file, SavePictureTask.OnPictureSaveListener listener){ SavePictureTask savePictureTask = new SavePictureTask(file, listener); MagicParams.magicBaseView.savePicture(savePictureTask); } public void startRecord(){ if(MagicParams.magicBaseView instanceof MagicCameraView) ((MagicCameraView)MagicParams.magicBaseView).changeRecordingState(true); } public void stopRecord(){ if(MagicParams.magicBaseView instanceof MagicCameraView) ((MagicCameraView)MagicParams.magicBaseView).changeRecordingState(false); } public void setBeautyLevel(int level){ if(MagicParams.magicBaseView instanceof MagicCameraView && MagicParams.beautyLevel != level) { MagicParams.beautyLevel = level; ((MagicCameraView) MagicParams.magicBaseView).onBeautyLevelChanged(); } } public void initBeauty(){ if(MagicParams.magicBaseView instanceof MagicImageView) { PostManager.getInstance().postSlow(new Runnable() { @Override public void run() { ((MagicImageView) MagicParams.magicBaseView).initMagicBeautify(); } },0); } } public void uninitBeauty(){ if(MagicParams.magicBaseView instanceof MagicImageView) { PostManager.getInstance().postSlow(new Runnable() { @Override public void run() { ((MagicImageView) MagicParams.magicBaseView).uninitMagicBeautify(); } },0); } } public void setSkinSmooth(float level){ skinSmoothLevel = level; PostManager.getInstance().removeSlow(setSkinSmoothRun); PostManager.getInstance().postSlow(setSkinSmoothRun,0); } public void setWhiteSkin(float level){ whiteSkinLevel = level; PostManager.getInstance().removeSlow(setWhiteSkinRun); PostManager.getInstance().postSlow(setWhiteSkinRun,0); } public void commitImage(){ if(MagicParams.magicBaseView instanceof MagicImageView) { ((MagicImageView) MagicParams.magicBaseView).commit(); } } public void restoreImage(){ if(MagicParams.magicBaseView instanceof MagicImageView) { ((MagicImageView) MagicParams.magicBaseView).restore(); } } private Runnable setSkinSmoothRun = new Runnable() { @Override public void run() { if(MagicParams.magicBaseView instanceof MagicImageView) { ((MagicImageView) MagicParams.magicBaseView).setSkinSmooth(skinSmoothLevel); } } }; private Runnable setWhiteSkinRun = new Runnable() { @Override public void run() { if(MagicParams.magicBaseView instanceof MagicImageView) { ((MagicImageView) MagicParams.magicBaseView).setWhiteSkin(whiteSkinLevel); } } }; public void switchCamera(){ CameraEngine.switchCamera(); } public static class Builder{ public MagicEngine build(MagicBaseView magicBaseView) { MagicParams.context = magicBaseView.getContext(); MagicParams.magicBaseView = magicBaseView; magicEngine = new MagicEngine(this); return magicEngine; } public Builder setVideoPath(String path){ MagicParams.videoPath = path; return this; } public Builder setVideoName(String name){ MagicParams.videoName = name; return this; } } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/beautify/MagicJni.java ================================================ package com.zero.magicshow.core.beautify; import android.graphics.Bitmap; import java.nio.ByteBuffer; /** * Created by why8222 on 2016/2/29. */ public class MagicJni { static{ System.loadLibrary("MagicJni"); } //初始化 public static native void jniInitMagicBeautify(ByteBuffer handler); public static native void jniUnInitMagicBeautify(); //局部均方差磨皮 public static native void jniStartSkinSmooth(float denoiseLevel); //log曲线美白 public static native void jniStartWhiteSkin(float whitenLevel); //Bitmap操作 public static native ByteBuffer jniStoreBitmapData(Bitmap bitmap); public static native void jniFreeBitmapData(ByteBuffer handler); public static native Bitmap jniGetBitmapFromStoredBitmapData(ByteBuffer handler); } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/camera/CameraEngine.java ================================================ package com.zero.magicshow.core.camera; import android.app.Activity; import android.graphics.PixelFormat; import android.graphics.SurfaceTexture; import android.hardware.Camera; import android.hardware.Camera.CameraInfo; import android.hardware.Camera.Parameters; import android.hardware.Camera.Size; import android.util.Log; import android.view.Surface; import android.view.SurfaceView; import com.zero.magicshow.common.config.CameraConfig; import com.zero.magicshow.common.utils.CameraParamUtil; import com.zero.magicshow.core.camera.utils.CameraUtils; import java.io.IOException; import java.util.List; import static android.hardware.Camera.Parameters.WHITE_BALANCE_AUTO; public class CameraEngine { private static Camera camera = null; public static int cameraID = 0; private static SurfaceTexture surfaceTexture; private static SurfaceView surfaceView; public static Camera getCamera(){ return camera; } public static boolean openCamera(){ if(camera == null){ try{ camera = Camera.open(cameraID); setDefaultParameters(); return true; }catch(RuntimeException e){ return false; } } return false; } public static boolean openCamera(int id){ if(camera == null){ try{ camera = Camera.open(id); cameraID = id; setDefaultParameters(); return true; }catch(RuntimeException e){ return false; } } return false; } public static void releaseCamera(boolean isDestory){ if(camera != null){ camera.setPreviewCallback(null); camera.stopPreview(); camera.release(); if(isDestory){ cameraID = 0; } // cameraID = 0; camera = null; } } public void resumeCamera(){ openCamera(); } public void setParameters(Parameters parameters){ camera.setParameters(parameters); } public Parameters getParameters(){ if(camera != null) camera.getParameters(); return null; } public static void switchCamera(){ releaseCamera(false); cameraID = cameraID == 0 ? 1 : 0; openCamera(cameraID); startPreview(surfaceTexture); } private static void setDefaultParameters(){ Parameters parameters = camera.getParameters(); // if (parameters.getSupportedFocusModes().contains( // Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) { // parameters.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); // } //增加对聚焦模式的判断 List focusModesList = parameters.getSupportedFocusModes(); if (CameraParamUtil.getInstance().isSupportedFocusMode(focusModesList, Camera.Parameters.FOCUS_MODE_AUTO)) { parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); }else if(CameraParamUtil.getInstance().isSupportedFocusMode(focusModesList, Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)){ parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO); } Size previewSize = CameraUtils.getLargePreviewSize(camera); parameters.setPreviewSize(previewSize.width, previewSize.height); // Size pictureSize = CameraUtils.getLargePictureSize(camera); parameters.setPictureSize(CameraConfig.pictureWidth, CameraConfig.pictureHeight); // parameters.setRotation(cameraID == 0 ? 90 : 270); parameters.setPictureFormat(PixelFormat.JPEG);//设置拍照后存储的图片格式 parameters.setWhiteBalance(WHITE_BALANCE_AUTO); //设置曝光值为1,酒吧比较暗,增加曝光 parameters.setExposureCompensation(1); parameters.setSceneMode(Camera.Parameters.SCENE_MODE_AUTO); parameters.setAntibanding(Camera.Parameters.ANTIBANDING_AUTO); camera.setParameters(parameters); camera.autoFocus(autoFocusCallback); Camera.CameraInfo info = new Camera.CameraInfo(); Camera.getCameraInfo(cameraID, info); int degrees = 90;//getDisplayRotation(activity); int result; if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { result = (info.orientation + degrees) % 360; result = (360 - result) % 360; // compensate the mirror } else { // back-facing result = (info.orientation - degrees + 360) % 360; } camera.setDisplayOrientation(result); } public static int getDisplayRotation(Activity activity) { int rotation = activity.getWindowManager().getDefaultDisplay().getRotation(); switch (rotation) { case Surface.ROTATION_0: return 0; case Surface.ROTATION_90: return 90; case Surface.ROTATION_180: return 180; case Surface.ROTATION_270: return 270; } return 0; } private static Camera.AutoFocusCallback autoFocusCallback = new Camera.AutoFocusCallback() { @Override public void onAutoFocus(boolean success, Camera camera) { if (success) { camera.cancelAutoFocus(); onFocusEnd(); } } }; public static void onFocusEnd() { // mFoucsView.setVisibility(INVISIBLE); } private static Size getPreviewSize(){ return camera.getParameters().getPreviewSize(); } private static Size getPictureSize(){ return camera.getParameters().getPictureSize(); } public static void startPreview(SurfaceTexture surfaceTexture){ if(camera != null) try { camera.setPreviewTexture(surfaceTexture); CameraEngine.surfaceTexture = surfaceTexture; camera.startPreview(); } catch (IOException e) { e.printStackTrace(); } } public static void startPreview(){ if(camera != null) camera.startPreview(); } public static void stopPreview(){ camera.stopPreview(); } public static void setRotation(int rotation){ Camera.Parameters params = camera.getParameters(); params.setRotation(rotation); camera.setParameters(params); } public static void takePicture(Camera.ShutterCallback shutterCallback, Camera.PictureCallback rawCallback, Camera.PictureCallback jpegCallback){ camera.takePicture(shutterCallback, rawCallback, jpegCallback); } public static com.zero.magicshow.core.camera.utils.CameraInfo getCameraInfo(){ if(null == camera){ return null; } com.zero.magicshow.core.camera.utils.CameraInfo info = new com.zero.magicshow.core.camera.utils.CameraInfo(); Size size = getPreviewSize(); CameraInfo cameraInfo = new CameraInfo(); Camera.getCameraInfo(cameraID, cameraInfo); info.previewWidth = size.width; info.previewHeight = size.height; info.orientation = cameraInfo.orientation; info.isFront = cameraID == 1 ? true : false; size = getPictureSize(); info.pictureWidth = CameraConfig.pictureWidth; info.pictureHeight = CameraConfig.pictureHeight; Log.e("HongLi","size.width:" + size.width + ";size.height:" + size.height + ";info.previewWidth:" + info.previewWidth + ";info.previewHeight:" + info.previewHeight + ";isFront:" + info.isFront); return info; } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/camera/utils/CameraInfo.java ================================================ package com.zero.magicshow.core.camera.utils; /** * Created by why8222 on 2016/2/25. */ public class CameraInfo { public int previewWidth; public int previewHeight; public int orientation; public boolean isFront; public int pictureWidth; public int pictureHeight; } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/camera/utils/CameraUtils.java ================================================ package com.zero.magicshow.core.camera.utils; import android.hardware.Camera; import java.util.List; /** * Created by why8222 on 2016/2/25. */ public class CameraUtils { public static Camera.Size getLargePictureSize(Camera camera){ if(camera != null){ List sizes = camera.getParameters().getSupportedPictureSizes(); Camera.Size temp = sizes.get(0); for(int i = 1;i < sizes.size();i ++){ float scale = (float)(sizes.get(i).height) / sizes.get(i).width; if(temp.width < sizes.get(i).width && scale < 0.6f && scale > 0.5f) temp = sizes.get(i); } return temp; } return null; } public static Camera.Size getLargePreviewSize(Camera camera){ if(camera != null){ List sizes = camera.getParameters().getSupportedPreviewSizes(); Camera.Size temp = sizes.get(0); for(int i = 1;i < sizes.size();i ++){ if(temp.width < sizes.get(i).width) temp = sizes.get(i); } return temp; } return null; } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/encoder/gles/EglCore.java ================================================ /* * Copyright 2013 Google Inc. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.zero.magicshow.core.encoder.gles; import android.graphics.SurfaceTexture; import android.opengl.EGL14; import android.opengl.EGLConfig; import android.opengl.EGLContext; import android.opengl.EGLDisplay; import android.opengl.EGLExt; import android.opengl.EGLSurface; import android.util.Log; import android.view.Surface; /** * Core EGL state (display, context, config). *

* The EGLContext must only be attached to one thread at a time. This class is not thread-safe. */ public final class EglCore { private static final String TAG = "EglCore"; /** * Constructor flag: surface must be recordable. This discourages EGL from using a * pixel format that cannot be converted efficiently to something usable by the video * encoder. */ public static final int FLAG_RECORDABLE = 0x01; /** * Constructor flag: ask for GLES3, fall back to GLES2 if not available. Without this * flag, GLES2 is used. */ public static final int FLAG_TRY_GLES3 = 0x02; // Android-specific extension. private static final int EGL_RECORDABLE_ANDROID = 0x3142; private EGLDisplay mEGLDisplay = EGL14.EGL_NO_DISPLAY; private EGLContext mEGLContext = EGL14.EGL_NO_CONTEXT; private EGLConfig mEGLConfig = null; private int mGlVersion = -1; /** * Prepares EGL display and context. *

* Equivalent to EglCore(null, 0). */ public EglCore() { this(null, 0); } /** * Prepares EGL display and context. *

* @param sharedContext The context to share, or null if sharing is not desired. * @param flags Configuration bit flags, e.g. FLAG_RECORDABLE. */ public EglCore(EGLContext sharedContext, int flags) { if (mEGLDisplay != EGL14.EGL_NO_DISPLAY) { throw new RuntimeException("EGL already set up"); } if (sharedContext == null) { sharedContext = EGL14.EGL_NO_CONTEXT; } mEGLDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY); if (mEGLDisplay == EGL14.EGL_NO_DISPLAY) { throw new RuntimeException("unable to get EGL14 display"); } int[] version = new int[2]; if (!EGL14.eglInitialize(mEGLDisplay, version, 0, version, 1)) { mEGLDisplay = null; throw new RuntimeException("unable to initialize EGL14"); } // Try to get a GLES3 context, if requested. if ((flags & FLAG_TRY_GLES3) != 0) { //Log.d(TAG, "Trying GLES 3"); EGLConfig config = getConfig(flags, 3); if (config != null) { int[] attrib3_list = { EGL14.EGL_CONTEXT_CLIENT_VERSION, 3, EGL14.EGL_NONE }; EGLContext context = EGL14.eglCreateContext(mEGLDisplay, config, sharedContext, attrib3_list, 0); if (EGL14.eglGetError() == EGL14.EGL_SUCCESS) { //Log.d(TAG, "Got GLES 3 config"); mEGLConfig = config; mEGLContext = context; mGlVersion = 3; } } } if (mEGLContext == EGL14.EGL_NO_CONTEXT) { // GLES 2 only, or GLES 3 attempt failed //Log.d(TAG, "Trying GLES 2"); EGLConfig config = getConfig(flags, 2); if (config == null) { throw new RuntimeException("Unable to find a suitable EGLConfig"); } int[] attrib2_list = { EGL14.EGL_CONTEXT_CLIENT_VERSION, 2, EGL14.EGL_NONE }; EGLContext context = EGL14.eglCreateContext(mEGLDisplay, config, sharedContext, attrib2_list, 0); checkEglError("eglCreateContext"); mEGLConfig = config; mEGLContext = context; mGlVersion = 2; } // Confirm with query. int[] values = new int[1]; EGL14.eglQueryContext(mEGLDisplay, mEGLContext, EGL14.EGL_CONTEXT_CLIENT_VERSION, values, 0); Log.d(TAG, "EGLContext created, client version " + values[0]); } /** * Finds a suitable EGLConfig. * * @param flags Bit flags from constructor. * @param version Must be 2 or 3. */ private EGLConfig getConfig(int flags, int version) { int renderableType = EGL14.EGL_OPENGL_ES2_BIT; if (version >= 3) { renderableType |= EGLExt.EGL_OPENGL_ES3_BIT_KHR; } // The actual surface is generally RGBA or RGBX, so situationally omitting alpha // doesn't really help. It can also lead to a huge performance hit on glReadPixels() // when reading into a GL_RGBA buffer. int[] attribList = { EGL14.EGL_RED_SIZE, 8, EGL14.EGL_GREEN_SIZE, 8, EGL14.EGL_BLUE_SIZE, 8, EGL14.EGL_ALPHA_SIZE, 8, //EGL14.EGL_DEPTH_SIZE, 16, //EGL14.EGL_STENCIL_SIZE, 8, EGL14.EGL_RENDERABLE_TYPE, renderableType, EGL14.EGL_NONE, 0, // placeholder for recordable [@-3] EGL14.EGL_NONE }; if ((flags & FLAG_RECORDABLE) != 0) { attribList[attribList.length - 3] = EGL_RECORDABLE_ANDROID; attribList[attribList.length - 2] = 1; } EGLConfig[] configs = new EGLConfig[1]; int[] numConfigs = new int[1]; if (!EGL14.eglChooseConfig(mEGLDisplay, attribList, 0, configs, 0, configs.length, numConfigs, 0)) { Log.w(TAG, "unable to find RGB8888 / " + version + " EGLConfig"); return null; } return configs[0]; } /** * Discards all resources held by this class, notably the EGL context. This must be * called from the thread where the context was created. *

* On completion, no context will be current. */ public void release() { if (mEGLDisplay != EGL14.EGL_NO_DISPLAY) { // Android is unusual in that it uses a reference-counted EGLDisplay. So for // every eglInitialize() we need an eglTerminate(). EGL14.eglMakeCurrent(mEGLDisplay, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_CONTEXT); EGL14.eglDestroyContext(mEGLDisplay, mEGLContext); EGL14.eglReleaseThread(); EGL14.eglTerminate(mEGLDisplay); } mEGLDisplay = EGL14.EGL_NO_DISPLAY; mEGLContext = EGL14.EGL_NO_CONTEXT; mEGLConfig = null; } @Override protected void finalize() throws Throwable { try { if (mEGLDisplay != EGL14.EGL_NO_DISPLAY) { // We're limited here -- finalizers don't run on the thread that holds // the EGL state, so if a surface or context is still current on another // thread we can't fully release it here. Exceptions thrown from here // are quietly discarded. Complain in the log file. Log.w(TAG, "WARNING: EglCore was not explicitly released -- state may be leaked"); release(); } } finally { super.finalize(); } } /** * Destroys the specified surface. Note the EGLSurface won't actually be destroyed if it's * still current in a context. */ public void releaseSurface(EGLSurface eglSurface) { EGL14.eglDestroySurface(mEGLDisplay, eglSurface); } /** * Creates an EGL surface associated with a Surface. *

* If this is destined for MediaCodec, the EGLConfig should have the "recordable" attribute. */ public EGLSurface createWindowSurface(Object surface) { if (!(surface instanceof Surface) && !(surface instanceof SurfaceTexture)) { throw new RuntimeException("invalid surface: " + surface); } // Create a window surface, and attach it to the Surface we received. int[] surfaceAttribs = { EGL14.EGL_NONE }; EGLSurface eglSurface = EGL14.eglCreateWindowSurface(mEGLDisplay, mEGLConfig, surface, surfaceAttribs, 0); checkEglError("eglCreateWindowSurface"); if (eglSurface == null) { throw new RuntimeException("surface was null"); } return eglSurface; } /** * Creates an EGL surface associated with an offscreen buffer. */ public EGLSurface createOffscreenSurface(int width, int height) { int[] surfaceAttribs = { EGL14.EGL_WIDTH, width, EGL14.EGL_HEIGHT, height, EGL14.EGL_NONE }; EGLSurface eglSurface = EGL14.eglCreatePbufferSurface(mEGLDisplay, mEGLConfig, surfaceAttribs, 0); checkEglError("eglCreatePbufferSurface"); if (eglSurface == null) { throw new RuntimeException("surface was null"); } return eglSurface; } /** * Makes our EGL context current, using the supplied surface for both "draw" and "read". */ public void makeCurrent(EGLSurface eglSurface) { if (mEGLDisplay == EGL14.EGL_NO_DISPLAY) { // called makeCurrent() before create? Log.d(TAG, "NOTE: makeCurrent w/o display"); } if (!EGL14.eglMakeCurrent(mEGLDisplay, eglSurface, eglSurface, mEGLContext)) { throw new RuntimeException("eglMakeCurrent failed"); } } /** * Makes our EGL context current, using the supplied "draw" and "read" surfaces. */ public void makeCurrent(EGLSurface drawSurface, EGLSurface readSurface) { if (mEGLDisplay == EGL14.EGL_NO_DISPLAY) { // called makeCurrent() before create? Log.d(TAG, "NOTE: makeCurrent w/o display"); } if (!EGL14.eglMakeCurrent(mEGLDisplay, drawSurface, readSurface, mEGLContext)) { throw new RuntimeException("eglMakeCurrent(draw,read) failed"); } } /** * Makes no context current. */ public void makeNothingCurrent() { if (!EGL14.eglMakeCurrent(mEGLDisplay, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_CONTEXT)) { throw new RuntimeException("eglMakeCurrent failed"); } } /** * Calls eglSwapBuffers. Use this to "publish" the current frame. * * @return false on failure */ public boolean swapBuffers(EGLSurface eglSurface) { return EGL14.eglSwapBuffers(mEGLDisplay, eglSurface); } /** * Sends the presentation time stamp to EGL. Time is expressed in nanoseconds. */ public void setPresentationTime(EGLSurface eglSurface, long nsecs) { EGLExt.eglPresentationTimeANDROID(mEGLDisplay, eglSurface, nsecs); } /** * Returns true if our context and the specified surface are current. */ public boolean isCurrent(EGLSurface eglSurface) { return mEGLContext.equals(EGL14.eglGetCurrentContext()) && eglSurface.equals(EGL14.eglGetCurrentSurface(EGL14.EGL_DRAW)); } /** * Performs a simple surface query. */ public int querySurface(EGLSurface eglSurface, int what) { int[] value = new int[1]; EGL14.eglQuerySurface(mEGLDisplay, eglSurface, what, value, 0); return value[0]; } /** * Queries a string value. */ public String queryString(int what) { return EGL14.eglQueryString(mEGLDisplay, what); } /** * Returns the GLES version this context is configured for (currently 2 or 3). */ public int getGlVersion() { return mGlVersion; } /** * Writes the current display, context, and surface to the log. */ public static void logCurrent(String msg) { EGLDisplay display; EGLContext context; EGLSurface surface; display = EGL14.eglGetCurrentDisplay(); context = EGL14.eglGetCurrentContext(); surface = EGL14.eglGetCurrentSurface(EGL14.EGL_DRAW); Log.i(TAG, "Current EGL (" + msg + "): display=" + display + ", context=" + context + ", surface=" + surface); } /** * Checks for EGL errors. Throws an exception if an error has been raised. */ private void checkEglError(String msg) { int error; if ((error = EGL14.eglGetError()) != EGL14.EGL_SUCCESS) { throw new RuntimeException(msg + ": EGL error: 0x" + Integer.toHexString(error)); } } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/encoder/gles/EglSurfaceBase.java ================================================ /* * Copyright 2013 Google Inc. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.zero.magicshow.core.encoder.gles; import android.graphics.Bitmap; import android.opengl.EGL14; import android.opengl.EGLSurface; import android.opengl.GLES20; import android.util.Log; import com.zero.magicshow.common.utils.OpenGlUtils; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.nio.IntBuffer; /** * Common base class for EGL surfaces. *

* There can be multiple surfaces associated with a single context. */ public class EglSurfaceBase { protected static final String TAG = "EglSurfaceBase"; // EglCore object we're associated with. It may be associated with multiple surfaces. protected EglCore mEglCore; private EGLSurface mEGLSurface = EGL14.EGL_NO_SURFACE; protected int mWidth = -1; protected int mHeight = -1; protected EglSurfaceBase(EglCore eglCore) { mEglCore = eglCore; } /** * Creates a window surface. *

* @param surface May be a Surface or SurfaceTexture. */ public void createWindowSurface(Object surface) { if (mEGLSurface != EGL14.EGL_NO_SURFACE) { throw new IllegalStateException("surface already created"); } mEGLSurface = mEglCore.createWindowSurface(surface); // Don't cache width/height here, because the size of the underlying surface can change // out from under us (see e.g. HardwareScalerActivity). //mWidth = mEglCore.querySurface(mEGLSurface, EGL14.EGL_WIDTH); //mHeight = mEglCore.querySurface(mEGLSurface, EGL14.EGL_HEIGHT); } /** * Creates an off-screen surface. */ public void createOffscreenSurface(int width, int height) { if (mEGLSurface != EGL14.EGL_NO_SURFACE) { throw new IllegalStateException("surface already created"); } mEGLSurface = mEglCore.createOffscreenSurface(width, height); mWidth = width; mHeight = height; } /** * Returns the surface's width, in pixels. *

* If this is called on a window surface, and the underlying surface is in the process * of changing size, we may not see the new size right away (e.g. in the "surfaceChanged" * callback). The size should match after the next buffer swap. */ public int getWidth() { if (mWidth < 0) { return mEglCore.querySurface(mEGLSurface, EGL14.EGL_WIDTH); } else { return mWidth; } } /** * Returns the surface's height, in pixels. */ public int getHeight() { if (mHeight < 0) { return mEglCore.querySurface(mEGLSurface, EGL14.EGL_HEIGHT); } else { return mHeight; } } /** * Release the EGL surface. */ public void releaseEglSurface() { mEglCore.releaseSurface(mEGLSurface); mEGLSurface = EGL14.EGL_NO_SURFACE; mWidth = mHeight = -1; } /** * Makes our EGL context and surface current. */ public void makeCurrent() { mEglCore.makeCurrent(mEGLSurface); } /** * Makes our EGL context and surface current for drawing, using the supplied surface * for reading. */ public void makeCurrentReadFrom(EglSurfaceBase readSurface) { mEglCore.makeCurrent(mEGLSurface, readSurface.mEGLSurface); } /** * Calls eglSwapBuffers. Use this to "publish" the current frame. * * @return false on failure */ public boolean swapBuffers() { boolean result = mEglCore.swapBuffers(mEGLSurface); if (!result) { Log.d(TAG, "WARNING: swapBuffers() failed"); } return result; } /** * Sends the presentation time stamp to EGL. * * @param nsecs Timestamp, in nanoseconds. */ public void setPresentationTime(long nsecs) { mEglCore.setPresentationTime(mEGLSurface, nsecs); } /** * Saves the EGL surface to a file. *

* Expects that this object's EGL surface is current. */ public void saveFrame(File file) throws IOException { if (!mEglCore.isCurrent(mEGLSurface)) { throw new RuntimeException("Expected EGL context/surface is not current"); } // glReadPixels fills in a "direct" ByteBuffer with what is essentially big-endian RGBA // data (i.e. a byte of red, followed by a byte of green...). While the Bitmap // constructor that takes an int[] wants little-endian ARGB (blue/red swapped), the // Bitmap "copy pixels" method wants the same format GL provides. // // Ideally we'd have some way to re-use the ByteBuffer, especially if we're calling // here often. // // Making this even more interesting is the upside-down nature of GL, which means // our output will look upside down relative to what appears on screen if the // typical GL conventions are used. String filename = file.toString(); int width = getWidth(); int height = getHeight(); IntBuffer ib = IntBuffer.allocate(width * height); GLES20.glReadPixels(0, 0, width, height, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, ib); OpenGlUtils.checkGlError("glReadPixels"); BufferedOutputStream bos = null; try { bos = new BufferedOutputStream(new FileOutputStream(filename)); Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); bmp.copyPixelsFromBuffer(IntBuffer.wrap(ib.array())); bmp.compress(Bitmap.CompressFormat.PNG, 90, bos); bmp.recycle(); } finally { if (bos != null) bos.close(); } Log.d(TAG, "Saved " + width + "x" + height + " frame as '" + filename + "'"); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/encoder/video/TextureMovieEncoder.java ================================================ /* * Copyright 2013 Google Inc. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.zero.magicshow.core.encoder.video; import java.io.File; import java.io.IOException; import java.lang.ref.WeakReference; import java.nio.FloatBuffer; import android.graphics.SurfaceTexture; import android.opengl.EGLContext; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.util.Log; import com.zero.magicshow.core.camera.utils.CameraInfo; import com.zero.magicshow.core.filter.base.MagicCameraInputFilter; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.core.filter.utils.MagicFilterFactory; import com.zero.magicshow.core.filter.utils.MagicFilterType; import com.zero.magicshow.core.encoder.gles.EglCore; /** * Encode a movie from frames rendered from an external texture image. *

* The object wraps an encoder running on a dedicated thread. The various control messages * may be sent from arbitrary threads (typically the app UI thread). The encoder thread * manages both sides of the encoder (feeding and draining); the only external input is * the GL texture. *

* The design is complicated slightly by the need to create an EGL context that shares state * with a view that gets restarted if (say) the device orientation changes. When the view * in question is a GLSurfaceView, we don't have full control over the EGL context creation * on that side, so we have to bend a bit backwards here. *

* To use: *

    *
  • create TextureMovieEncoder object *
  • create an EncoderConfig *
  • call TextureMovieEncoder#startRecording() with the config *
  • call TextureMovieEncoder#setTextureId() with the texture object that receives frames *
  • for each frame, after latching it with SurfaceTexture#updateTexImage(), * call TextureMovieEncoder#frameAvailable(). *
* * TODO: tweak the API (esp. textureId) so it's less awkward for simple use cases. */ public class TextureMovieEncoder implements Runnable { private static final String TAG = ""; private static final boolean VERBOSE = false; private static final int MSG_START_RECORDING = 0; private static final int MSG_STOP_RECORDING = 1; private static final int MSG_FRAME_AVAILABLE = 2; private static final int MSG_SET_TEXTURE_ID = 3; private static final int MSG_UPDATE_SHARED_CONTEXT = 4; private static final int MSG_QUIT = 5; // ----- accessed exclusively by encoder thread ----- private WindowSurface mInputWindowSurface; private EglCore mEglCore; private MagicCameraInputFilter mInput; private int mTextureId; private VideoEncoderCore mVideoEncoder; // ----- accessed by multiple threads ----- private volatile EncoderHandler mHandler; private Object mReadyFence = new Object(); // guards ready/running private boolean mReady; private boolean mRunning; private GPUImageFilter filter; private FloatBuffer gLCubeBuffer; private FloatBuffer gLTextureBuffer; public TextureMovieEncoder() { } /** * Encoder configuration. *

* Object is immutable, which means we can safely pass it between threads without * explicit synchronization (and don't need to worry about it getting tweaked out from * under us). *

* TODO: make frame rate and iframe interval configurable? Maybe use builder pattern * with reasonable defaults for those and bit rate. */ public static class EncoderConfig { final File mOutputFile; final int mWidth; final int mHeight; final int mBitRate; final EGLContext mEglContext; public EncoderConfig(File outputFile, int width, int height, int bitRate, EGLContext sharedEglContext, CameraInfo info) { mOutputFile = outputFile; mWidth = width; mHeight = height; mBitRate = bitRate; mEglContext = sharedEglContext; } @Override public String toString() { return "EncoderConfig: " + mWidth + "x" + mHeight + " @" + mBitRate + " to '" + mOutputFile.toString() + "' ctxt=" + mEglContext; } } /** * Tells the video recorder to start recording. (Call from non-encoder thread.) *

* Creates a new thread, which will create an encoder using the provided configuration. *

* Returns after the recorder thread has started and is ready to accept Messages. The * encoder may not yet be fully configured. */ public void startRecording(EncoderConfig config) { Log.d(TAG, "Encoder: startRecording()"); synchronized (mReadyFence) { if (mRunning) { Log.w(TAG, "Encoder thread already running"); return; } mRunning = true; new Thread(this, "TextureMovieEncoder").start(); while (!mReady) { try { mReadyFence.wait(); } catch (InterruptedException ie) { // ignore } } } mHandler.sendMessage(mHandler.obtainMessage(MSG_START_RECORDING, config)); } /** * Tells the video recorder to stop recording. (Call from non-encoder thread.) *

* Returns immediately; the encoder/muxer may not yet be finished creating the movie. *

* TODO: have the encoder thread invoke a callback on the UI thread just before it shuts down * so we can provide reasonable status UI (and let the caller know that movie encoding * has completed). */ public void stopRecording() { mHandler.sendMessage(mHandler.obtainMessage(MSG_STOP_RECORDING)); mHandler.sendMessage(mHandler.obtainMessage(MSG_QUIT)); // We don't know when these will actually finish (or even start). We don't want to // delay the UI thread though, so we return immediately. } /** * Returns true if recording has been started. */ public boolean isRecording() { synchronized (mReadyFence) { return mRunning; } } /** * Tells the video recorder to refresh its EGL surface. (Call from non-encoder thread.) */ public void updateSharedContext(EGLContext sharedContext) { mHandler.sendMessage(mHandler.obtainMessage(MSG_UPDATE_SHARED_CONTEXT, sharedContext)); } /** * Tells the video recorder that a new frame is available. (Call from non-encoder thread.) *

* This function sends a message and returns immediately. This isn't sufficient -- we * don't want the caller to latch a new frame until we're done with this one -- but we * can get away with it so long as the input frame rate is reasonable and the encoder * thread doesn't stall. *

* TODO: either block here until the texture has been rendered onto the encoder surface, * or have a separate "block if still busy" method that the caller can execute immediately * before it calls updateTexImage(). The latter is preferred because we don't want to * stall the caller while this thread does work. */ public void frameAvailable(SurfaceTexture st) { synchronized (mReadyFence) { if (!mReady) { return; } } float[] transform = new float[16]; // TODO - avoid alloc every frame st.getTransformMatrix(transform); long timestamp = st.getTimestamp(); if (timestamp == 0) { // Seeing this after device is toggled off/on with power button. The // first frame back has a zero timestamp. // // MPEG4Writer thinks this is cause to abort() in native code, so it's very // important that we just ignore the frame. Log.w(TAG, "HEY: got SurfaceTexture with timestamp of zero"); return; } mHandler.sendMessage(mHandler.obtainMessage(MSG_FRAME_AVAILABLE, (int) (timestamp >> 32), (int) timestamp, transform)); } /** * Tells the video recorder what texture name to use. This is the external texture that * we're receiving camera previews in. (Call from non-encoder thread.) *

* TODO: do something less clumsy */ public void setTextureId(int id) { synchronized (mReadyFence) { if (!mReady) { return; } } mHandler.sendMessage(mHandler.obtainMessage(MSG_SET_TEXTURE_ID, id, 0, null)); } /** * Encoder thread entry point. Establishes Looper/Handler and waits for messages. *

* @see Thread#run() */ @Override public void run() { // Establish a Looper for this thread, and define a Handler for it. Looper.prepare(); synchronized (mReadyFence) { mHandler = new EncoderHandler(this); mReady = true; mReadyFence.notify(); } Looper.loop(); Log.d(TAG, "Encoder thread exiting"); synchronized (mReadyFence) { mReady = mRunning = false; mHandler = null; } } /** * Handles encoder state change requests. The handler is created on the encoder thread. */ private static class EncoderHandler extends Handler { private WeakReference mWeakEncoder; public EncoderHandler(TextureMovieEncoder encoder) { mWeakEncoder = new WeakReference(encoder); } @Override // runs on encoder thread public void handleMessage(Message inputMessage) { int what = inputMessage.what; Object obj = inputMessage.obj; TextureMovieEncoder encoder = mWeakEncoder.get(); if (encoder == null) { Log.w(TAG, "EncoderHandler.handleMessage: encoder is null"); return; } switch (what) { case MSG_START_RECORDING: encoder.handleStartRecording((EncoderConfig) obj); break; case MSG_STOP_RECORDING: encoder.handleStopRecording(); break; case MSG_FRAME_AVAILABLE: long timestamp = (((long) inputMessage.arg1) << 32) | (((long) inputMessage.arg2) & 0xffffffffL); encoder.handleFrameAvailable((float[]) obj, timestamp); break; case MSG_SET_TEXTURE_ID: encoder.handleSetTexture(inputMessage.arg1); break; case MSG_UPDATE_SHARED_CONTEXT: encoder.handleUpdateSharedContext((EGLContext) inputMessage.obj); break; case MSG_QUIT: Looper.myLooper().quit(); break; default: throw new RuntimeException("Unhandled msg what=" + what); } } } /** * Starts recording. */ private void handleStartRecording(EncoderConfig config) { Log.d(TAG, "handleStartRecording " + config); prepareEncoder(config.mEglContext, config.mWidth, config.mHeight, config.mBitRate, config.mOutputFile); } /** * Handles notification of an available frame. *

* The texture is rendered onto the encoder's input surface, along with a moving * box (just because we can). *

* @param transform The texture transform, from SurfaceTexture. * @param timestampNanos The frame's timestamp, from SurfaceTexture. */ private void handleFrameAvailable(float[] transform, long timestampNanos) { if (VERBOSE) Log.d(TAG, "handleFrameAvailable tr=" + transform); mVideoEncoder.drainEncoder(false); mInput.setTextureTransformMatrix(transform); if(filter == null) { mInput.onDrawFrame(mTextureId, gLCubeBuffer, gLTextureBuffer); }else { filter.onDrawFrame(mTextureId, gLCubeBuffer, gLTextureBuffer); } mInputWindowSurface.setPresentationTime(timestampNanos); mInputWindowSurface.swapBuffers(); } /** * Handles a request to stop encoding. */ private void handleStopRecording() { Log.d(TAG, "handleStopRecording"); mVideoEncoder.drainEncoder(true); releaseEncoder(); } /** * Sets the texture name that SurfaceTexture will use when frames are received. */ private void handleSetTexture(int id) { //Log.d(TAG, "handleSetTexture " + id); mTextureId = id; } /** * Tears down the EGL surface and context we've been using to feed the MediaCodec input * surface, and replaces it with a new one that shares with the new context. *

* This is useful if the old context we were sharing with went away (maybe a GLSurfaceView * that got torn down) and we need to hook up with the new one. */ private void handleUpdateSharedContext(EGLContext newSharedContext) { Log.d(TAG, "handleUpdatedSharedContext " + newSharedContext); // Release the EGLSurface and EGLContext. mInputWindowSurface.releaseEglSurface(); mInput.destroy(); mEglCore.release(); // Create a new EGLContext and recreate the window surface. mEglCore = new EglCore(newSharedContext, EglCore.FLAG_RECORDABLE); mInputWindowSurface.recreate(mEglCore); mInputWindowSurface.makeCurrent(); // Create new programs and such for the new context. mInput = new MagicCameraInputFilter(); mInput.init(); filter = MagicFilterFactory.initFilters(type); if(filter != null){ filter.init(); filter.onInputSizeChanged(mPreviewWidth, mPreviewHeight); filter.onDisplaySizeChanged(mVideoWidth, mVideoHeight); } } private void prepareEncoder(EGLContext sharedContext, int width, int height, int bitRate, File outputFile) { try { mVideoEncoder = new VideoEncoderCore(width, height, bitRate, outputFile); } catch (IOException ioe) { throw new RuntimeException(ioe); } mVideoWidth = width; mVideoHeight = height; mEglCore = new EglCore(sharedContext, EglCore.FLAG_RECORDABLE); mInputWindowSurface = new WindowSurface(mEglCore, mVideoEncoder.getInputSurface(), true); mInputWindowSurface.makeCurrent(); mInput = new MagicCameraInputFilter(); mInput.init(); filter = MagicFilterFactory.initFilters(type); if(filter != null){ filter.init(); filter.onInputSizeChanged(mPreviewWidth, mPreviewHeight); filter.onDisplaySizeChanged(mVideoWidth, mVideoHeight); } } private void releaseEncoder() { mVideoEncoder.release(); if (mInputWindowSurface != null) { mInputWindowSurface.release(); mInputWindowSurface = null; } if (mInput != null) { mInput.destroy(); mInput = null; } if (mEglCore != null) { mEglCore.release(); mEglCore = null; } if(filter != null){ filter.destroy(); filter = null; type = MagicFilterType.NONE; } } private MagicFilterType type = MagicFilterType.NONE; public void setFilter(MagicFilterType type) { this.type = type; } private int mPreviewWidth = -1; private int mPreviewHeight = -1; private int mVideoWidth = -1; private int mVideoHeight = -1; public void setPreviewSize(int width, int height){ mPreviewWidth = width; mPreviewHeight = height; } public void setTextureBuffer(FloatBuffer gLTextureBuffer) { this.gLTextureBuffer = gLTextureBuffer; } public void setCubeBuffer(FloatBuffer gLCubeBuffer) { this.gLCubeBuffer = gLCubeBuffer; } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/encoder/video/VideoEncoderCore.java ================================================ /* * Copyright 2014 Google Inc. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.zero.magicshow.core.encoder.video; import android.media.MediaCodec; import android.media.MediaCodecInfo; import android.media.MediaFormat; import android.media.MediaMuxer; import android.util.Log; import android.view.Surface; import java.io.File; import java.io.IOException; import java.nio.ByteBuffer; /** * This class wraps up the core components used for surface-input video encoding. *

* Once created, frames are fed to the input surface. Remember to provide the presentation * time stamp, and always call drainEncoder() before swapBuffers() to ensure that the * producer side doesn't get backed up. *

* This class is not thread-safe, with one exception: it is valid to use the input surface * on one thread, and drain the output on a different thread. */ public class VideoEncoderCore { private static final String TAG = "VideoEncoderCore"; private static final boolean VERBOSE = false; // TODO: these ought to be configurable as well private static final String MIME_TYPE = "video/avc"; // H.264 Advanced Video Coding private static final int FRAME_RATE = 30; // 30fps private static final int IFRAME_INTERVAL = 5; // 5 seconds between I-frames private Surface mInputSurface; private MediaMuxer mMuxer; private MediaCodec mEncoder; private MediaCodec.BufferInfo mBufferInfo; private int mTrackIndex; private boolean mMuxerStarted; /** * Configures encoder and muxer state, and prepares the input Surface. */ public VideoEncoderCore(int width, int height, int bitRate, File outputFile) throws IOException { mBufferInfo = new MediaCodec.BufferInfo(); MediaFormat format = MediaFormat.createVideoFormat(MIME_TYPE, width, height); // Set some properties. Failing to specify some of these can cause the MediaCodec // configure() call to throw an unhelpful exception. format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface); format.setInteger(MediaFormat.KEY_BIT_RATE, bitRate); format.setInteger(MediaFormat.KEY_FRAME_RATE, FRAME_RATE); format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, IFRAME_INTERVAL); if (VERBOSE) Log.d(TAG, "format: " + format); // Create a MediaCodec encoder, and configure it with our format. Get a Surface // we can use for input and wrap it with a class that handles the EGL work. mEncoder = MediaCodec.createEncoderByType(MIME_TYPE); mEncoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE); mInputSurface = mEncoder.createInputSurface(); mEncoder.start(); // Create a MediaMuxer. We can't add the video track and start() the muxer here, // because our MediaFormat doesn't have the Magic Goodies. These can only be // obtained from the encoder after it has started processing data. // // We're not actually interested in multiplexing audio. We just want to convert // the raw H.264 elementary stream we get from MediaCodec into a .mp4 file. mMuxer = new MediaMuxer(outputFile.toString(), MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4); mTrackIndex = -1; mMuxerStarted = false; } /** * Returns the encoder's input surface. */ public Surface getInputSurface() { return mInputSurface; } /** * Releases encoder resources. */ public void release() { if (VERBOSE) Log.d(TAG, "releasing encoder objects"); if (mEncoder != null) { mEncoder.stop(); mEncoder.release(); mEncoder = null; } if (mMuxer != null) { // TODO: stop() throws an exception if you haven't fed it any data. Keep track // of frames submitted, and don't call stop() if we haven't written anything. mMuxer.stop(); mMuxer.release(); mMuxer = null; } } /** * Extracts all pending data from the encoder and forwards it to the muxer. *

* If endOfStream is not set, this returns when there is no more data to drain. If it * is set, we send EOS to the encoder, and then iterate until we see EOS on the output. * Calling this with endOfStream set should be done once, right before stopping the muxer. *

* We're just using the muxer to get a .mp4 file (instead of a raw H.264 stream). We're * not recording audio. */ public void drainEncoder(boolean endOfStream) { final int TIMEOUT_USEC = 10000; if (VERBOSE) Log.d(TAG, "drainEncoder(" + endOfStream + ")"); if (endOfStream) { if (VERBOSE) Log.d(TAG, "sending EOS to encoder"); mEncoder.signalEndOfInputStream(); } ByteBuffer[] encoderOutputBuffers = mEncoder.getOutputBuffers(); while (true) { int encoderStatus = mEncoder.dequeueOutputBuffer(mBufferInfo, TIMEOUT_USEC); if (encoderStatus == MediaCodec.INFO_TRY_AGAIN_LATER) { // no output available yet if (!endOfStream) { break; // out of while } else { if (VERBOSE) Log.d(TAG, "no output available, spinning to await EOS"); } } else if (encoderStatus == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) { // not expected for an encoder encoderOutputBuffers = mEncoder.getOutputBuffers(); } else if (encoderStatus == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) { // should happen before receiving buffers, and should only happen once if (mMuxerStarted) { throw new RuntimeException("format changed twice"); } MediaFormat newFormat = mEncoder.getOutputFormat(); Log.d(TAG, "encoder output format changed: " + newFormat); // now that we have the Magic Goodies, start the muxer mTrackIndex = mMuxer.addTrack(newFormat); mMuxer.start(); mMuxerStarted = true; } else if (encoderStatus < 0) { Log.w(TAG, "unexpected result from encoder.dequeueOutputBuffer: " + encoderStatus); // let's ignore it } else { ByteBuffer encodedData = encoderOutputBuffers[encoderStatus]; if (encodedData == null) { throw new RuntimeException("encoderOutputBuffer " + encoderStatus + " was null"); } if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) { // The codec config data was pulled out and fed to the muxer when we got // the INFO_OUTPUT_FORMAT_CHANGED status. Ignore it. if (VERBOSE) Log.d(TAG, "ignoring BUFFER_FLAG_CODEC_CONFIG"); mBufferInfo.size = 0; } if (mBufferInfo.size != 0) { if (!mMuxerStarted) { throw new RuntimeException("muxer hasn't started"); } // adjust the ByteBuffer values to match BufferInfo (not needed?) encodedData.position(mBufferInfo.offset); encodedData.limit(mBufferInfo.offset + mBufferInfo.size); mMuxer.writeSampleData(mTrackIndex, encodedData, mBufferInfo); if (VERBOSE) { Log.d(TAG, "sent " + mBufferInfo.size + " bytes to muxer, ts=" + mBufferInfo.presentationTimeUs); } } mEncoder.releaseOutputBuffer(encoderStatus, false); if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) { if (!endOfStream) { Log.w(TAG, "reached end of stream unexpectedly"); } else { if (VERBOSE) Log.d(TAG, "end of stream reached"); } break; // out of while } } } } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/encoder/video/WindowSurface.java ================================================ /* * Copyright 2013 Google Inc. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.zero.magicshow.core.encoder.video; import android.graphics.SurfaceTexture; import android.view.Surface; import com.zero.magicshow.core.encoder.gles.EglCore; import com.zero.magicshow.core.encoder.gles.EglSurfaceBase; /** * Recordable EGL window surface. *

* It's good practice to explicitly release() the surface, preferably from a "finally" block. */ public class WindowSurface extends EglSurfaceBase { private Surface mSurface; private boolean mReleaseSurface; /** * Associates an EGL surface with the native window surface. *

* Set releaseSurface to true if you want the Surface to be released when release() is * called. This is convenient, but can interfere with framework classes that expect to * manage the Surface themselves (e.g. if you release a SurfaceView's Surface, the * surfaceDestroyed() callback won't fire). */ public WindowSurface(EglCore eglCore, Surface surface, boolean releaseSurface) { super(eglCore); createWindowSurface(surface); mSurface = surface; mReleaseSurface = releaseSurface; } /** * Associates an EGL surface with the SurfaceTexture. */ public WindowSurface(EglCore eglCore, SurfaceTexture surfaceTexture) { super(eglCore); createWindowSurface(surfaceTexture); } /** * Releases any resources associated with the EGL surface (and, if configured to do so, * with the Surface as well). *

* Does not require that the surface's EGL context be current. */ public void release() { releaseEglSurface(); if (mSurface != null) { if (mReleaseSurface) { mSurface.release(); } mSurface = null; } } /** * Recreate the EGLSurface, using the new EglBase. The caller should have already * freed the old EGLSurface with releaseEglSurface(). *

* This is useful when we want to update the EGLSurface associated with a Surface. * For example, if we want to share with a different EGLContext, which can only * be done by tearing down and recreating the context. (That's handled by the caller; * this just creates a new EGLSurface for the Surface we were handed earlier.) *

* If the previous EGLSurface isn't fully destroyed, e.g. it's still current on a * context somewhere, the create call will fail with complaints from the Surface * about already being connected. */ public void recreate(EglCore newEglCore) { if (mSurface == null) { throw new RuntimeException("not yet implemented for SurfaceTexture"); } mEglCore = newEglCore; // switch to new context createWindowSurface(mSurface); // create new surface } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/advanced/MagicAmaroFilter.java ================================================ package com.zero.magicshow.core.filter.advanced; import android.opengl.GLES20; import com.zero.magicshow.R; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.common.utils.MagicParams; import com.zero.magicshow.common.utils.OpenGlUtils; public class MagicAmaroFilter extends GPUImageFilter{ private int[] inputTextureHandles = {-1,-1,-1}; private int[] inputTextureUniformLocations = {-1,-1,-1}; private int mGLStrengthLocation; public MagicAmaroFilter(){ super(NO_FILTER_VERTEX_SHADER, OpenGlUtils.readShaderFromRawResource(R.raw.amaro)); } protected void onDestroy() { super.onDestroy(); GLES20.glDeleteTextures(inputTextureHandles.length, inputTextureHandles, 0); for(int i = 0; i < inputTextureHandles.length; i++) inputTextureHandles[i] = -1; } protected void onDrawArraysAfter(){ for(int i = 0; i < inputTextureHandles.length && inputTextureHandles[i] != OpenGlUtils.NO_TEXTURE; i++){ GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + (i+3)); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } } protected void onDrawArraysPre(){ for(int i = 0; i < inputTextureHandles.length && inputTextureHandles[i] != OpenGlUtils.NO_TEXTURE; i++){ GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + (i+3)); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, inputTextureHandles[i]); GLES20.glUniform1i(inputTextureUniformLocations[i], (i+3)); } } protected void onInit(){ super.onInit(); for(int i=0; i < inputTextureUniformLocations.length; i++) inputTextureUniformLocations[i] = GLES20.glGetUniformLocation(getProgram(), "inputImageTexture"+(2+i)); mGLStrengthLocation = GLES20.glGetUniformLocation(mGLProgId, "strength"); } protected void onInitialized(){ super.onInitialized(); setFloat(mGLStrengthLocation, 1.0f); runOnDraw(new Runnable(){ public void run(){ inputTextureHandles[0] = OpenGlUtils.loadTexture(MagicParams.context, "filter/brannan_blowout.png"); inputTextureHandles[1] = OpenGlUtils.loadTexture(MagicParams.context, "filter/overlaymap.png"); inputTextureHandles[2] = OpenGlUtils.loadTexture(MagicParams.context, "filter/amaromap.png"); } }); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/advanced/MagicAntiqueFilter.java ================================================ package com.zero.magicshow.core.filter.advanced; import android.opengl.GLES20; import com.zero.magicshow.R; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.common.utils.OpenGlUtils; import java.nio.ByteBuffer; public class MagicAntiqueFilter extends GPUImageFilter{ private int[] mToneCurveTexture = {-1}; private int mToneCurveTextureUniformLocation; public MagicAntiqueFilter(){ super(NO_FILTER_VERTEX_SHADER, OpenGlUtils.readShaderFromRawResource(R.raw.antique)); } protected void onDestroy(){ super.onDestroy(); GLES20.glDeleteTextures(1, mToneCurveTexture, 0); this.mToneCurveTexture[0] = -1; } protected void onDrawArraysAfter(){ if (this.mToneCurveTexture[0] != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE3); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } } protected void onDrawArraysPre(){ if (this.mToneCurveTexture[0] != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE3); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mToneCurveTexture[0]); GLES20.glUniform1i(this.mToneCurveTextureUniformLocation, 3); } } protected void onInit(){ super.onInit(); mToneCurveTextureUniformLocation = GLES20.glGetUniformLocation(mGLProgId, "curve"); } protected void onInitialized(){ super.onInitialized(); runOnDraw(new Runnable(){ public void run(){ GLES20.glGenTextures(1, mToneCurveTexture, 0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mToneCurveTexture[0]); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); byte[] arrayOfByte = new byte[2048]; int[] arrayOfInt1 = { 0, 1, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 8, 9, 10, 11, 11, 12, 13, 14, 15, 15, 16, 17, 18, 19, 20, 21, 22, 23, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 48, 49, 50, 51, 52, 53, 55, 56, 57, 58, 59, 61, 62, 63, 64, 66, 67, 68, 69, 71, 72, 73, 74, 76, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89, 90, 91, 93, 94, 95, 96, 98, 99, 100, 102, 103, 104, 106, 107, 108, 110, 111, 112, 114, 115, 116, 118, 119, 120, 122, 123, 124, 126, 127, 128, 130, 131, 132, 134, 135, 136, 137, 139, 140, 141, 143, 144, 145, 146, 148, 149, 150, 152, 153, 154, 155, 157, 158, 159, 160, 161, 163, 164, 165, 166, 168, 169, 170, 171, 172, 173, 175, 176, 177, 178, 179, 180, 181, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 211, 212, 213, 214, 215, 216, 216, 217, 218, 219, 220, 220, 221, 222, 223, 223, 224, 225, 226, 226, 227, 228, 228, 229, 230, 230, 231, 232, 232, 233, 234, 234, 235, 236, 236, 237, 238, 238, 239, 239, 240, 241, 241, 242, 242, 243, 244, 244, 245, 245, 246, 247, 247, 248, 248, 249, 249, 250, 251, 251, 252, 252, 253, 253, 254, 254, 255 }; int[] arrayOfInt2 = { 15, 15, 16, 17, 18, 19, 20, 20, 21, 22, 23, 23, 24, 25, 26, 27, 28, 29, 30, 31, 31, 32, 33, 34, 35, 37, 38, 39, 40, 41, 42, 43, 43, 44, 45, 46, 48, 49, 50, 51, 52, 53, 55, 56, 57, 57, 58, 59, 61, 62, 63, 64, 66, 67, 68, 69, 71, 72, 72, 73, 74, 76, 77, 78, 79, 81, 82, 83, 85, 86, 87, 87, 89, 90, 91, 93, 94, 95, 96, 98, 99, 100, 102, 102, 103, 104, 106, 107, 108, 110, 111, 112, 114, 115, 116, 118, 118, 119, 120, 122, 123, 124, 126, 127, 128, 130, 131, 132, 134, 134, 135, 136, 137, 139, 140, 141, 143, 144, 145, 146, 148, 149, 149, 150, 152, 153, 154, 155, 157, 158, 159, 160, 161, 163, 163, 164, 165, 166, 168, 169, 170, 171, 172, 173, 175, 176, 177, 177, 178, 179, 180, 181, 183, 184, 185, 186, 187, 188, 189, 190, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 211, 212, 212, 213, 214, 215, 216, 216, 217, 218, 219, 220, 220, 221, 222, 222, 223, 223, 224, 225, 226, 226, 227, 228, 228, 229, 230, 230, 230, 231, 232, 232, 233, 234, 234, 235, 236, 236, 237, 238, 238, 238, 239, 239, 240, 241, 241, 242, 242, 243, 244, 244, 245, 245, 245, 246, 247, 247, 248, 248, 249, 249, 250, 251, 251, 252, 252, 252, 253, 253, 254, 254, 255 }; int[] arrayOfInt3 = { 87, 89, 89, 90, 90, 91, 91, 93, 93, 94, 95, 95, 96, 96, 98, 98, 99, 100, 100, 102, 102, 103, 103, 104, 104, 106, 107, 107, 108, 108, 110, 110, 111, 112, 112, 114, 114, 115, 115, 116, 118, 118, 119, 119, 120, 120, 122, 123, 123, 124, 124, 126, 126, 127, 128, 128, 130, 130, 131, 131, 132, 134, 134, 135, 135, 136, 136, 137, 139, 139, 140, 140, 141, 143, 143, 144, 144, 145, 146, 146, 148, 148, 149, 150, 150, 152, 152, 153, 154, 154, 155, 155, 157, 158, 158, 159, 159, 160, 161, 161, 163, 163, 164, 165, 165, 166, 168, 168, 169, 169, 170, 171, 171, 172, 173, 173, 175, 175, 176, 177, 177, 178, 179, 179, 180, 181, 181, 183, 183, 184, 185, 185, 186, 187, 187, 188, 189, 189, 190, 191, 191, 192, 193, 193, 194, 195, 195, 196, 197, 197, 198, 199, 199, 200, 201, 201, 202, 203, 204, 204, 205, 206, 206, 207, 208, 208, 209, 210, 211, 211, 211, 212, 212, 213, 214, 215, 215, 216, 216, 217, 217, 218, 219, 219, 220, 220, 221, 221, 222, 223, 223, 223, 224, 225, 226, 226, 226, 227, 228, 228, 228, 229, 230, 230, 230, 231, 232, 232, 232, 233, 234, 234, 235, 235, 236, 236, 237, 238, 238, 238, 239, 239, 240, 240, 241, 241, 242, 242, 242, 243, 244, 244, 244, 245, 245, 246, 247, 247, 247, 248, 248, 249, 249, 249, 250, 251, 251, 252, 252, 252, 253, 253, 254, 254, 254, 255 }; int[] arrayOfInt4 = { 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 10, 11, 12, 13, 13, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22, 23, 24, 24, 25, 26, 27, 28, 29, 29, 30, 31, 32, 33, 34, 35, 36, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 64, 65, 66, 67, 68, 69, 70, 72, 73, 74, 75, 76, 78, 79, 80, 81, 83, 84, 85, 86, 88, 89, 90, 91, 93, 94, 95, 97, 98, 99, 101, 102, 103, 105, 106, 107, 109, 110, 111, 113, 114, 115, 117, 118, 119, 121, 122, 123, 125, 126, 127, 129, 130, 131, 133, 134, 136, 137, 138, 140, 141, 142, 144, 145, 146, 148, 149, 150, 152, 153, 154, 156, 157, 158, 159, 161, 162, 163, 165, 166, 167, 168, 170, 171, 172, 173, 175, 176, 177, 178, 180, 181, 182, 183, 184, 186, 187, 188, 189, 190, 191, 192, 193, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 213, 214, 215, 216, 217, 218, 219, 219, 220, 221, 222, 223, 223, 224, 225, 226, 227, 227, 228, 229, 230, 230, 231, 232, 232, 233, 234, 234, 235, 236, 236, 237, 238, 238, 239, 240, 240, 241, 242, 242, 243, 244, 244, 245, 245, 246, 247, 247, 248, 248, 249, 250, 250, 251, 251, 252, 253, 253, 254, 254, 255 }; for (int i = 0; i < 256; i++){ arrayOfByte[(i * 4)] = ((byte)arrayOfInt1[i]); arrayOfByte[(1 + i * 4)] = ((byte)arrayOfInt2[i]); arrayOfByte[(2 + i * 4)] = ((byte)arrayOfInt3[i]); arrayOfByte[(3 + i * 4)] = ((byte)arrayOfInt4[i]); } int[] arrayOfInt5 = { 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 8, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 20, 20, 20, 21, 21, 21, 22, 22, 23, 23, 23, 24, 24, 24, 25, 25, 25, 25, 26, 26, 27, 27, 28, 28, 28, 28, 29, 29, 30, 29, 31, 31, 31, 31, 32, 32, 33, 33, 34, 34, 34, 34, 35, 35, 36, 36, 37, 37, 37, 38, 38, 39, 39, 39, 40, 40, 40, 41, 42, 42, 43, 43, 44, 44, 45, 45, 45, 46, 47, 47, 48, 48, 49, 50, 51, 51, 52, 52, 53, 53, 54, 55, 55, 56, 57, 57, 58, 59, 60, 60, 61, 62, 63, 63, 64, 65, 66, 67, 68, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 88, 89, 90, 91, 93, 94, 95, 96, 97, 98, 100, 101, 103, 104, 105, 107, 108, 110, 111, 113, 115, 116, 118, 119, 120, 122, 123, 125, 127, 128, 130, 132, 134, 135, 137, 139, 141, 143, 144, 146, 148, 150, 152, 154, 156, 158, 160, 163, 165, 167, 169, 171, 173, 175, 178, 180, 182, 185, 187, 189, 192, 194, 197, 199, 201, 204, 206, 209, 211, 214, 216, 219, 221, 224, 226, 229, 232, 234, 236, 239, 241, 245, 247, 250, 252, 255 }; for (int j = 0; j < 256; j++){ arrayOfByte[(1024 + j * 4)] = ((byte)arrayOfInt5[j]); arrayOfByte[(1 + (1024 + j * 4))] = ((byte)arrayOfInt5[j]); arrayOfByte[(2 + (1024 + j * 4))] = ((byte)arrayOfInt5[j]); arrayOfByte[(3 + (1024 + j * 4))] = -1; } GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, 256, 2, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, ByteBuffer.wrap(arrayOfByte)); } }); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/advanced/MagicBeautyFilter.java ================================================ package com.zero.magicshow.core.filter.advanced; import android.opengl.GLES20; import com.zero.magicshow.R; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.common.utils.MagicParams; import com.zero.magicshow.common.utils.OpenGlUtils; /** * Created by Administrator on 2016/5/22. */ public class MagicBeautyFilter extends GPUImageFilter{ private int mSingleStepOffsetLocation; private int mParamsLocation; public MagicBeautyFilter(){ super(NO_FILTER_VERTEX_SHADER , OpenGlUtils.readShaderFromRawResource(R.raw.beauty)); } protected void onInit() { super.onInit(); mSingleStepOffsetLocation = GLES20.glGetUniformLocation(getProgram(), "singleStepOffset"); mParamsLocation = GLES20.glGetUniformLocation(getProgram(), "params"); setBeautyLevel(MagicParams.beautyLevel); } private void setTexelSize(final float w, final float h) { setFloatVec2(mSingleStepOffsetLocation, new float[] {2.0f / w, 2.0f / h}); } @Override public void onInputSizeChanged(final int width, final int height) { super.onInputSizeChanged(width, height); setTexelSize(width, height); } public void setBeautyLevel(int level){ switch (level) { case 1: setFloat(mParamsLocation, 1.0f); break; case 2: setFloat(mParamsLocation, 0.8f); break; case 3: setFloat(mParamsLocation,0.6f); break; case 4: setFloat(mParamsLocation, 0.4f); break; case 5: setFloat(mParamsLocation,0.33f); break; default: setFloat(mParamsLocation,0.0f); break; } } public void onBeautyLevelChanged(){ setBeautyLevel(MagicParams.beautyLevel); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/advanced/MagicBlackCatFilter.java ================================================ package com.zero.magicshow.core.filter.advanced; import android.opengl.GLES20; import com.zero.magicshow.R; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.common.utils.OpenGlUtils; import java.nio.ByteBuffer; public class MagicBlackCatFilter extends GPUImageFilter{ private int[] mToneCurveTexture = {-1}; private int mToneCurveTextureUniformLocation; public MagicBlackCatFilter(){ super(NO_FILTER_VERTEX_SHADER, OpenGlUtils.readShaderFromRawResource(R.raw.blackcat)); } protected void onDestroy(){ super.onDestroy(); GLES20.glDeleteTextures(1, mToneCurveTexture, 0); mToneCurveTexture[0] = -1; } protected void onDrawArraysAfter(){ if (mToneCurveTexture[0] != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE3); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } } protected void onDrawArraysPre(){ if (mToneCurveTexture[0] != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE3); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mToneCurveTexture[0]); GLES20.glUniform1i(mToneCurveTextureUniformLocation, 3); } } protected void onInit(){ super.onInit(); mToneCurveTextureUniformLocation = GLES20.glGetUniformLocation(mGLProgId, "curve"); } protected void onInitialized(){ super.onInitialized(); runOnDraw(new Runnable(){ public void run(){ GLES20.glGenTextures(1, mToneCurveTexture, 0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mToneCurveTexture[0]); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); byte[] arrayOfByte = new byte[2048]; int[] arrayOfInt1 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 5, 7, 8, 10, 11, 13, 15, 16, 18, 20, 21, 23, 24, 26, 28, 29, 31, 33, 34, 36, 37, 39, 41, 42, 44, 45, 47, 49, 50, 52, 53, 55, 57, 58, 60, 61, 63, 65, 66, 68, 69, 71, 72, 74, 76, 77, 79, 80, 82, 83, 85, 86, 88, 90, 91, 93, 94, 96, 97, 99, 100, 102, 103, 105, 106, 108, 109, 111, 112, 114, 115, 116, 118, 119, 121, 122, 124, 125, 127, 128, 129, 131, 132, 134, 135, 136, 138, 139, 141, 142, 143, 145, 146, 147, 149, 150, 151, 153, 154, 155, 157, 158, 159, 160, 162, 163, 164, 165, 167, 168, 169, 170, 172, 173, 174, 175, 176, 178, 179, 180, 181, 182, 183, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 199, 200, 201, 202, 203, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 215, 216, 217, 218, 219, 220, 220, 221, 222, 223, 224, 224, 225, 226, 227, 227, 228, 229, 229, 230, 231, 232, 232, 233, 234, 234, 235, 236, 236, 237, 238, 238, 239, 240, 240, 241, 242, 242, 243, 243, 244, 245, 245, 246, 247, 247, 248, 248, 249, 250, 250, 251, 251, 252, 253, 253, 254, 254, 255 }; int[] arrayOfInt2 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 5, 7, 8, 10, 11, 13, 15, 16, 16, 18, 20, 21, 23, 24, 26, 28, 29, 31, 33, 34, 36, 37, 39, 41, 41, 42, 44, 45, 47, 49, 50, 52, 53, 55, 57, 58, 60, 61, 63, 65, 66, 68, 69, 71, 72, 74, 76, 77, 79, 80, 82, 83, 85, 86, 86, 88, 90, 91, 93, 94, 96, 97, 99, 100, 102, 103, 105, 106, 108, 109, 111, 112, 114, 115, 116, 118, 119, 121, 122, 124, 125, 127, 128, 129, 131, 134, 135, 136, 138, 139, 141, 142, 143, 145, 146, 147, 149, 150, 151, 153, 154, 155, 157, 158, 159, 160, 162, 163, 164, 165, 167, 168, 169, 170, 172, 173, 174, 175, 176, 179, 180, 181, 182, 183, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 199, 200, 201, 203, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 215, 216, 217, 219, 220, 220, 221, 222, 223, 224, 224, 225, 226, 227, 227, 228, 229, 229, 230, 232, 232, 233, 234, 234, 235, 236, 236, 237, 238, 238, 239, 240, 240, 242, 242, 243, 243, 244, 245, 245, 246, 247, 247, 248, 248, 249, 250, 251, 251, 252, 253, 253, 254, 254, 255 }; int[] arrayOfInt3 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 3, 5, 7, 8, 10, 10, 11, 13, 15, 16, 18, 20, 20, 21, 23, 24, 26, 28, 29, 29, 31, 33, 34, 36, 37, 39, 39, 41, 42, 44, 45, 47, 49, 50, 50, 52, 53, 55, 57, 58, 60, 61, 63, 63, 65, 66, 68, 69, 71, 72, 74, 76, 77, 79, 79, 80, 82, 83, 85, 86, 88, 90, 91, 93, 94, 96, 97, 99, 100, 100, 102, 103, 105, 106, 108, 109, 111, 112, 114, 115, 116, 118, 119, 121, 122, 124, 125, 127, 128, 129, 131, 132, 134, 135, 136, 138, 139, 141, 142, 143, 145, 146, 147, 149, 150, 151, 153, 154, 155, 157, 158, 159, 160, 162, 164, 165, 167, 168, 169, 170, 172, 173, 174, 175, 176, 178, 179, 180, 181, 182, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 199, 200, 201, 202, 203, 203, 204, 205, 206, 207, 209, 210, 211, 212, 213, 214, 215, 215, 216, 218, 219, 220, 220, 221, 222, 223, 224, 225, 226, 227, 227, 228, 229, 229, 230, 232, 232, 233, 234, 234, 235, 236, 236, 238, 238, 239, 240, 240, 241, 242, 243, 243, 244, 245, 245, 246, 247, 247, 248, 249, 250, 250, 251, 251, 252, 253, 254, 254, 255 }; for (int i = 0; i < 256; i++){ arrayOfByte[(i * 4)] = ((byte)arrayOfInt1[i]); arrayOfByte[(1 + i * 4)] = ((byte)arrayOfInt2[i]); arrayOfByte[(2 + i * 4)] = ((byte)arrayOfInt3[i]); arrayOfByte[(3 + i * 4)] = -1; } int[] arrayOfInt4 = { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 16, 17, 18, 18, 19, 19, 20, 21, 21, 23, 24, 25, 26, 26, 26, 27, 28, 29, 30, 31, 32, 32, 33, 34, 35, 36, 37, 38, 38, 38, 39, 40, 41, 43, 44, 45, 45, 46, 47, 48, 49, 49, 50, 51, 52, 53, 54, 55, 56, 57, 57, 58, 59, 60, 61, 62, 63, 64, 65, 65, 66, 67, 68, 69, 70, 70, 71, 72, 74, 75, 76, 76, 77, 78, 79, 80, 81, 82, 82, 83, 85, 86, 87, 88, 89, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 101, 102, 103, 104, 105, 107, 107, 108, 109, 111, 112, 113, 114, 114, 115, 116, 117, 119, 120, 120, 121, 122, 123, 124, 125, 126, 126, 127, 128, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 139, 141, 142, 143, 144, 145, 145, 146, 147, 148, 149, 151, 151, 153, 154, 155, 156, 157, 158, 158, 159, 160, 161, 162, 163, 165, 166, 167, 168, 169, 170, 170, 171, 172, 173, 174, 175, 177, 178, 179, 180, 181, 182, 183, 183, 184, 185, 186, 189, 189, 190, 191, 192, 193, 194, 195, 195, 196, 198, 199, 201, 202, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 213, 214, 214, 215, 216, 218, 219, 220, 221, 221, 222, 223, 225, 227, 227, 228, 229, 230, 230, 230, 230, 230, 230, 230, 230, 230 }; int[] arrayOfInt5 = { 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 7, 8, 8, 9, 10, 11, 11, 12, 13, 14, 15, 15, 16, 17, 18, 19, 19, 20, 21, 22, 23, 24, 25, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 39, 40, 41, 42, 43, 44, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 61, 62, 63, 64, 65, 66, 67, 69, 70, 71, 72, 73, 74, 76, 77, 78, 79, 81, 82, 83, 84, 86, 87, 88, 89, 91, 92, 93, 95, 96, 97, 99, 100, 101, 103, 104, 105, 107, 108, 109, 111, 112, 114, 115, 116, 118, 119, 121, 122, 124, 125, 126, 128, 129, 131, 132, 134, 135, 137, 138, 140, 141, 142, 144, 145, 147, 148, 149, 151, 152, 154, 155, 156, 158, 159, 160, 162, 163, 164, 166, 167, 168, 170, 171, 172, 173, 175, 176, 177, 178, 180, 181, 182, 183, 184, 186, 187, 188, 189, 190, 191, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 220, 221, 222, 223, 224, 225, 225, 226, 227, 228, 229, 229, 230, 231, 232, 232, 233, 234, 234, 235, 236, 236, 237, 238, 238, 239, 240, 240, 241, 241, 242, 243, 243, 244, 244, 245, 245, 246, 246, 247, 247, 248, 248, 249, 249, 250, 250, 251, 251, 252, 252, 252, 253, 253, 254, 254, 254, 255, 255 }; int[] arrayOfInt6 = { 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 8, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 20, 20, 20, 21, 21, 21, 22, 22, 23, 23, 23, 24, 24, 24, 25, 25, 25, 25, 26, 26, 27, 27, 28, 28, 28, 28, 29, 29, 30, 29, 31, 31, 31, 31, 32, 32, 33, 33, 34, 34, 34, 34, 35, 35, 36, 36, 37, 37, 37, 38, 38, 39, 39, 39, 40, 40, 40, 41, 42, 42, 43, 43, 44, 44, 45, 45, 45, 46, 47, 47, 48, 48, 49, 50, 51, 51, 52, 52, 53, 53, 54, 55, 55, 56, 57, 57, 58, 59, 60, 60, 61, 62, 63, 63, 64, 65, 66, 67, 68, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 88, 89, 90, 91, 93, 94, 95, 96, 97, 98, 100, 101, 103, 104, 105, 107, 108, 110, 111, 113, 115, 116, 118, 119, 120, 122, 123, 125, 127, 128, 130, 132, 134, 135, 137, 139, 141, 143, 144, 146, 148, 150, 152, 154, 156, 158, 160, 163, 165, 167, 169, 171, 173, 175, 178, 180, 182, 185, 187, 189, 192, 194, 197, 199, 201, 204, 206, 209, 211, 214, 216, 219, 221, 224, 226, 229, 232, 234, 236, 239, 241, 245, 247, 250, 252, 255 }; for (int j = 0; j < 256; j++){ arrayOfByte[(1024 + j * 4)] = ((byte)arrayOfInt4[j]); arrayOfByte[(1 + (1024 + j * 4))] = ((byte)arrayOfInt5[j]); arrayOfByte[(2 + (1024 + j * 4))] = ((byte)arrayOfInt6[j]); arrayOfByte[(3 + (1024 + j * 4))] = -1; } GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, 256, 2, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, ByteBuffer.wrap(arrayOfByte)); } }); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/advanced/MagicBrannanFilter.java ================================================ package com.zero.magicshow.core.filter.advanced; import android.opengl.GLES20; import com.zero.magicshow.R; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.common.utils.MagicParams; import com.zero.magicshow.common.utils.OpenGlUtils; public class MagicBrannanFilter extends GPUImageFilter{ private int[] inputTextureHandles = {-1,-1,-1,-1,-1}; private int[] inputTextureUniformLocations = {-1,-1,-1,-1,-1}; private int mGLStrengthLocation; public MagicBrannanFilter(){ super(NO_FILTER_VERTEX_SHADER, OpenGlUtils.readShaderFromRawResource(R.raw.brannan)); } protected void onDestroy() { super.onDestroy(); GLES20.glDeleteTextures(inputTextureHandles.length, inputTextureHandles, 0); for(int i = 0; i < inputTextureHandles.length; i++) inputTextureHandles[i] = -1; } protected void onDrawArraysAfter(){ for(int i = 0; i < inputTextureHandles.length && inputTextureHandles[i] != OpenGlUtils.NO_TEXTURE; i++){ GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + (i+3)); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } } protected void onDrawArraysPre(){ for(int i = 0; i < inputTextureHandles.length && inputTextureHandles[i] != OpenGlUtils.NO_TEXTURE; i++){ GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + (i+3) ); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, inputTextureHandles[i]); GLES20.glUniform1i(inputTextureUniformLocations[i], (i+3)); } } protected void onInit(){ super.onInit(); for(int i=0; i < inputTextureUniformLocations.length; i++) inputTextureUniformLocations[i] = GLES20.glGetUniformLocation(getProgram(), "inputImageTexture"+(2+i)); mGLStrengthLocation = GLES20.glGetUniformLocation(mGLProgId, "strength"); } protected void onInitialized(){ super.onInitialized(); setFloat(mGLStrengthLocation, 1.0f); runOnDraw(new Runnable(){ public void run(){ inputTextureHandles[0] = OpenGlUtils.loadTexture(MagicParams.context, "filter/brannan_process.png"); inputTextureHandles[1] = OpenGlUtils.loadTexture(MagicParams.context, "filter/brannan_blowout.png"); inputTextureHandles[2] = OpenGlUtils.loadTexture(MagicParams.context, "filter/brannan_contrast.png"); inputTextureHandles[3] = OpenGlUtils.loadTexture(MagicParams.context, "filter/brannan_luma.png"); inputTextureHandles[4] = OpenGlUtils.loadTexture(MagicParams.context, "filter/brannan_screen.png"); } }); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/advanced/MagicBrooklynFilter.java ================================================ package com.zero.magicshow.core.filter.advanced; import android.opengl.GLES20; import com.zero.magicshow.R; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.common.utils.MagicParams; import com.zero.magicshow.common.utils.OpenGlUtils; public class MagicBrooklynFilter extends GPUImageFilter{ private int[] inputTextureHandles = {-1,-1,-1}; private int[] inputTextureUniformLocations = {-1,-1,-1}; private int mGLStrengthLocation; public MagicBrooklynFilter(){ super(NO_FILTER_VERTEX_SHADER, OpenGlUtils.readShaderFromRawResource(R.raw.brooklyn)); } public void onDestroy() { super.onDestroy(); GLES20.glDeleteTextures(inputTextureHandles.length, inputTextureHandles, 0); for(int i = 0; i < inputTextureHandles.length; i++) inputTextureHandles[i] = -1; } protected void onDrawArraysAfter(){ for(int i = 0; i < inputTextureHandles.length && inputTextureHandles[i] != OpenGlUtils.NO_TEXTURE; i++){ GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + (i+3)); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } } protected void onDrawArraysPre(){ for(int i = 0; i < inputTextureHandles.length && inputTextureHandles[i] != OpenGlUtils.NO_TEXTURE; i++){ GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + (i+3) ); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, inputTextureHandles[i]); GLES20.glUniform1i(inputTextureUniformLocations[i], (i+3)); } } public void onInit(){ super.onInit(); for(int i=0; i < inputTextureUniformLocations.length; i++) inputTextureUniformLocations[i] = GLES20.glGetUniformLocation(getProgram(), "inputImageTexture"+(2+i)); mGLStrengthLocation = GLES20.glGetUniformLocation(mGLProgId, "strength"); } public void onInitialized(){ super.onInitialized(); setFloat(mGLStrengthLocation, 1.0f); runOnDraw(new Runnable(){ public void run(){ inputTextureHandles[0] = OpenGlUtils.loadTexture(MagicParams.context, "filter/brooklynCurves1.png"); inputTextureHandles[1] = OpenGlUtils.loadTexture(MagicParams.context, "filter/filter_map_first.png"); inputTextureHandles[2] = OpenGlUtils.loadTexture(MagicParams.context, "filter/brooklynCurves2.png"); } }); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/advanced/MagicCalmFilter.java ================================================ package com.zero.magicshow.core.filter.advanced; import android.opengl.GLES20; import com.zero.magicshow.R; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.common.utils.MagicParams; import com.zero.magicshow.common.utils.OpenGlUtils; import java.nio.ByteBuffer; public class MagicCalmFilter extends GPUImageFilter{ private int[] mToneCurveTexture = {-1}; private int mToneCurveTextureUniformLocation; private int mMaskGrey1TextureId = -1; private int mMaskGrey1UniformLocation; private int mMaskGrey2TextureId = -1; private int mMaskGrey2UniformLocation; public MagicCalmFilter(){ super(NO_FILTER_VERTEX_SHADER, OpenGlUtils.readShaderFromRawResource(R.raw.calm)); } protected void onDestroy(){ super.onDestroy(); GLES20.glDeleteTextures(3, new int[]{mToneCurveTexture[0], mMaskGrey1TextureId, mMaskGrey2TextureId}, 0); mToneCurveTexture[0] = -1; mMaskGrey1TextureId = -1; mMaskGrey2TextureId = -1; } protected void onDrawArraysAfter(){ if (mToneCurveTexture[0] != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE3); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } if (mMaskGrey1TextureId != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE4); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } if (mMaskGrey2TextureId != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE5); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } } protected void onDrawArraysPre(){ if (mToneCurveTexture[0] != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE3); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mToneCurveTexture[0]); GLES20.glUniform1i(mToneCurveTextureUniformLocation, 3); } if (mMaskGrey1TextureId != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE4); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mMaskGrey1TextureId); GLES20.glUniform1i(mMaskGrey1UniformLocation, 4); } if (mMaskGrey2TextureId != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE5); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mMaskGrey2TextureId); GLES20.glUniform1i(mMaskGrey2UniformLocation, 5); } } protected void onInit(){ super.onInit(); mToneCurveTextureUniformLocation = GLES20.glGetUniformLocation(mGLProgId, "curve"); mMaskGrey1UniformLocation = GLES20.glGetUniformLocation(getProgram(), "grey1Frame"); mMaskGrey2UniformLocation = GLES20.glGetUniformLocation(getProgram(), "grey2Frame"); } protected void onInitialized(){ super.onInitialized(); runOnDraw(new Runnable(){ public void run(){ GLES20.glGenTextures(1, mToneCurveTexture, 0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mToneCurveTexture[0]); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); byte[] arrayOfByte = new byte[3072]; int[] arrayOfInt1 = { 38, 39, 40, 41, 41, 42, 43, 44, 45, 46, 47, 47, 48, 49, 50, 51, 52, 52, 53, 54, 55, 56, 57, 58, 58, 59, 60, 61, 62, 63, 64, 64, 65, 66, 67, 68, 69, 69, 70, 71, 72, 73, 74, 75, 75, 76, 77, 78, 79, 80, 81, 81, 82, 83, 84, 85, 86, 87, 87, 88, 89, 90, 91, 92, 92, 93, 94, 95, 96, 97, 98, 98, 99, 100, 101, 102, 103, 104, 104, 105, 106, 107, 108, 109, 109, 110, 111, 112, 113, 114, 115, 115, 116, 117, 118, 119, 120, 121, 121, 122, 123, 124, 125, 126, 127, 127, 128, 129, 130, 131, 132, 132, 133, 134, 135, 136, 137, 138, 138, 139, 140, 141, 142, 143, 144, 144, 145, 146, 147, 148, 149, 149, 150, 151, 152, 153, 154, 155, 155, 156, 157, 158, 159, 160, 161, 161, 162, 163, 164, 165, 166, 166, 167, 168, 169, 170, 171, 172, 172, 173, 174, 175, 176, 177, 178, 178, 179, 180, 181, 182, 183, 184, 184, 185, 186, 187, 188, 189, 189, 190, 191, 192, 193, 194, 195, 195, 196, 197, 198, 199, 200, 201, 201, 202, 203, 204, 205, 206, 206, 207, 208, 209, 210, 211, 212, 212, 213, 214, 215, 216, 217, 218, 218, 219, 220, 221, 222, 223, 224, 224, 225, 226, 227, 228, 229, 229, 230, 231, 232, 233, 234, 235, 235, 236, 237, 238, 239, 240, 241, 241, 242, 243, 244, 245, 246, 246, 247, 248, 249, 250, 251, 252, 252, 253, 254, 255 }; for (int i = 0; i < 256; i++){ arrayOfByte[(i * 4)] = ((byte)arrayOfInt1[i]); arrayOfByte[(1 + i * 4)] = ((byte)arrayOfInt1[i]); arrayOfByte[(2 + i * 4)] = ((byte)arrayOfInt1[i]); arrayOfByte[(3 + i * 4)] = -1; } int[] arrayOfInt2 = { 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 18, 19, 21, 22, 23, 24, 25, 26, 27, 29, 30, 31, 32, 33, 34, 35, 36, 37, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 93, 94, 95, 96, 97, 98, 99, 99, 100, 101, 102, 103, 104, 104, 105, 106, 107, 108, 109, 109, 110, 111, 112, 113, 114, 114, 115, 116, 117, 118, 118, 119, 120, 121, 122, 123, 123, 124, 125, 126, 127, 127, 128, 129, 130, 131, 131, 132, 133, 134, 135, 135, 136, 137, 138, 139, 140, 140, 141, 142, 143, 144, 145, 145, 146, 147, 148, 149, 150, 150, 151, 152, 153, 154, 155, 156, 157, 157, 158, 159, 160, 161, 162, 163, 164, 165, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 196, 197, 198, 199, 200, 201, 202, 203, 204, 206, 207, 208, 209, 210, 211, 213, 214, 215, 216, 217, 218, 220, 221, 222, 223, 224, 226, 227, 228, 229, 230, 232, 233, 234, 235, 237, 238, 239, 240, 241, 243, 244, 245, 246, 248, 249, 250, 251, 253, 254, 255 }; int[] arrayOfInt3 = { 0, 1, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 8, 9, 10, 11, 11, 12, 13, 14, 15, 15, 16, 17, 18, 19, 20, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 36, 37, 38, 39, 40, 42, 43, 44, 46, 47, 48, 50, 51, 53, 54, 56, 57, 59, 60, 62, 64, 65, 67, 69, 70, 72, 74, 75, 77, 79, 80, 82, 84, 85, 87, 89, 91, 92, 94, 96, 97, 99, 101, 102, 104, 106, 107, 109, 111, 112, 114, 115, 117, 118, 120, 121, 123, 124, 126, 127, 129, 130, 132, 133, 134, 136, 137, 138, 140, 141, 142, 144, 145, 146, 147, 149, 150, 151, 152, 153, 155, 156, 157, 158, 159, 160, 161, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 184, 185, 186, 187, 188, 189, 190, 191, 191, 192, 193, 194, 195, 196, 196, 197, 198, 199, 200, 200, 201, 202, 203, 203, 204, 205, 206, 206, 207, 208, 209, 209, 210, 211, 211, 212, 213, 214, 214, 215, 216, 216, 217, 218, 218, 219, 220, 220, 221, 222, 222, 223, 224, 224, 225, 226, 226, 227, 227, 228, 229, 229, 230, 231, 231, 232, 233, 233, 234, 234, 235, 236, 236, 237, 237, 238, 239, 239, 240, 240, 241, 242, 242, 243, 243, 244, 245, 245, 246, 246, 247, 247, 248, 249, 249, 250, 250, 251, 252, 252, 253, 253, 254, 254, 255 }; for (int j = 0; j < 256; j++){ arrayOfByte[(1024 + j * 4)] = ((byte)arrayOfInt3[j]); arrayOfByte[(1 + (1024 + j * 4))] = ((byte)arrayOfInt3[j]); arrayOfByte[(2 + (1024 + j * 4))] = ((byte)arrayOfInt2[j]); arrayOfByte[(3 + (1024 + j * 4))] = -1; } int[] arrayOfInt4 = { 0, 1, 3, 4, 5, 7, 8, 10, 11, 12, 14, 15, 16, 18, 19, 20, 22, 23, 24, 26, 27, 28, 30, 31, 33, 34, 35, 37, 38, 39, 41, 42, 43, 45, 46, 47, 49, 50, 51, 53, 54, 55, 57, 58, 59, 61, 62, 63, 64, 66, 67, 68, 70, 71, 72, 74, 75, 76, 77, 79, 80, 81, 83, 84, 85, 86, 88, 89, 90, 91, 93, 94, 95, 96, 98, 99, 100, 101, 103, 104, 105, 106, 108, 109, 110, 111, 112, 114, 115, 116, 117, 118, 119, 121, 122, 123, 124, 125, 126, 128, 129, 130, 131, 132, 133, 134, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 175, 176, 177, 178, 179, 180, 181, 182, 183, 183, 184, 185, 186, 187, 188, 189, 189, 190, 191, 192, 193, 194, 194, 195, 196, 197, 198, 198, 199, 200, 201, 202, 202, 203, 204, 205, 205, 206, 207, 208, 208, 209, 210, 211, 211, 212, 213, 214, 214, 215, 216, 216, 217, 218, 218, 219, 220, 221, 221, 222, 223, 223, 224, 225, 225, 226, 227, 227, 228, 229, 229, 230, 231, 231, 232, 233, 233, 234, 235, 235, 236, 237, 237, 238, 239, 239, 240, 240, 241, 242, 242, 243, 244, 244, 245, 246, 246, 247, 247, 248, 249, 249, 250, 251, 251, 252, 252, 253, 254, 254, 255 }; int[] arrayOfInt5 = { 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 20, 20, 21, 21, 21, 22, 22, 23, 23, 24, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31, 31, 32, 33, 33, 34, 34, 35, 35, 36, 37, 37, 38, 38, 39, 40, 40, 41, 42, 42, 43, 44, 44, 45, 46, 47, 47, 48, 49, 49, 50, 51, 52, 53, 53, 54, 55, 56, 57, 57, 58, 59, 60, 61, 62, 63, 64, 65, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 81, 82, 83, 84, 85, 86, 87, 88, 90, 91, 92, 93, 94, 96, 97, 98, 99, 101, 102, 103, 105, 106, 107, 109, 110, 111, 113, 114, 115, 117, 118, 120, 121, 123, 124, 126, 127, 129, 130, 132, 133, 135, 137, 138, 140, 142, 143, 145, 147, 148, 150, 152, 153, 155, 157, 159, 161, 162, 164, 166, 168, 170, 172, 174, 175, 177, 179, 181, 183, 185, 187, 189, 191, 193, 195, 197, 199, 201, 203, 205, 207, 209, 211, 213, 215, 217, 219, 221, 224, 226, 228, 230, 232, 234, 236, 238, 240, 242, 244, 247, 249, 251, 253, 255 }; int[] arrayOfInt6 = { 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 8, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 20, 20, 20, 21, 21, 21, 22, 22, 23, 23, 23, 24, 24, 24, 25, 25, 25, 25, 26, 26, 27, 27, 28, 28, 28, 28, 29, 29, 30, 29, 31, 31, 31, 31, 32, 32, 33, 33, 34, 34, 34, 34, 35, 35, 36, 36, 37, 37, 37, 38, 38, 39, 39, 39, 40, 40, 40, 41, 42, 42, 43, 43, 44, 44, 45, 45, 45, 46, 47, 47, 48, 48, 49, 50, 51, 51, 52, 52, 53, 53, 54, 55, 55, 56, 57, 57, 58, 59, 60, 60, 61, 62, 63, 63, 64, 65, 66, 67, 68, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 88, 89, 90, 91, 93, 94, 95, 96, 97, 98, 100, 101, 103, 104, 105, 107, 108, 110, 111, 113, 115, 116, 118, 119, 120, 122, 123, 125, 127, 128, 130, 132, 134, 135, 137, 139, 141, 143, 144, 146, 148, 150, 152, 154, 156, 158, 160, 163, 165, 167, 169, 171, 173, 175, 178, 180, 182, 185, 187, 189, 192, 194, 197, 199, 201, 204, 206, 209, 211, 214, 216, 219, 221, 224, 226, 229, 232, 234, 236, 239, 241, 245, 247, 250, 252, 255 }; for (int k = 0; k < 256; k++){ arrayOfByte[(2048 + k * 4)] = ((byte)arrayOfInt4[k]); arrayOfByte[(1 + (2048 + k * 4))] = ((byte)arrayOfInt5[k]); arrayOfByte[(2 + (2048 + k * 4))] = ((byte)arrayOfInt6[k]); arrayOfByte[(3 + (2048 + k * 4))] = -1; } GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, 256, 3, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, ByteBuffer.wrap(arrayOfByte)); mMaskGrey1TextureId = OpenGlUtils.loadTexture(MagicParams.context, "filter/calm_mask1.jpg"); mMaskGrey2TextureId = OpenGlUtils.loadTexture(MagicParams.context, "filter/calm_mask2.jpg"); } }); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/advanced/MagicCoolFilter.java ================================================ package com.zero.magicshow.core.filter.advanced; import android.opengl.GLES20; import com.zero.magicshow.R; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.common.utils.OpenGlUtils; import java.nio.ByteBuffer; public class MagicCoolFilter extends GPUImageFilter{ private int[] mToneCurveTexture = {-1}; private int mToneCurveTextureUniformLocation; public MagicCoolFilter(){ super(NO_FILTER_VERTEX_SHADER, OpenGlUtils.readShaderFromRawResource(R.raw.cool)); } public void onDestroy(){ super.onDestroy(); GLES20.glDeleteTextures(1, mToneCurveTexture, 0); this.mToneCurveTexture[0] = -1; } protected void onDrawArraysAfter(){ if (this.mToneCurveTexture[0] != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE3); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } } protected void onDrawArraysPre(){ if (this.mToneCurveTexture[0] != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE3); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mToneCurveTexture[0]); GLES20.glUniform1i(this.mToneCurveTextureUniformLocation, 3); } } public void onInit(){ super.onInit(); mToneCurveTextureUniformLocation = GLES20.glGetUniformLocation(mGLProgId, "curve"); } public void onInitialized(){ super.onInitialized(); runOnDraw(new Runnable(){ public void run(){ GLES20.glGenTextures(1, mToneCurveTexture, 0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mToneCurveTexture[0]); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); byte[] arrayOfByte = new byte[2048]; int[] arrayOfInt1 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 16, 16, 17, 18, 19, 20, 20, 21, 22, 23, 24, 24, 25, 26, 27, 28, 28, 29, 30, 31, 32, 33, 33, 34, 35, 36, 37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 82, 83, 84, 85, 86, 87, 88, 90, 91, 92, 93, 94, 95, 97, 98, 99, 100, 102, 103, 104, 105, 107, 108, 109, 111, 112, 113, 115, 116, 117, 119, 120, 121, 123, 124, 126, 127, 128, 130, 131, 133, 134, 136, 137, 139, 140, 142, 143, 145, 146, 148, 149, 151, 152, 154, 155, 157, 158, 160, 161, 163, 165, 166, 168, 169, 171, 173, 174, 176, 177, 179, 181, 182, 184, 185, 187, 189, 190, 192, 194, 195, 197, 199, 200, 202, 204, 205, 207, 209, 210, 212, 214, 216, 217, 219, 221, 222, 224, 226, 228, 229, 231, 233, 234, 236, 238, 240, 241, 243, 245, 246, 248, 250, 252, 253, 255 }; int[] arrayOfInt2 = { 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 250, 251, 252, 253, 254, 255 }; int[] arrayOfInt3 = { 0, 3, 6, 9, 11, 14, 17, 20, 23, 26, 28, 31, 34, 37, 40, 43, 45, 48, 51, 54, 57, 59, 62, 65, 68, 70, 73, 76, 79, 81, 84, 87, 89, 92, 95, 97, 100, 102, 105, 108, 110, 113, 115, 118, 120, 123, 125, 128, 130, 133, 135, 137, 140, 142, 144, 147, 149, 151, 153, 156, 158, 160, 162, 164, 166, 168, 171, 173, 175, 177, 179, 180, 182, 184, 186, 188, 190, 191, 193, 195, 197, 198, 200, 201, 203, 205, 206, 207, 209, 210, 212, 213, 214, 216, 217, 218, 219, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 234, 235, 236, 237, 237, 238, 239, 240, 240, 241, 242, 242, 243, 243, 244, 244, 245, 245, 246, 246, 247, 247, 248, 248, 248, 249, 249, 249, 250, 250, 250, 251, 251, 251, 251, 252, 252, 252, 252, 252, 253, 253, 253, 253, 253, 253, 253, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }; int[] arrayOfInt4 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 13, 17, 21, 24, 32, 36, 39, 46, 50, 53, 56, 62, 65, 68, 73, 75, 78, 80, 85, 87, 88, 92, 94, 95, 96, 99, 100, 102, 104, 106, 107, 109, 110, 112, 113, 115, 116, 117, 120, 121, 122, 123, 125, 126, 127, 129, 130, 131, 132, 134, 135, 136, 138, 139, 140, 141, 142, 143, 144, 146, 147, 148, 149, 150, 151, 152, 154, 154, 155, 156, 158, 159, 159, 161, 162, 163, 163, 165, 166, 166, 168, 169, 169, 170, 172, 172, 173, 175, 175, 176, 177, 178, 179, 180, 181, 182, 182, 184, 184, 185, 186, 187, 188, 188, 190, 190, 191, 192, 193, 194, 194, 196, 196, 197, 197, 199, 199, 200, 201, 202, 202, 203, 204, 205, 205, 207, 207, 208, 208, 210, 210, 211, 212, 213, 213, 214, 215, 215, 216, 217, 218, 218, 219, 220, 221, 221, 222, 223, 223, 224, 225, 226, 226, 227, 228, 228, 229, 230, 230, 231, 232, 232, 233, 234, 235, 235, 236, 237, 237, 238, 239, 239, 240, 240, 241, 242, 242, 243, 244, 244, 245, 246, 246, 247, 248, 248, 249, 249, 250, 251, 251, 252, 253, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }; for (int i = 0; i < 256; i++){ arrayOfByte[(i * 4)] = ((byte)arrayOfInt1[i]); arrayOfByte[(1 + i * 4)] = ((byte)arrayOfInt2[i]); arrayOfByte[(2 + i * 4)] = ((byte)arrayOfInt3[i]); arrayOfByte[(3 + i * 4)] = ((byte)arrayOfInt4[i]); } int[] arrayOfInt5 = { 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 8, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 20, 20, 20, 21, 21, 21, 22, 22, 23, 23, 23, 24, 24, 24, 25, 25, 25, 25, 26, 26, 27, 27, 28, 28, 28, 28, 29, 29, 30, 29, 31, 31, 31, 31, 32, 32, 33, 33, 34, 34, 34, 34, 35, 35, 36, 36, 37, 37, 37, 38, 38, 39, 39, 39, 40, 40, 40, 41, 42, 42, 43, 43, 44, 44, 45, 45, 45, 46, 47, 47, 48, 48, 49, 50, 51, 51, 52, 52, 53, 53, 54, 55, 55, 56, 57, 57, 58, 59, 60, 60, 61, 62, 63, 63, 64, 65, 66, 67, 68, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 88, 89, 90, 91, 93, 94, 95, 96, 97, 98, 100, 101, 103, 104, 105, 107, 108, 110, 111, 113, 115, 116, 118, 119, 120, 122, 123, 125, 127, 128, 130, 132, 134, 135, 137, 139, 141, 143, 144, 146, 148, 150, 152, 154, 156, 158, 160, 163, 165, 167, 169, 171, 173, 175, 178, 180, 182, 185, 187, 189, 192, 194, 197, 199, 201, 204, 206, 209, 211, 214, 216, 219, 221, 224, 226, 229, 232, 234, 236, 239, 241, 245, 247, 250, 252, 255 }; for (int j = 0; j < 256; j++){ arrayOfByte[(1024 + j * 4)] = ((byte)arrayOfInt5[j]); arrayOfByte[(1 + (1024 + j * 4))] = ((byte)arrayOfInt5[j]); arrayOfByte[(2 + (1024 + j * 4))] = ((byte)arrayOfInt5[j]); arrayOfByte[(3 + (1024 + j * 4))] = -1; } GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, 256, 2, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, ByteBuffer.wrap(arrayOfByte)); } }); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/advanced/MagicCrayonFilter.java ================================================ package com.zero.magicshow.core.filter.advanced; import android.opengl.GLES20; import com.zero.magicshow.R; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.common.utils.OpenGlUtils; public class MagicCrayonFilter extends GPUImageFilter{ private int mSingleStepOffsetLocation; //1.0 - 5.0 private int mStrengthLocation; public MagicCrayonFilter(){ super(NO_FILTER_VERTEX_SHADER, OpenGlUtils.readShaderFromRawResource(R.raw.crayon)); } protected void onInit() { super.onInit(); mSingleStepOffsetLocation = GLES20.glGetUniformLocation(getProgram(), "singleStepOffset"); mStrengthLocation = GLES20.glGetUniformLocation(getProgram(), "strength"); setFloat(mStrengthLocation, 2.0f); } protected void onDestroy() { super.onDestroy(); } protected void onInitialized(){ super.onInitialized(); setFloat(mStrengthLocation, 0.5f); } private void setTexelSize(final float w, final float h) { setFloatVec2(mSingleStepOffsetLocation, new float[] {1.0f / w, 1.0f / h}); } @Override public void onInputSizeChanged(final int width, final int height) { super.onInputSizeChanged(width, height); setTexelSize(width, height); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/advanced/MagicEarlyBirdFilter.java ================================================ package com.zero.magicshow.core.filter.advanced; import android.opengl.GLES20; import com.zero.magicshow.R; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.common.utils.MagicParams; import com.zero.magicshow.common.utils.OpenGlUtils; public class MagicEarlyBirdFilter extends GPUImageFilter{ private int[] inputTextureHandles = {-1,-1,-1,-1,-1}; private int[] inputTextureUniformLocations = {-1,-1,-1,-1,-1}; protected int mGLStrengthLocation; public MagicEarlyBirdFilter(){ super(NO_FILTER_VERTEX_SHADER, OpenGlUtils.readShaderFromRawResource(R.raw.earlybird)); } protected void onDestroy() { super.onDestroy(); GLES20.glDeleteTextures(inputTextureHandles.length, inputTextureHandles, 0); for(int i = 0; i < inputTextureHandles.length; i++) inputTextureHandles[i] = -1; } protected void onDrawArraysAfter(){ for(int i = 0; i < inputTextureHandles.length && inputTextureHandles[i] != OpenGlUtils.NO_TEXTURE; i++){ GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + (i+3)); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } } protected void onDrawArraysPre(){ for(int i = 0; i < inputTextureHandles.length && inputTextureHandles[i] != OpenGlUtils.NO_TEXTURE; i++){ GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + (i+3) ); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, inputTextureHandles[i]); GLES20.glUniform1i(inputTextureUniformLocations[i], (i+3)); } } protected void onInit(){ super.onInit(); for(int i=0; i < inputTextureUniformLocations.length; i++) inputTextureUniformLocations[i] = GLES20.glGetUniformLocation(getProgram(), "inputImageTexture"+(2+i)); mGLStrengthLocation = GLES20.glGetUniformLocation(mGLProgId, "strength"); } protected void onInitialized(){ super.onInitialized(); setFloat(mGLStrengthLocation, 1.0f); runOnDraw(new Runnable(){ public void run(){ inputTextureHandles[0] = OpenGlUtils.loadTexture(MagicParams.context, "filter/earlybirdcurves.png"); inputTextureHandles[1] = OpenGlUtils.loadTexture(MagicParams.context, "filter/earlybirdoverlaymap_new.png"); inputTextureHandles[2] = OpenGlUtils.loadTexture(MagicParams.context, "filter/vignettemap_new.png"); inputTextureHandles[3] = OpenGlUtils.loadTexture(MagicParams.context, "filter/earlybirdblowout.png"); inputTextureHandles[4] = OpenGlUtils.loadTexture(MagicParams.context, "filter/earlybirdmap.png"); } }); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/advanced/MagicEmeraldFilter.java ================================================ package com.zero.magicshow.core.filter.advanced; import android.opengl.GLES20; import com.zero.magicshow.R; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.common.utils.OpenGlUtils; import java.nio.ByteBuffer; public class MagicEmeraldFilter extends GPUImageFilter{ private int[] mToneCurveTexture = {-1}; private int mToneCurveTextureUniformLocation; public MagicEmeraldFilter(){ super(NO_FILTER_VERTEX_SHADER, OpenGlUtils.readShaderFromRawResource(R.raw.emerald)); } protected void onDestroy(){ super.onDestroy(); GLES20.glDeleteTextures(1, mToneCurveTexture, 0); mToneCurveTexture[0] = -1; } protected void onDrawArraysAfter(){ if (mToneCurveTexture[0] != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE3); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } } protected void onDrawArraysPre(){ if (mToneCurveTexture[0] != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE3); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mToneCurveTexture[0]); GLES20.glUniform1i(mToneCurveTextureUniformLocation, 3); } } protected void onInit(){ super.onInit(); mToneCurveTextureUniformLocation = GLES20.glGetUniformLocation(mGLProgId, "curve"); } protected void onInitialized(){ super.onInitialized(); runOnDraw(new Runnable(){ public void run(){ GLES20.glGenTextures(1, mToneCurveTexture, 0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mToneCurveTexture[0]); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); byte[] arrayOfByte = new byte[2048]; int[] arrayOfInt1 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 4, 7, 8, 9, 10, 12, 13, 14, 17, 18, 19, 21, 22, 23, 25, 26, 29, 30, 31, 32, 34, 35, 36, 39, 40, 41, 43, 44, 45, 46, 48, 50, 51, 53, 54, 55, 56, 58, 60, 61, 62, 64, 65, 66, 67, 69, 70, 72, 73, 75, 76, 77, 78, 79, 81, 82, 84, 85, 87, 88, 89, 90, 91, 92, 94, 96, 97, 98, 99, 101, 102, 103, 104, 105, 106, 107, 110, 111, 112, 113, 114, 115, 116, 117, 119, 120, 121, 122, 123, 125, 126, 127, 128, 129, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 173, 174, 175, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 184, 185, 186, 187, 188, 189, 190, 191, 191, 192, 193, 194, 195, 196, 197, 197, 198, 199, 200, 201, 201, 202, 203, 204, 205, 206, 206, 207, 208, 209, 210, 210, 211, 212, 213, 213, 214, 215, 216, 216, 217, 218, 219, 220, 220, 221, 222, 223, 223, 224, 225, 226, 226, 227, 228, 228, 229, 230, 231, 231, 232, 233, 234, 234, 235, 236, 236, 237, 237, 238, 239, 239, 240, 241, 242, 242, 243, 244, 244, 245, 246, 247, 247, 248, 249, 249, 250, 251, 251, 252, 253, 254, 254, 255 }; int[] arrayOfInt2 = { 0, 0, 0, 0, 0, 0, 1, 3, 4, 5, 7, 8, 9, 10, 12, 13, 14, 16, 18, 19, 21, 22, 23, 25, 26, 27, 29, 30, 31, 32, 34, 35, 36, 37, 39, 40, 41, 43, 44, 45, 46, 48, 50, 51, 53, 54, 55, 56, 58, 59, 60, 61, 62, 64, 65, 66, 67, 69, 70, 71, 72, 73, 75, 76, 77, 78, 79, 82, 83, 84, 85, 87, 88, 89, 90, 91, 92, 94, 95, 96, 97, 98, 99, 101, 102, 103, 104, 105, 106, 107, 109, 111, 112, 113, 114, 115, 116, 117, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 131, 132, 133, 134, 135, 136, 137, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 184, 185, 186, 188, 189, 190, 191, 191, 192, 193, 194, 195, 196, 197, 197, 198, 199, 200, 201, 201, 202, 203, 204, 205, 206, 206, 207, 209, 210, 210, 211, 212, 213, 213, 214, 215, 216, 216, 217, 218, 219, 220, 220, 221, 222, 223, 223, 224, 225, 226, 226, 227, 228, 229, 230, 231, 231, 232, 233, 234, 234, 235, 236, 237, 237, 238, 239, 239, 240, 241, 242, 242, 243, 244, 244, 245, 247, 247, 248, 249, 249, 250, 251, 251, 252, 253, 254, 254, 255, 255, 255, 255, 255, 255 }; int[] arrayOfInt3 = { 0, 1, 3, 4, 5, 7, 8, 9, 10, 12, 13, 14, 16, 17, 18, 19, 21, 22, 23, 25, 26, 27, 29, 30, 31, 32, 34, 35, 36, 37, 39, 40, 41, 43, 44, 45, 46, 48, 49, 50, 51, 53, 54, 55, 56, 58, 59, 60, 61, 62, 64, 65, 66, 67, 69, 70, 71, 72, 73, 75, 76, 77, 78, 79, 81, 82, 83, 84, 85, 87, 88, 89, 90, 91, 92, 94, 95, 96, 97, 98, 99, 101, 102, 103, 104, 105, 106, 107, 109, 110, 111, 112, 113, 114, 115, 116, 117, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 184, 185, 186, 187, 188, 189, 190, 191, 191, 192, 193, 194, 195, 196, 197, 197, 198, 199, 200, 201, 201, 202, 203, 204, 205, 206, 206, 207, 208, 209, 210, 210, 211, 212, 213, 213, 214, 215, 216, 216, 217, 218, 219, 220, 220, 221, 222, 223, 223, 224, 225, 226, 226, 227, 228, 228, 229, 230, 231, 231, 232, 233, 234, 234, 235, 236, 237, 237, 238, 239, 239, 240, 241, 242, 242, 243, 244, 244, 245, 246, 247, 247, 248, 249, 249, 250, 251, 251, 252, 253, 254, 254, 255 }; for (int i = 0; i < 256; i++){ arrayOfByte[(i * 4)] = ((byte)arrayOfInt1[i]); arrayOfByte[(1 + i * 4)] = ((byte)arrayOfInt2[i]); arrayOfByte[(2 + i * 4)] = ((byte)arrayOfInt3[i]); arrayOfByte[(3 + i * 4)] = -1; } int[] arrayOfInt4 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 17, 18, 19, 20, 21, 22, 23, 24, 25, 27, 28, 29, 30, 31, 32, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 60, 61, 62, 63, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 123, 124, 125, 126, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 164, 165, 166, 167, 168, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 200, 201, 202, 203, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 224, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 255, 255, 255, 255, 255 }; int[] arrayOfInt5 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 126, 127, 128, 129, 130, 131, 132, 133, 135, 136, 137, 138, 139, 140, 141, 142, 143, 145, 146, 147, 148, 149, 150, 151, 152, 154, 155, 156, 157, 158, 159, 160, 161, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 223, 224, 225, 226, 227, 228, 229, 229, 230, 231, 232, 233, 233, 234, 235, 236, 237, 237, 238, 239, 240, 240, 241, 242, 243, 243, 244, 245, 245, 246, 247, 247, 248, 249, 249, 250, 250, 251, 252, 252, 253, 253, 254, 254, 255 }; int[] arrayOfInt6 = { 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 8, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 20, 20, 20, 21, 21, 21, 22, 22, 23, 23, 23, 24, 24, 24, 25, 25, 25, 25, 26, 26, 27, 27, 28, 28, 28, 28, 29, 29, 30, 29, 31, 31, 31, 31, 32, 32, 33, 33, 34, 34, 34, 34, 35, 35, 36, 36, 37, 37, 37, 38, 38, 39, 39, 39, 40, 40, 40, 41, 42, 42, 43, 43, 44, 44, 45, 45, 45, 46, 47, 47, 48, 48, 49, 50, 51, 51, 52, 52, 53, 53, 54, 55, 55, 56, 57, 57, 58, 59, 60, 60, 61, 62, 63, 63, 64, 65, 66, 67, 68, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 88, 89, 90, 91, 93, 94, 95, 96, 97, 98, 100, 101, 103, 104, 105, 107, 108, 110, 111, 113, 115, 116, 118, 119, 120, 122, 123, 125, 127, 128, 130, 132, 134, 135, 137, 139, 141, 143, 144, 146, 148, 150, 152, 154, 156, 158, 160, 163, 165, 167, 169, 171, 173, 175, 178, 180, 182, 185, 187, 189, 192, 194, 197, 199, 201, 204, 206, 209, 211, 214, 216, 219, 221, 224, 226, 229, 232, 234, 236, 239, 241, 245, 247, 250, 252, 255 }; for (int j = 0; j < 256; j++){ arrayOfByte[(1024 + j * 4)] = ((byte)arrayOfInt5[j]); arrayOfByte[(1 + (1024 + j * 4))] = ((byte)arrayOfInt4[j]); arrayOfByte[(2 + (1024 + j * 4))] = ((byte)arrayOfInt6[j]); arrayOfByte[(3 + (1024 + j * 4))] = -1; } GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, 256, 2, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, ByteBuffer.wrap(arrayOfByte)); } }); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/advanced/MagicEvergreenFilter.java ================================================ package com.zero.magicshow.core.filter.advanced; import android.opengl.GLES20; import com.zero.magicshow.R; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.common.utils.OpenGlUtils; import java.nio.ByteBuffer; public class MagicEvergreenFilter extends GPUImageFilter{ private int[] mToneCurveTexture = {-1}; private int mToneCurveTextureUniformLocation; public MagicEvergreenFilter(){ super(NO_FILTER_VERTEX_SHADER, OpenGlUtils.readShaderFromRawResource(R.raw.evergreen)); } protected void onDestroy(){ super.onDestroy(); GLES20.glDeleteTextures(1, mToneCurveTexture, 0); mToneCurveTexture[0] = -1; } protected void onDrawArraysAfter(){ if (mToneCurveTexture[0] != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE3); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } } protected void onDrawArraysPre(){ if (mToneCurveTexture[0] != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE3); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mToneCurveTexture[0]); GLES20.glUniform1i(mToneCurveTextureUniformLocation, 3); } } protected void onInit(){ super.onInit(); mToneCurveTextureUniformLocation = GLES20.glGetUniformLocation(mGLProgId, "curve"); } protected void onInitialized(){ super.onInitialized(); runOnDraw(new Runnable(){ public void run(){ GLES20.glGenTextures(1, mToneCurveTexture, 0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mToneCurveTexture[0]); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); byte[] arrayOfByte = new byte[1024]; int[] arrayOfInt1 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 }; int[] arrayOfInt2 = { 0, 1, 1, 2, 3, 4, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 15, 16, 17, 17, 18, 19, 20, 21, 21, 22, 23, 24, 24, 25, 26, 27, 28, 28, 29, 30, 31, 32, 32, 33, 34, 35, 36, 37, 38, 38, 39, 40, 41, 42, 43, 44, 45, 46, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 90, 91, 92, 93, 94, 95, 96, 97, 99, 100, 101, 102, 103, 104, 105, 107, 108, 109, 110, 111, 112, 113, 115, 116, 117, 118, 119, 120, 122, 123, 124, 125, 126, 127, 129, 130, 131, 132, 133, 135, 136, 137, 138, 139, 140, 142, 143, 144, 145, 146, 148, 149, 150, 151, 152, 153, 155, 156, 157, 158, 159, 160, 162, 163, 164, 165, 166, 167, 169, 170, 171, 172, 173, 174, 175, 177, 178, 179, 180, 181, 182, 183, 185, 186, 187, 188, 189, 190, 191, 192, 193, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 241, 242, 243, 244, 245, 246, 247, 247, 248, 249, 250, 251, 252, 252, 253, 254, 255 }; int[] arrayOfInt3 = { 0, 2, 4, 6, 8, 10, 11, 13, 16, 17, 19, 20, 21, 23, 24, 25, 27, 28, 29, 31, 32, 33, 34, 36, 38, 39, 40, 42, 43, 44, 45, 46, 48, 49, 50, 51, 52, 53, 54, 56, 58, 59, 60, 61, 62, 63, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 76, 77, 78, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 128, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 144, 145, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 157, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 168, 169, 170, 171, 172, 173, 175, 176, 177, 177, 178, 179, 180, 181, 182, 183, 184, 185, 185, 186, 187, 188, 190, 191, 192, 193, 193, 194, 195, 196, 197, 198, 199, 200, 200, 201, 202, 203, 205, 206, 207, 207, 208, 209, 210, 211, 212, 213, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 225, 226, 227, 228, 229, 230, 231, 231, 232, 234, 235, 236, 237, 237, 238, 239, 240, 241, 242, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 252, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }; int[] arrayOfInt4 = { 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 8, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 20, 20, 20, 21, 21, 21, 22, 22, 23, 23, 23, 24, 24, 24, 25, 25, 25, 25, 26, 26, 27, 27, 28, 28, 28, 28, 29, 29, 30, 29, 31, 31, 31, 31, 32, 32, 33, 33, 34, 34, 34, 34, 35, 35, 36, 36, 37, 37, 37, 38, 38, 39, 39, 39, 40, 40, 40, 41, 42, 42, 43, 43, 44, 44, 45, 45, 45, 46, 47, 47, 48, 48, 49, 50, 51, 51, 52, 52, 53, 53, 54, 55, 55, 56, 57, 57, 58, 59, 60, 60, 61, 62, 63, 63, 64, 65, 66, 67, 68, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 88, 89, 90, 91, 93, 94, 95, 96, 97, 98, 100, 101, 103, 104, 105, 107, 108, 110, 111, 113, 115, 116, 118, 119, 120, 122, 123, 125, 127, 128, 130, 132, 134, 135, 137, 139, 141, 143, 144, 146, 148, 150, 152, 154, 156, 158, 160, 163, 165, 167, 169, 171, 173, 175, 178, 180, 182, 185, 187, 189, 192, 194, 197, 199, 201, 204, 206, 209, 211, 214, 216, 219, 221, 224, 226, 229, 232, 234, 236, 239, 241, 245, 247, 250, 252, 255 }; for (int i = 0; i < 256; i++) { arrayOfByte[(i * 4)] = ((byte)arrayOfInt1[i]); arrayOfByte[(1 + i * 4)] = ((byte)arrayOfInt2[i]); arrayOfByte[(2 + i * 4)] = ((byte)arrayOfInt3[i]); arrayOfByte[(3 + i * 4)] = ((byte)arrayOfInt4[i]); } GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, 256, 1, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, ByteBuffer.wrap(arrayOfByte)); } }); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/advanced/MagicFairytaleFilter.java ================================================ package com.zero.magicshow.core.filter.advanced; import com.zero.magicshow.core.filter.base.MagicLookupFilter; public class MagicFairytaleFilter extends MagicLookupFilter{ public MagicFairytaleFilter() { super("filter/fairy_tale.png"); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/advanced/MagicFreudFilter.java ================================================ package com.zero.magicshow.core.filter.advanced; import android.opengl.GLES20; import com.zero.magicshow.R; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.common.utils.MagicParams; import com.zero.magicshow.common.utils.OpenGlUtils; public class MagicFreudFilter extends GPUImageFilter{ private int mTexelHeightUniformLocation; private int mTexelWidthUniformLocation; private int[] inputTextureHandles = {-1}; private int[] inputTextureUniformLocations = {-1}; private int mGLStrengthLocation; public MagicFreudFilter(){ super(NO_FILTER_VERTEX_SHADER, OpenGlUtils.readShaderFromRawResource(R.raw.freud)); } protected void onDestroy() { super.onDestroy(); GLES20.glDeleteTextures(1, inputTextureHandles, 0); for(int i = 0; i < inputTextureHandles.length; i++) inputTextureHandles[i] = -1; } protected void onDrawArraysAfter(){ for(int i = 0; i < inputTextureHandles.length && inputTextureHandles[i] != OpenGlUtils.NO_TEXTURE; i++){ GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + (i+3)); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } } protected void onDrawArraysPre(){ for(int i = 0; i < inputTextureHandles.length && inputTextureHandles[i] != OpenGlUtils.NO_TEXTURE; i++){ GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + (i+3) ); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, inputTextureHandles[i]); GLES20.glUniform1i(inputTextureUniformLocations[i], (i+3)); } } protected void onInit(){ super.onInit(); inputTextureUniformLocations[0] = GLES20.glGetUniformLocation(getProgram(), "inputImageTexture2"); mTexelWidthUniformLocation = GLES20.glGetUniformLocation(getProgram(), "inputImageTextureWidth"); mTexelHeightUniformLocation = GLES20.glGetUniformLocation(getProgram(), "inputImageTextureHeight"); mGLStrengthLocation = GLES20.glGetUniformLocation(mGLProgId, "strength"); } protected void onInitialized(){ super.onInitialized(); setFloat(mGLStrengthLocation, 1.0f); runOnDraw(new Runnable(){ public void run(){ inputTextureHandles[0] = OpenGlUtils.loadTexture(MagicParams.context, "filter/freud_rand.png"); } }); } public void onInputSizeChanged(int width, int height) { super.onInputSizeChanged(width, height); GLES20.glUniform1f(mTexelWidthUniformLocation, (float)width); GLES20.glUniform1f(mTexelHeightUniformLocation, (float)height); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/advanced/MagicHealthyFilter.java ================================================ package com.zero.magicshow.core.filter.advanced; import android.opengl.GLES20; import com.zero.magicshow.R; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.common.utils.MagicParams; import com.zero.magicshow.common.utils.OpenGlUtils; import java.nio.ByteBuffer; public class MagicHealthyFilter extends GPUImageFilter{ private int[] mToneCurveTexture = {-1}; private int mToneCurveTextureUniformLocation; private int mMaskGrey1TextureId = -1; private int mMaskGrey1UniformLocation; private int mTexelHeightUniformLocation; private int mTexelWidthUniformLocation; public MagicHealthyFilter(){ super(NO_FILTER_VERTEX_SHADER, OpenGlUtils.readShaderFromRawResource(R.raw.healthy)); } protected void onDestroy(){ super.onDestroy(); GLES20.glDeleteTextures(1, mToneCurveTexture, 0); mToneCurveTexture[0] = -1; int[] texture = new int[1]; texture[0] = mMaskGrey1TextureId; GLES20.glDeleteTextures(1, texture, 0); mMaskGrey1TextureId = -1; } protected void onDrawArraysAfter(){ if (mToneCurveTexture[0] != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE3); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } if (mMaskGrey1TextureId != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE4); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } } protected void onDrawArraysPre(){ if (mToneCurveTexture[0] != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE3); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mToneCurveTexture[0]); GLES20.glUniform1i(mToneCurveTextureUniformLocation, 3); } if (mMaskGrey1TextureId != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE4); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mMaskGrey1TextureId); GLES20.glUniform1i(mMaskGrey1UniformLocation, 4); } } protected void onInit(){ super.onInit(); mToneCurveTextureUniformLocation = GLES20.glGetUniformLocation(mGLProgId, "curve"); mMaskGrey1UniformLocation = GLES20.glGetUniformLocation(getProgram(), "mask"); mTexelWidthUniformLocation = GLES20.glGetUniformLocation(getProgram(), "texelWidthOffset"); mTexelHeightUniformLocation = GLES20.glGetUniformLocation(getProgram(), "texelHeightOffset"); } protected void onInitialized(){ super.onInitialized(); runOnDraw(new Runnable(){ public void run(){ GLES20.glGenTextures(1, mToneCurveTexture, 0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mToneCurveTexture[0]); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); byte[] arrayOfByte = new byte[1024]; int[] arrayOfInt1 = { 95, 95, 96, 97, 97, 98, 99, 99, 100, 101, 101, 102, 103, 104, 104, 105, 106, 106, 107, 108, 108, 109, 110, 111, 111, 112, 113, 113, 114, 115, 115, 116, 117, 117, 118, 119, 120, 120, 121, 122, 122, 123, 124, 124, 125, 126, 127, 127, 128, 129, 129, 130, 131, 131, 132, 133, 133, 134, 135, 136, 136, 137, 138, 138, 139, 140, 140, 141, 142, 143, 143, 144, 145, 145, 146, 147, 147, 148, 149, 149, 150, 151, 152, 152, 153, 154, 154, 155, 156, 156, 157, 158, 159, 159, 160, 161, 161, 162, 163, 163, 164, 165, 165, 166, 167, 168, 168, 169, 170, 170, 171, 172, 172, 173, 174, 175, 175, 176, 177, 177, 178, 179, 179, 180, 181, 181, 182, 183, 184, 184, 185, 186, 186, 187, 188, 188, 189, 190, 191, 191, 192, 193, 193, 194, 195, 195, 196, 197, 197, 198, 199, 200, 200, 201, 202, 202, 203, 204, 204, 205, 206, 207, 207, 208, 209, 209, 210, 211, 211, 212, 213, 213, 214, 215, 216, 216, 217, 218, 218, 219, 220, 220, 221, 222, 223, 223, 224, 225, 225, 226, 227, 227, 228, 229, 229, 230, 231, 232, 232, 233, 234, 234, 235, 236, 236, 237, 238, 239, 239, 240, 241, 241, 242, 243, 243, 244, 245, 245, 246, 247, 248, 248, 249, 250, 250, 251, 252, 252, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }; int[] arrayOfInt2 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 4, 5, 7, 8, 9, 12, 13, 14, 15, 16, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 41, 42, 43, 44, 45, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 60, 61, 62, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 168, 169, 170, 171, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 189, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 204, 205, 206, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 219, 220, 221, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 234, 235, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 249, 249, 250, 251, 252, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 }; int[] arrayOfInt3 = { 0, 1, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10, 10, 11, 12, 13, 14, 15, 16, 17, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 95, 96, 97, 98, 99, 100, 101, 102, 103, 105, 106, 107, 108, 109, 110, 111, 112, 114, 115, 116, 117, 118, 119, 120, 121, 122, 124, 125, 126, 127, 128, 129, 130, 131, 132, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 249, 250, 251, 252, 253, 254, 255 }; for (int i = 0; i < 256; i++) { arrayOfByte[(i * 4)] = ((byte)arrayOfInt3[i]); arrayOfByte[(1 + i * 4)] = ((byte)arrayOfInt2[i]); arrayOfByte[(2 + i * 4)] = ((byte)arrayOfInt1[i]); arrayOfByte[(3 + i * 4)] = -1; } GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, 256, 1, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, ByteBuffer.wrap(arrayOfByte)); mMaskGrey1TextureId = OpenGlUtils.loadTexture(MagicParams.context, "filter/healthy_mask_1.jpg"); } }); } public void onInputSizeChanged(int width, int height){ super.onInputSizeChanged(width, height); GLES20.glUniform1f(mTexelWidthUniformLocation, 1.0f / width); GLES20.glUniform1f(mTexelHeightUniformLocation, 1.0f / height); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/advanced/MagicHefeFilter.java ================================================ package com.zero.magicshow.core.filter.advanced; import android.opengl.GLES20; import com.zero.magicshow.R; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.common.utils.MagicParams; import com.zero.magicshow.common.utils.OpenGlUtils; public class MagicHefeFilter extends GPUImageFilter{ private int[] inputTextureHandles = {-1,-1,-1,-1}; private int[] inputTextureUniformLocations = {-1,-1,-1,-1}; private int mGLStrengthLocation; public MagicHefeFilter(){ super(NO_FILTER_VERTEX_SHADER, OpenGlUtils.readShaderFromRawResource(R.raw.hefe)); } protected void onDestroy() { super.onDestroy(); GLES20.glDeleteTextures(inputTextureHandles.length, inputTextureHandles, 0); for(int i = 0; i < inputTextureHandles.length; i++) inputTextureHandles[i] = -1; } protected void onDrawArraysAfter(){ for(int i = 0; i < inputTextureHandles.length && inputTextureHandles[i] != OpenGlUtils.NO_TEXTURE; i++){ GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + (i+3)); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } } protected void onDrawArraysPre(){ for(int i = 0; i < inputTextureHandles.length && inputTextureHandles[i] != OpenGlUtils.NO_TEXTURE; i++){ GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + (i+3) ); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, inputTextureHandles[i]); GLES20.glUniform1i(inputTextureUniformLocations[i], (i+3)); } } protected void onInit(){ super.onInit(); for(int i=0; i < inputTextureUniformLocations.length; i++) inputTextureUniformLocations[i] = GLES20.glGetUniformLocation(getProgram(), "inputImageTexture"+(2+i)); mGLStrengthLocation = GLES20.glGetUniformLocation(mGLProgId, "strength"); } protected void onInitialized(){ super.onInitialized(); setFloat(mGLStrengthLocation, 1.0f); runOnDraw(new Runnable(){ public void run(){ inputTextureHandles[0] = OpenGlUtils.loadTexture(MagicParams.context, "filter/edgeburn.png"); inputTextureHandles[1] = OpenGlUtils.loadTexture(MagicParams.context, "filter/hefemap.png"); inputTextureHandles[2] = OpenGlUtils.loadTexture(MagicParams.context, "filter/hefemetal.png"); inputTextureHandles[3] = OpenGlUtils.loadTexture(MagicParams.context, "filter/hefesoftlight.png"); } }); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/advanced/MagicHudsonFilter.java ================================================ package com.zero.magicshow.core.filter.advanced; import android.opengl.GLES20; import com.zero.magicshow.R; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.common.utils.MagicParams; import com.zero.magicshow.common.utils.OpenGlUtils; public class MagicHudsonFilter extends GPUImageFilter{ private int[] inputTextureHandles = {-1,-1,-1}; private int[] inputTextureUniformLocations = {-1,-1,-1}; private int mGLStrengthLocation; public MagicHudsonFilter(){ super(NO_FILTER_VERTEX_SHADER, OpenGlUtils.readShaderFromRawResource(R.raw.hudson)); } protected void onDestroy() { super.onDestroy(); GLES20.glDeleteTextures(inputTextureHandles.length, inputTextureHandles, 0); for(int i = 0; i < inputTextureHandles.length; i++) inputTextureHandles[i] = -1; } protected void onDrawArraysAfter(){ for(int i = 0; i < inputTextureHandles.length && inputTextureHandles[i] != OpenGlUtils.NO_TEXTURE; i++){ GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + (i+3)); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } } protected void onDrawArraysPre(){ for(int i = 0; i < inputTextureHandles.length && inputTextureHandles[i] != OpenGlUtils.NO_TEXTURE; i++){ GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + (i+3) ); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, inputTextureHandles[i]); GLES20.glUniform1i(inputTextureUniformLocations[i], (i+3)); } } protected void onInit(){ super.onInit(); for(int i=0; i < inputTextureUniformLocations.length; i++) inputTextureUniformLocations[i] = GLES20.glGetUniformLocation(getProgram(), "inputImageTexture"+(2+i)); mGLStrengthLocation = GLES20.glGetUniformLocation(mGLProgId, "strength"); } protected void onInitialized(){ super.onInitialized(); setFloat(mGLStrengthLocation, 1.0f); runOnDraw(new Runnable(){ public void run(){ inputTextureHandles[0] = OpenGlUtils.loadTexture(MagicParams.context, "filter/hudsonbackground.png"); inputTextureHandles[1] = OpenGlUtils.loadTexture(MagicParams.context, "filter/overlaymap.png"); inputTextureHandles[2] = OpenGlUtils.loadTexture(MagicParams.context, "filter/hudsonmap.png"); } }); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/advanced/MagicImageAdjustFilter.java ================================================ package com.zero.magicshow.core.filter.advanced; import com.zero.magicshow.core.filter.base.MagicBaseGroupFilter; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageBrightnessFilter; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageContrastFilter; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageExposureFilter; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageHueFilter; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageSaturationFilter; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageSharpenFilter; import com.zero.magicshow.core.filter.utils.MagicFilterType; import java.util.ArrayList; import java.util.List; public class MagicImageAdjustFilter extends MagicBaseGroupFilter{ public MagicImageAdjustFilter() { super(initFilters()); } private static List initFilters(){ List filters = new ArrayList(); filters.add(new GPUImageContrastFilter()); filters.add(new GPUImageBrightnessFilter()); filters.add(new GPUImageExposureFilter()); filters.add(new GPUImageHueFilter()); filters.add(new GPUImageSaturationFilter()); filters.add(new GPUImageSharpenFilter()); return filters; } public void setImageFilter(float range,MagicFilterType type){ switch (type){ case CONTRAST: setContrast(range); break; case BRIGHTNESS: setBrightness(range); break; case EXPOSURE: setExposure(range); break; case HUE: setHue(range); break; case SATURATION: setSaturation(range); break; case SHARPEN: setSharpness(range); break; } } public void setSharpness(final float range){ ((GPUImageSharpenFilter) filters.get(5)).setSharpness(range); } public void setHue(final float range){ ((GPUImageHueFilter) filters.get(3)).setHue(range); } public void setBrightness(final float range){ ((GPUImageBrightnessFilter) filters.get(1)).setBrightness(range); } public void setContrast(final float range){ ((GPUImageContrastFilter) filters.get(0)).setContrast(range); } public void setSaturation(final float range){ ((GPUImageSaturationFilter) filters.get(4)).setSaturation(range); } public void setExposure(final float range){ ((GPUImageExposureFilter) filters.get(2)).setExposure(range); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/advanced/MagicInkwellFilter.java ================================================ package com.zero.magicshow.core.filter.advanced; import android.opengl.GLES20; import com.zero.magicshow.R; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.common.utils.MagicParams; import com.zero.magicshow.common.utils.OpenGlUtils; public class MagicInkwellFilter extends GPUImageFilter{ private int[] inputTextureHandles = {-1}; private int[] inputTextureUniformLocations = {-1}; private int mGLStrengthLocation; public MagicInkwellFilter(){ super(NO_FILTER_VERTEX_SHADER, OpenGlUtils.readShaderFromRawResource(R.raw.inkwell)); } public void onDestroy() { super.onDestroy(); GLES20.glDeleteTextures(1, inputTextureHandles, 0); for(int i = 0; i < inputTextureHandles.length; i++) inputTextureHandles[i] = -1; } protected void onDrawArraysAfter(){ for(int i = 0; i < inputTextureHandles.length && inputTextureHandles[i] != OpenGlUtils.NO_TEXTURE; i++){ GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + (i+3)); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } } protected void onDrawArraysPre(){ for(int i = 0; i < inputTextureHandles.length && inputTextureHandles[i] != OpenGlUtils.NO_TEXTURE; i++){ GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + (i+3) ); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, inputTextureHandles[i]); GLES20.glUniform1i(inputTextureUniformLocations[i], (i+3)); } } protected void onInit(){ super.onInit(); for(int i=0; i < inputTextureUniformLocations.length; i++) inputTextureUniformLocations[i] = GLES20.glGetUniformLocation(getProgram(), "inputImageTexture"+(2+i)); mGLStrengthLocation = GLES20.glGetUniformLocation(mGLProgId, "strength"); } protected void onInitialized(){ super.onInitialized(); setFloat(mGLStrengthLocation, 1.0f); runOnDraw(new Runnable(){ public void run(){ inputTextureHandles[0] = OpenGlUtils.loadTexture(MagicParams.context, "filter/inkwellmap.png"); } }); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/advanced/MagicKevinFilter.java ================================================ package com.zero.magicshow.core.filter.advanced; import android.opengl.GLES20; import com.zero.magicshow.R; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.common.utils.MagicParams; import com.zero.magicshow.common.utils.OpenGlUtils; public class MagicKevinFilter extends GPUImageFilter{ private int[] inputTextureHandles = {-1}; private int[] inputTextureUniformLocations = {-1}; private int mGLStrengthLocation; public MagicKevinFilter(){ super(NO_FILTER_VERTEX_SHADER, OpenGlUtils.readShaderFromRawResource(R.raw.kevin_new)); } protected void onDestroy() { super.onDestroy(); GLES20.glDeleteTextures(1, inputTextureHandles, 0); for(int i = 0; i < inputTextureHandles.length; i++) inputTextureHandles[i] = -1; } protected void onDrawArraysAfter(){ for(int i = 0; i < inputTextureHandles.length && inputTextureHandles[i] != OpenGlUtils.NO_TEXTURE; i++){ GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + (i+3)); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } } protected void onDrawArraysPre(){ for(int i = 0; i < inputTextureHandles.length && inputTextureHandles[i] != OpenGlUtils.NO_TEXTURE; i++){ GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + (i+3) ); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, inputTextureHandles[i]); GLES20.glUniform1i(inputTextureUniformLocations[i], (i+3)); } } protected void onInit(){ super.onInit(); for(int i=0; i < inputTextureUniformLocations.length; i++) inputTextureUniformLocations[i] = GLES20.glGetUniformLocation(getProgram(), "inputImageTexture"+(2+i)); mGLStrengthLocation = GLES20.glGetUniformLocation(mGLProgId, "strength"); } protected void onInitialized(){ super.onInitialized(); setFloat(mGLStrengthLocation, 1.0f); runOnDraw(new Runnable(){ public void run(){ inputTextureHandles[0] = OpenGlUtils.loadTexture(MagicParams.context, "filter/kelvinmap.png"); } }); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/advanced/MagicLatteFilter.java ================================================ package com.zero.magicshow.core.filter.advanced; import android.opengl.GLES20; import com.zero.magicshow.R; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.common.utils.OpenGlUtils; import java.nio.ByteBuffer; public class MagicLatteFilter extends GPUImageFilter{ private int[] mToneCurveTexture = {-1}; private int mToneCurveTextureUniformLocation; public MagicLatteFilter(){ super(NO_FILTER_VERTEX_SHADER, OpenGlUtils.readShaderFromRawResource(R.raw.latte)); } protected void onDestroy(){ super.onDestroy(); GLES20.glDeleteTextures(1, mToneCurveTexture, 0); mToneCurveTexture[0] = -1; } protected void onDrawArraysAfter(){ if (mToneCurveTexture[0] != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE3); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } } protected void onDrawArraysPre(){ if (mToneCurveTexture[0] != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE3); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mToneCurveTexture[0]); GLES20.glUniform1i(mToneCurveTextureUniformLocation, 3); } } protected void onInit(){ super.onInit(); mToneCurveTextureUniformLocation = GLES20.glGetUniformLocation(mGLProgId, "curve"); } protected void onInitialized(){ super.onInitialized(); runOnDraw(new Runnable(){ public void run(){ GLES20.glGenTextures(1, mToneCurveTexture, 0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mToneCurveTexture[0]); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); byte[] arrayOfByte = new byte[2048]; int[] arrayOfInt1 = { 5, 6, 8, 9, 11, 12, 14, 15, 16, 18, 19, 21, 22, 23, 25, 26, 28, 29, 30, 32, 33, 34, 36, 37, 39, 40, 41, 43, 44, 45, 46, 48, 49, 50, 52, 53, 54, 55, 56, 58, 59, 60, 61, 62, 64, 65, 66, 67, 68, 69, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 108, 109, 110, 111, 112, 113, 114, 115, 115, 116, 117, 118, 119, 120, 120, 121, 122, 123, 124, 125, 125, 126, 127, 128, 129, 130, 130, 131, 132, 133, 134, 134, 135, 136, 137, 137, 138, 139, 140, 141, 141, 142, 143, 144, 145, 145, 146, 147, 148, 148, 149, 150, 151, 151, 152, 153, 154, 155, 155, 156, 157, 158, 158, 159, 160, 161, 162, 162, 163, 164, 165, 166, 166, 167, 168, 169, 170, 170, 171, 172, 173, 174, 174, 175, 176, 177, 178, 178, 179, 180, 181, 182, 183, 183, 184, 185, 186, 187, 188, 189, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 }; int[] arrayOfInt2 = { 5, 6, 8, 11, 12, 14, 15, 18, 19, 21, 22, 25, 26, 28, 29, 32, 33, 34, 36, 39, 40, 41, 43, 44, 46, 48, 49, 50, 52, 54, 55, 56, 58, 59, 61, 62, 64, 65, 66, 67, 69, 71, 72, 73, 74, 75, 76, 78, 79, 80, 81, 82, 83, 85, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 108, 108, 109, 110, 111, 112, 113, 114, 115, 115, 116, 117, 118, 119, 120, 120, 121, 122, 123, 125, 125, 126, 127, 128, 129, 130, 130, 131, 132, 133, 134, 134, 135, 136, 137, 137, 138, 139, 140, 141, 141, 142, 143, 144, 145, 145, 146, 147, 148, 148, 149, 149, 150, 151, 151, 152, 153, 154, 155, 155, 156, 157, 158, 158, 159, 160, 161, 162, 162, 163, 164, 165, 165, 166, 166, 167, 168, 169, 170, 170, 171, 172, 173, 174, 174, 175, 175, 176, 177, 178, 178, 179, 180, 181, 182, 183, 183, 184, 184, 185, 186, 187, 188, 189, 189, 190, 191, 192, 192, 193, 194, 195, 196, 197, 198, 198, 199, 199, 200, 201, 202, 203, 204, 205, 206, 206, 207, 208, 209, 210, 211, 212, 213, 213, 214, 215, 215, 216, 217, 218, 219, 219, 220, 221, 222, 223, 224, 225, 226, 226, 227, 228, 229, 230, 231, 232, 232, 233, 234, 235, 237, 238, 239, 240, 240, 241, 242, 243, 244, 245, 246, 246, 247, 248, 249, 250, 251, 252, 252, 253, 254, 255 }; int[] arrayOfInt3 = { 5, 6, 8, 11, 12, 14, 15, 16, 18, 21, 22, 23, 25, 26, 28, 30, 32, 33, 34, 36, 37, 40, 41, 43, 44, 45, 46, 49, 50, 52, 53, 54, 55, 58, 59, 60, 61, 62, 64, 66, 67, 68, 69, 71, 72, 73, 75, 76, 77, 78, 79, 80, 81, 83, 85, 86, 87, 88, 89, 90, 92, 93, 94, 95, 95, 96, 97, 98, 99, 101, 102, 103, 104, 105, 106, 107, 108, 108, 109, 111, 112, 113, 114, 115, 115, 116, 117, 118, 119, 120, 120, 121, 123, 124, 125, 125, 126, 127, 128, 129, 130, 130, 131, 132, 133, 134, 134, 135, 136, 137, 137, 138, 139, 140, 141, 141, 142, 143, 144, 145, 145, 146, 147, 148, 148, 149, 150, 151, 151, 152, 153, 154, 155, 155, 156, 156, 157, 158, 158, 159, 160, 161, 162, 162, 163, 164, 165, 165, 166, 166, 167, 168, 169, 170, 170, 170, 171, 172, 173, 174, 174, 175, 176, 176, 177, 178, 178, 179, 180, 180, 181, 182, 183, 183, 184, 184, 185, 186, 187, 188, 189, 189, 189, 190, 191, 192, 192, 193, 194, 195, 196, 196, 197, 198, 198, 199, 199, 200, 201, 202, 202, 203, 204, 205, 206, 206, 207, 208, 209, 209, 210, 211, 212, 213, 213, 214, 215, 215, 215, 216, 217, 218, 218, 219, 220, 221, 221, 222, 223, 224, 224, 225, 226, 227, 227, 228, 229, 230, 230, 231, 232, 233, 233, 234, 235, 237, 237, 238, 239, 240, 240, 241, 242, 243, 243, 244 }; for (int i = 0; i < 256; i++){ arrayOfByte[(i * 4)] = ((byte)arrayOfInt1[i]); arrayOfByte[(1 + i * 4)] = ((byte)arrayOfInt2[i]); arrayOfByte[(2 + i * 4)] = ((byte)arrayOfInt3[i]); arrayOfByte[(3 + i * 4)] = -1; } int[] arrayOfInt4 = { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 10, 12, 13, 14, 15, 16, 18, 19, 20, 21, 22, 24, 25, 26, 27, 28, 30, 31, 32, 33, 34, 36, 37, 38, 39, 40, 42, 43, 44, 45, 46, 48, 49, 50, 51, 52, 54, 55, 56, 57, 58, 60, 61, 62, 63, 64, 66, 67, 68, 69, 71, 72, 73, 74, 75, 77, 78, 79, 80, 81, 83, 84, 85, 86, 87, 89, 90, 91, 92, 93, 95, 96, 97, 98, 99, 101, 102, 103, 104, 105, 107, 108, 109, 110, 111, 113, 114, 115, 116, 117, 119, 120, 121, 122, 123, 125, 126, 127, 128, 129, 131, 132, 133, 134, 135, 137, 138, 139, 140, 141, 143, 144, 145, 146, 147, 149, 150, 151, 152, 153, 155, 156, 157, 158, 159, 161, 162, 163, 164, 165, 167, 168, 169, 170, 171, 173, 174, 175, 176, 177, 179, 180, 181, 182, 184, 185, 186, 187, 188, 190, 191, 192, 193, 194, 196, 197, 198, 199, 200, 202, 203, 204, 205, 206, 208, 209, 210, 211, 212, 214, 215, 216, 217, 218, 220, 221, 222, 223, 224, 226, 227, 228, 229, 230, 232, 233, 234, 235, 236, 238, 239, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240 }; int[] arrayOfInt5 = { 0, 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 23, 24, 25, 26, 27, 29, 30, 31, 32, 33, 35, 36, 37, 38, 39, 41, 42, 43, 44, 46, 47, 48, 49, 51, 52, 53, 54, 56, 57, 58, 59, 61, 62, 63, 65, 66, 67, 69, 70, 71, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89, 90, 92, 93, 94, 96, 97, 99, 100, 101, 103, 104, 106, 107, 108, 110, 111, 113, 114, 116, 117, 119, 120, 121, 123, 124, 126, 127, 129, 130, 132, 133, 135, 136, 138, 139, 140, 142, 143, 145, 146, 147, 149, 150, 151, 153, 154, 155, 157, 158, 159, 160, 162, 163, 164, 165, 167, 168, 169, 170, 171, 173, 174, 175, 176, 177, 178, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 210, 211, 212, 213, 214, 215, 215, 216, 217, 218, 219, 219, 220, 221, 222, 222, 223, 224, 225, 225, 226, 227, 227, 228, 229, 229, 230, 231, 231, 232, 233, 233, 234, 234, 235, 236, 236, 237, 237, 238, 238, 239, 240, 240, 241, 241, 242, 242, 243, 243, 244, 244, 244, 245, 245, 246, 246, 247, 247, 247, 248, 248, 249, 249, 249, 250, 250, 250, 251, 251, 251, 252, 252, 252, 252, 253, 253, 253, 253, 254, 254, 254, 254, 255, 255, 255 }; int[] arrayOfInt6 = { 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 8, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 20, 20, 20, 21, 21, 21, 22, 22, 23, 23, 23, 24, 24, 24, 25, 25, 25, 25, 26, 26, 27, 27, 28, 28, 28, 28, 29, 29, 30, 29, 31, 31, 31, 31, 32, 32, 33, 33, 34, 34, 34, 34, 35, 35, 36, 36, 37, 37, 37, 38, 38, 39, 39, 39, 40, 40, 40, 41, 42, 42, 43, 43, 44, 44, 45, 45, 45, 46, 47, 47, 48, 48, 49, 50, 51, 51, 52, 52, 53, 53, 54, 55, 55, 56, 57, 57, 58, 59, 60, 60, 61, 62, 63, 63, 64, 65, 66, 67, 68, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 88, 89, 90, 91, 93, 94, 95, 96, 97, 98, 100, 101, 103, 104, 105, 107, 108, 110, 111, 113, 115, 116, 118, 119, 120, 122, 123, 125, 127, 128, 130, 132, 134, 135, 137, 139, 141, 143, 144, 146, 148, 150, 152, 154, 156, 158, 160, 163, 165, 167, 169, 171, 173, 175, 178, 180, 182, 185, 187, 189, 192, 194, 197, 199, 201, 204, 206, 209, 211, 214, 216, 219, 221, 224, 226, 229, 232, 234, 236, 239, 241, 245, 247, 250, 252, 255 }; for (int j = 0; j < 256; j++){ arrayOfByte[(1024 + j * 4)] = ((byte)arrayOfInt5[j]); arrayOfByte[(1 + (1024 + j * 4))] = ((byte)arrayOfInt4[j]); arrayOfByte[(2 + (1024 + j * 4))] = ((byte)arrayOfInt6[j]); arrayOfByte[(3 + (1024 + j * 4))] = -1; } GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, 256, 2, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, ByteBuffer.wrap(arrayOfByte)); } }); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/advanced/MagicLomoFilter.java ================================================ package com.zero.magicshow.core.filter.advanced; import android.opengl.GLES20; import com.zero.magicshow.R; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.common.utils.MagicParams; import com.zero.magicshow.common.utils.OpenGlUtils; public class MagicLomoFilter extends GPUImageFilter{ private int[] inputTextureHandles = {-1,-1}; private int[] inputTextureUniformLocations = {-1,-1}; private int mGLStrengthLocation; public MagicLomoFilter(){ super(NO_FILTER_VERTEX_SHADER, OpenGlUtils.readShaderFromRawResource(R.raw.lomo)); } protected void onDestroy() { super.onDestroy(); GLES20.glDeleteTextures(inputTextureHandles.length, inputTextureHandles, 0); for(int i = 0; i < inputTextureHandles.length; i++) inputTextureHandles[i] = -1; } protected void onDrawArraysAfter(){ for(int i = 0; i < inputTextureHandles.length && inputTextureHandles[i] != OpenGlUtils.NO_TEXTURE; i++){ GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + (i+3)); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } } protected void onDrawArraysPre(){ for(int i = 0; i < inputTextureHandles.length && inputTextureHandles[i] != OpenGlUtils.NO_TEXTURE; i++){ GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + (i+3) ); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, inputTextureHandles[i]); GLES20.glUniform1i(inputTextureUniformLocations[i], (i+3)); } } protected void onInit(){ super.onInit(); for(int i=0; i < inputTextureUniformLocations.length; i++) inputTextureUniformLocations[i] = GLES20.glGetUniformLocation(getProgram(), "inputImageTexture"+(2+i)); mGLStrengthLocation = GLES20.glGetUniformLocation(mGLProgId, "strength"); } protected void onInitialized(){ super.onInitialized(); setFloat(mGLStrengthLocation, 1.0f); runOnDraw(new Runnable(){ public void run(){ inputTextureHandles[0] = OpenGlUtils.loadTexture(MagicParams.context, "filter/lomomap_new.png"); inputTextureHandles[1] = OpenGlUtils.loadTexture(MagicParams.context, "filter/vignette_map.png"); } }); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/advanced/MagicN1977Filter.java ================================================ package com.zero.magicshow.core.filter.advanced; import android.opengl.GLES20; import com.zero.magicshow.R; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.common.utils.MagicParams; import com.zero.magicshow.common.utils.OpenGlUtils; public class MagicN1977Filter extends GPUImageFilter{ private int[] inputTextureHandles = {-1,-1}; private int[] inputTextureUniformLocations = {-1,-1}; private int mGLStrengthLocation; public MagicN1977Filter(){ super(NO_FILTER_VERTEX_SHADER, OpenGlUtils.readShaderFromRawResource(R.raw.n1977)); } protected void onDrawArraysAfter(){ for(int i = 0; i < inputTextureHandles.length && inputTextureHandles[i] != OpenGlUtils.NO_TEXTURE; i++){ GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + (i+3)); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } } protected void onDrawArraysPre(){ for(int i = 0; i < inputTextureHandles.length && inputTextureHandles[i] != OpenGlUtils.NO_TEXTURE; i++){ GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + (i+3) ); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, inputTextureHandles[i]); GLES20.glUniform1i(inputTextureUniformLocations[i], (i+3)); } } protected void onInit(){ super.onInit(); for(int i=0; i < inputTextureUniformLocations.length; i++) inputTextureUniformLocations[i] = GLES20.glGetUniformLocation(getProgram(), "inputImageTexture"+(2+i)); mGLStrengthLocation = GLES20.glGetUniformLocation(mGLProgId, "strength"); } protected void onInitialized(){ super.onInitialized(); setFloat(mGLStrengthLocation, 1.0f); runOnDraw(new Runnable(){ public void run(){ inputTextureHandles[0] = OpenGlUtils.loadTexture(MagicParams.context, "filter/n1977map.png"); inputTextureHandles[1] = OpenGlUtils.loadTexture(MagicParams.context, "filter/n1977blowout.png"); } }); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/advanced/MagicNashvilleFilter.java ================================================ package com.zero.magicshow.core.filter.advanced; import android.opengl.GLES20; import com.zero.magicshow.R; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.common.utils.MagicParams; import com.zero.magicshow.common.utils.OpenGlUtils; public class MagicNashvilleFilter extends GPUImageFilter{ private int[] inputTextureHandles = {-1}; private int[] inputTextureUniformLocations = {-1}; private int mGLStrengthLocation; public MagicNashvilleFilter(){ super(NO_FILTER_VERTEX_SHADER, OpenGlUtils.readShaderFromRawResource(R.raw.nashville)); } public void onDestroy() { super.onDestroy(); GLES20.glDeleteTextures(1, inputTextureHandles, 0); for(int i = 0; i < inputTextureHandles.length; i++) inputTextureHandles[i] = -1; } protected void onDrawArraysAfter(){ for(int i = 0; i < inputTextureHandles.length && inputTextureHandles[i] != OpenGlUtils.NO_TEXTURE; i++){ GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + (i+3)); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } } protected void onDrawArraysPre(){ for(int i = 0; i < inputTextureHandles.length && inputTextureHandles[i] != OpenGlUtils.NO_TEXTURE; i++){ GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + (i+3) ); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, inputTextureHandles[i]); GLES20.glUniform1i(inputTextureUniformLocations[i], (i+3)); } } public void onInit(){ super.onInit(); for(int i=0; i < inputTextureUniformLocations.length; i++) inputTextureUniformLocations[i] = GLES20.glGetUniformLocation(getProgram(), "inputImageTexture"+(2+i)); mGLStrengthLocation = GLES20.glGetUniformLocation(mGLProgId, "strength"); } public void onInitialized(){ super.onInitialized(); setFloat(mGLStrengthLocation, 1.0f); runOnDraw(new Runnable(){ public void run(){ inputTextureHandles[0] = OpenGlUtils.loadTexture(MagicParams.context, "filter/nashvillemap.png"); } }); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/advanced/MagicNostalgiaFilter.java ================================================ package com.zero.magicshow.core.filter.advanced; import android.opengl.GLES20; import com.zero.magicshow.R; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.common.utils.OpenGlUtils; import java.nio.ByteBuffer; public class MagicNostalgiaFilter extends GPUImageFilter{ private int mBlurSizeUniformLocation; private int mTexelWidthUniformLocation; private int mTexelHeightUniformLocation; private int[] mToneCurveTexture = { -1 }; private int[] mToneCurveTexture2 = { -1 }; private int mToneCurveTextureUniformLocation; private int mToneCurveTextureUniformLocation2; public MagicNostalgiaFilter(){ super(NO_FILTER_VERTEX_SHADER, OpenGlUtils.readShaderFromRawResource(R.raw.nostalgia)); } public void onDestroy(){ super.onDestroy(); GLES20.glDeleteTextures(1, mToneCurveTexture, 0); mToneCurveTexture[0] = -1; GLES20.glDeleteTextures(1, mToneCurveTexture2, 0); mToneCurveTexture2[0] = -1; } protected void onDrawArraysAfter(){ if (mToneCurveTexture[0] != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE3); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } if (mToneCurveTexture2[0] != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE4); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } } protected void onDrawArraysPre(){ if (mToneCurveTexture[0] != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE3); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mToneCurveTexture[0]); GLES20.glUniform1i(mToneCurveTextureUniformLocation, 3); } if (mToneCurveTexture2[0] != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE4); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mToneCurveTexture[0]); GLES20.glUniform1i(mToneCurveTextureUniformLocation2, 4); } GLES20.glUniform1f(mBlurSizeUniformLocation, 1.0F); } public void onInit(){ super.onInit(); mToneCurveTextureUniformLocation = GLES20.glGetUniformLocation(mGLProgId, "curve"); mToneCurveTextureUniformLocation2 = GLES20.glGetUniformLocation(mGLProgId, "curve2"); mTexelWidthUniformLocation = GLES20.glGetUniformLocation(getProgram(), "texelWidthOffset"); mTexelHeightUniformLocation = GLES20.glGetUniformLocation(getProgram(), "texelHeightOffset"); mBlurSizeUniformLocation = GLES20.glGetUniformLocation(getProgram(), "blurSize"); } public void onInitialized(){ super.onInitialized(); runOnDraw(new Runnable(){ public void run(){ GLES20.glGenTextures(1, mToneCurveTexture, 0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mToneCurveTexture[0]); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); byte[] arrayOfByte1 = new byte[2048]; int[] arrayOfInt1 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 5, 6, 8, 9, 11, 13, 15, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 39, 41, 43, 45, 47, 49, 50, 52, 54, 56, 57, 59, 61, 62, 64, 66, 68, 69, 71, 72, 74, 76, 77, 79, 80, 82, 84, 85, 87, 88, 90, 91, 93, 94, 96, 97, 98, 100, 101, 103, 104, 106, 107, 108, 110, 111, 112, 114, 115, 116, 118, 119, 120, 122, 123, 124, 125, 127, 128, 129, 130, 131, 133, 134, 135, 136, 137, 138, 140, 141, 142, 143, 144, 145, 146, 147, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 174, 175, 176, 177, 178, 179, 180, 181, 182, 182, 183, 184, 185, 186, 187, 188, 188, 189, 190, 191, 192, 193, 193, 194, 195, 196, 197, 197, 198, 199, 200, 201, 201, 202, 203, 204, 204, 205, 206, 207, 207, 208, 209, 210, 210, 211, 212, 213, 213, 214, 215, 216, 216, 217, 218, 219, 219, 220, 221, 221, 222, 223, 224, 224, 225, 226, 226, 227, 228, 228, 229, 230, 231, 231, 232, 233, 233, 234, 235, 235, 236, 237, 237, 238, 239, 240, 240, 241, 242, 242, 243, 244, 244, 245, 246, 246, 247, 248, 248, 249, 250, 250, 251, 252, 252, 253, 254, 254, 255 }; int[] arrayOfInt2 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 4, 6, 7, 9, 10, 12, 13, 14, 16, 17, 19, 20, 22, 23, 24, 26, 27, 29, 30, 32, 33, 34, 36, 37, 39, 40, 42, 43, 44, 46, 47, 49, 50, 52, 53, 54, 56, 57, 59, 60, 61, 63, 64, 66, 67, 69, 70, 71, 73, 74, 75, 77, 78, 80, 81, 82, 84, 85, 87, 88, 89, 91, 92, 93, 95, 96, 97, 99, 100, 101, 103, 104, 105, 107, 108, 109, 111, 112, 113, 115, 116, 117, 119, 120, 121, 122, 124, 125, 126, 127, 129, 130, 131, 132, 134, 135, 136, 137, 139, 140, 141, 142, 144, 145, 146, 147, 148, 149, 151, 152, 153, 154, 155, 156, 158, 159, 160, 161, 162, 163, 164, 165, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 198, 199, 200, 201, 202, 203, 204, 204, 205, 206, 207, 208, 209, 209, 210, 211, 212, 213, 213, 214, 215, 216, 216, 217, 218, 219, 219, 220, 221, 222, 222, 223, 224, 225, 225, 226, 227, 227, 228, 229, 229, 230, 231, 231, 232, 233, 233, 234, 235, 235, 236, 237, 237, 238, 239, 239, 240, 241, 241, 242, 243, 243, 244, 244, 245, 246, 246, 247, 248, 248, 249, 249, 250, 251, 251, 252, 253, 253, 254, 254, 255 }; int[] arrayOfInt3 = { 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 31, 33, 35, 37, 39, 41, 43, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 65, 67, 69, 71, 73, 75, 76, 78, 80, 82, 84, 85, 87, 89, 91, 92, 94, 96, 98, 99, 101, 102, 104, 106, 107, 109, 110, 112, 114, 115, 117, 118, 119, 121, 122, 124, 125, 126, 128, 129, 130, 132, 133, 134, 135, 137, 138, 139, 140, 141, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 166, 167, 168, 169, 170, 171, 171, 172, 173, 174, 175, 175, 176, 177, 178, 178, 179, 180, 181, 181, 182, 183, 184, 184, 185, 186, 186, 187, 188, 189, 189, 190, 191, 191, 192, 193, 193, 194, 195, 195, 196, 197, 197, 198, 199, 200, 200, 201, 202, 202, 203, 204, 204, 205, 206, 206, 207, 208, 208, 209, 210, 210, 211, 212, 212, 213, 214, 214, 215, 216, 216, 217, 218, 218, 219, 220, 220, 221, 221, 222, 223, 223, 224, 225, 225, 226, 227, 227, 228, 229, 229, 230, 231, 231, 232, 233, 233, 234, 234, 235, 236, 236, 237, 238, 238, 239, 240, 240, 241, 242, 242, 243, 243, 244, 245, 245, 246, 247, 247, 248, 249, 249, 250, 251, 251, 252, 252, 253, 254, 254, 255 }; int[] arrayOfInt4 = { 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 8, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 20, 20, 20, 21, 21, 21, 22, 22, 23, 23, 23, 24, 24, 24, 25, 25, 25, 25, 26, 26, 27, 27, 28, 28, 28, 28, 29, 29, 30, 29, 31, 31, 31, 31, 32, 32, 33, 33, 34, 34, 34, 34, 35, 35, 36, 36, 37, 37, 37, 38, 38, 39, 39, 39, 40, 40, 40, 41, 42, 42, 43, 43, 44, 44, 45, 45, 45, 46, 47, 47, 48, 48, 49, 50, 51, 51, 52, 52, 53, 53, 54, 55, 55, 56, 57, 57, 58, 59, 60, 60, 61, 62, 63, 63, 64, 65, 66, 67, 68, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 88, 89, 90, 91, 93, 94, 95, 96, 97, 98, 100, 101, 103, 104, 105, 107, 108, 110, 111, 113, 115, 116, 118, 119, 120, 122, 123, 125, 127, 128, 130, 132, 134, 135, 137, 139, 141, 143, 144, 146, 148, 150, 152, 154, 156, 158, 160, 163, 165, 167, 169, 171, 173, 175, 178, 180, 182, 185, 187, 189, 192, 194, 197, 199, 201, 204, 206, 209, 211, 214, 216, 219, 221, 224, 226, 229, 232, 234, 236, 239, 241, 245, 247, 250, 252, 255 }; for (int i = 0; i < 256; i++){ arrayOfByte1[(0 + i * 4)] = ((byte)arrayOfInt1[i]); arrayOfByte1[(1 + i * 4)] = ((byte)arrayOfInt2[i]); arrayOfByte1[(2 + i * 4)] = ((byte)arrayOfInt3[i]); arrayOfByte1[(3 + i * 4)] = ((byte)arrayOfInt4[i]); } int[] arrayOfInt5 = { 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 30, 32, 33, 34, 35, 37, 38, 39, 41, 42, 43, 44, 46, 47, 48, 50, 51, 52, 53, 55, 56, 57, 58, 60, 61, 62, 64, 65, 66, 67, 69, 70, 71, 72, 74, 75, 76, 77, 79, 80, 81, 82, 84, 85, 86, 87, 88, 90, 91, 92, 93, 95, 96, 97, 98, 99, 101, 102, 103, 104, 105, 107, 108, 109, 110, 111, 112, 114, 115, 116, 117, 118, 119, 121, 122, 123, 124, 125, 126, 127, 128, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 174, 175, 176, 177, 178, 179, 180, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 198, 199, 200, 201, 202, 204, 205, 206, 207, 209, 210, 211, 213, 214, 215, 217, 218, 220, 221, 222, 224, 225, 227, 228, 230, 231, 233, 234, 235, 237, 238, 240, 241, 243, 244, 246, 247, 249, 250, 252, 253, 255 }; int[] arrayOfInt6 = { 0, 3, 6, 8, 11, 14, 16, 18, 21, 24, 26, 29, 30, 33, 35, 37, 39, 41, 43, 45, 47, 49, 50, 52, 53, 54, 56, 58, 59, 61, 62, 63, 65, 65, 66, 68, 69, 70, 72, 73, 74, 75, 76, 77, 78, 79, 80, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 112, 113, 114, 115, 115, 116, 117, 118, 119, 120, 121, 122, 123, 123, 124, 125, 126, 127, 127, 128, 129, 130, 131, 132, 133, 134, 135, 135, 135, 136, 137, 138, 139, 140, 140, 141, 142, 143, 144, 145, 146, 146, 147, 147, 148, 149, 149, 150, 151, 152, 153, 154, 154, 155, 156, 157, 158, 158, 159, 159, 160, 161, 161, 162, 163, 164, 164, 165, 166, 167, 167, 168, 169, 170, 170, 170, 171, 172, 173, 173, 174, 175, 176, 176, 177, 178, 179, 179, 180, 181, 181, 182, 182, 183, 183, 184, 185, 186, 186, 187, 188, 188, 189, 190, 191, 191, 192, 193, 193, 194, 194, 194, 195, 196, 197, 197, 198, 199, 199, 200, 201, 201, 202, 203, 203, 204, 205, 205, 206, 206, 207, 207, 208, 209, 209, 210, 211, 211, 212, 213, 213, 214, 215, 215, 216, 217, 217, 217, 217, 218, 219, 219, 220, 221, 221, 222, 223, 223, 224, 225, 225, 226, 227, 227, 228, 228, 229, 229, 229, 230, 231, 231, 232, 232, 233, 234, 234, 235 }; int[] arrayOfInt7 = { 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 89, 90, 91, 92, 93, 94, 96, 97, 98, 99, 100, 102, 103, 104, 106, 107, 108, 109, 111, 112, 113, 115, 116, 118, 119, 120, 122, 123, 125, 126, 128, 129, 131, 132, 134, 135, 137, 139, 140, 142, 143, 145, 147, 148, 150, 152, 153, 155, 156, 158, 160, 161, 163, 164, 166, 167, 169, 170, 172, 173, 175, 176, 178, 179, 180, 182, 183, 185, 186, 188, 189, 190, 192, 193, 194, 196, 197, 199, 200, 201, 203, 204, 205, 206, 208, 209, 210, 212, 213, 214, 216, 217, 218, 219, 221, 222, 223, 224, 226, 227, 228, 229, 231, 232, 233, 234, 236, 237, 238, 239, 240, 242, 243, 244, 245, 247, 248, 249, 250, 251, 253, 254, 255 }; for (int j = 0; j < 256; j++){ arrayOfByte1[(0 + (1024 + j * 4))] = ((byte)arrayOfInt5[j]); arrayOfByte1[(1 + (1024 + j * 4))] = ((byte)arrayOfInt6[j]); arrayOfByte1[(2 + (1024 + j * 4))] = ((byte)arrayOfInt7[j]); arrayOfByte1[(3 + (1024 + j * 4))] = ((byte)arrayOfInt4[j]); } GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, 256, 2, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, ByteBuffer.wrap(arrayOfByte1)); GLES20.glGenTextures(1, mToneCurveTexture2, 0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mToneCurveTexture2[0]); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); byte[] arrayOfByte2 = new byte[1024]; int[] arrayOfInt8 = { 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 8, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 20, 20, 20, 21, 21, 21, 22, 22, 23, 23, 23, 24, 24, 24, 25, 25, 25, 25, 26, 26, 27, 27, 28, 28, 28, 28, 29, 29, 30, 29, 31, 31, 31, 31, 32, 32, 33, 33, 34, 34, 34, 34, 35, 35, 36, 36, 37, 37, 37, 38, 38, 39, 39, 39, 40, 40, 40, 41, 42, 42, 43, 43, 44, 44, 45, 45, 45, 46, 47, 47, 48, 48, 49, 50, 51, 51, 52, 52, 53, 53, 54, 55, 55, 56, 57, 57, 58, 59, 60, 60, 61, 62, 63, 63, 64, 65, 66, 67, 68, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 88, 89, 90, 91, 93, 94, 95, 96, 97, 98, 100, 101, 103, 104, 105, 107, 108, 110, 111, 113, 115, 116, 118, 119, 120, 122, 123, 125, 127, 128, 130, 132, 134, 135, 137, 139, 141, 143, 144, 146, 148, 150, 152, 154, 156, 158, 160, 163, 165, 167, 169, 171, 173, 175, 178, 180, 182, 185, 187, 189, 192, 194, 197, 199, 201, 204, 206, 209, 211, 214, 216, 219, 221, 224, 226, 229, 232, 234, 236, 239, 241, 245, 247, 250, 252, 255 }; int[] arrayOfInt9 = { 42, 43, 43, 44, 45, 45, 46, 47, 48, 48, 49, 50, 50, 51, 52, 52, 53, 54, 55, 55, 56, 57, 57, 58, 59, 60, 60, 61, 62, 62, 63, 64, 65, 65, 66, 67, 67, 68, 69, 70, 70, 71, 72, 72, 73, 74, 75, 75, 76, 77, 78, 78, 79, 80, 81, 81, 82, 83, 84, 84, 85, 86, 87, 87, 88, 89, 90, 91, 91, 92, 93, 94, 94, 95, 96, 97, 98, 98, 99, 100, 101, 102, 103, 103, 104, 105, 106, 107, 108, 108, 109, 110, 111, 112, 113, 113, 114, 115, 116, 117, 118, 119, 120, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 201, 202, 203, 204, 205, 206, 207, 207, 208, 209, 210, 211, 212, 212, 213, 214, 215, 216, 217, 217, 218, 219, 220, 221, 221, 222, 223, 224, 224, 225, 226, 227, 228, 228, 229, 230, 231, 231, 232, 233, 234, 234, 235, 236, 237, 237, 238, 239, 240, 240, 241, 242, 243, 243, 244, 245, 246, 246, 247, 248, 248, 249, 250, 251, 251, 252, 253, 254, 254, 255 }; int[] arrayOfInt10 = { 15, 16, 17, 18, 19, 20, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 198, 199, 200, 201, 202, 203, 204, 205, 205, 206, 207, 208, 209, 210, 211, 211, 212, 213, 214, 215, 215, 216, 217, 218, 219, 219, 220, 221, 222, 222, 223, 224, 225, 225, 226, 227, 227, 228, 229, 230, 230, 231, 232, 232, 233, 234, 234, 235, 236, 236, 237, 238, 238, 239, 240, 240, 241, 241, 242, 243, 243, 244, 245, 245, 246, 246, 247, 248, 248, 249, 250, 250, 251, 251, 252, 253, 253, 254, 254, 255 }; int[] arrayOfInt11 = { 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 174, 175, 176, 177, 178, 179, 180, 181, 182, 182, 183, 184, 185, 186, 187, 188, 189, 190, 190, 191, 192, 193, 194, 195, 196, 197, 197, 198, 199, 200, 201, 202, 203, 203, 204, 205, 206, 207, 208, 209, 209, 210, 211, 212, 213, 214, 214, 215, 216, 217, 218, 219, 219, 220, 221, 222, 223, 224, 224, 225, 226, 227, 228, 229, 229, 230, 231, 232, 233, 234, 234, 235, 236, 237, 238, 239, 239, 240, 241, 242, 243, 244, 244, 245, 246, 247, 248, 248, 249, 250, 251, 252, 253, 253, 254, 255 }; for (int k = 0; k < 256; k++){ arrayOfByte2[(0 + k * 4)] = ((byte)arrayOfInt9[k]); arrayOfByte2[(1 + k * 4)] = ((byte)arrayOfInt10[k]); arrayOfByte2[(2 + k * 4)] = ((byte)arrayOfInt11[k]); arrayOfByte2[(3 + k * 4)] = ((byte)arrayOfInt8[k]); } GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, 256, 1, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, ByteBuffer.wrap(arrayOfByte2)); } }); } public void onInputSizeChanged(int width, int height) { super.onInputSizeChanged(width, height); GLES20.glUniform1f(mTexelWidthUniformLocation, (1.0f / (float)width)); GLES20.glUniform1f(mTexelHeightUniformLocation, (1.0f / (float)height)); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/advanced/MagicPixarFilter.java ================================================ package com.zero.magicshow.core.filter.advanced; import android.opengl.GLES20; import com.zero.magicshow.R; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.common.utils.MagicParams; import com.zero.magicshow.common.utils.OpenGlUtils; public class MagicPixarFilter extends GPUImageFilter{ private int[] inputTextureHandles = {-1}; private int[] inputTextureUniformLocations = {-1}; private int mGLStrengthLocation; public MagicPixarFilter(){ super(NO_FILTER_VERTEX_SHADER, OpenGlUtils.readShaderFromRawResource(R.raw.pixar)); } public void onDestroy() { super.onDestroy(); GLES20.glDeleteTextures(1, inputTextureHandles, 0); for(int i = 0; i < inputTextureHandles.length; i++) inputTextureHandles[i] = -1; } protected void onDrawArraysAfter(){ for(int i = 0; i < inputTextureHandles.length && inputTextureHandles[i] != OpenGlUtils.NO_TEXTURE; i++){ GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + (i+3)); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } } protected void onDrawArraysPre(){ for(int i = 0; i < inputTextureHandles.length && inputTextureHandles[i] != OpenGlUtils.NO_TEXTURE; i++){ GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + (i+3) ); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, inputTextureHandles[i]); GLES20.glUniform1i(inputTextureUniformLocations[i], (i+3)); } } public void onInit(){ super.onInit(); for(int i=0; i < inputTextureUniformLocations.length; i++) inputTextureUniformLocations[i] = GLES20.glGetUniformLocation(getProgram(), "inputImageTexture"+(2+i)); mGLStrengthLocation = GLES20.glGetUniformLocation(mGLProgId, "strength"); } public void onInitialized(){ super.onInitialized(); setFloat(mGLStrengthLocation, 1.0f); runOnDraw(new Runnable(){ public void run(){ inputTextureHandles[0] = OpenGlUtils.loadTexture(MagicParams.context, "filter/pixar_curves.png"); } }); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/advanced/MagicRiseFilter.java ================================================ package com.zero.magicshow.core.filter.advanced; import android.opengl.GLES20; import com.zero.magicshow.R; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.common.utils.MagicParams; import com.zero.magicshow.common.utils.OpenGlUtils; public class MagicRiseFilter extends GPUImageFilter{ private int[] inputTextureHandles = {-1,-1,-1}; private int[] inputTextureUniformLocations = {-1,-1,-1}; public MagicRiseFilter(){ super(NO_FILTER_VERTEX_SHADER, OpenGlUtils.readShaderFromRawResource(R.raw.rise)); } public void onDestroy() { super.onDestroy(); GLES20.glDeleteTextures(inputTextureHandles.length, inputTextureHandles, 0); for(int i = 0; i < inputTextureHandles.length; i++) inputTextureHandles[i] = -1; } protected void onDrawArraysAfter(){ for(int i = 0; i < inputTextureHandles.length && inputTextureHandles[i] != OpenGlUtils.NO_TEXTURE; i++){ GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + (i+3)); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } } protected void onDrawArraysPre(){ for(int i = 0; i < inputTextureHandles.length && inputTextureHandles[i] != OpenGlUtils.NO_TEXTURE; i++){ GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + (i+3) ); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, inputTextureHandles[i]); GLES20.glUniform1i(inputTextureUniformLocations[i], (i+3)); } } public void onInit(){ super.onInit(); for(int i=0; i < inputTextureUniformLocations.length; i++){ inputTextureUniformLocations[i] = GLES20.glGetUniformLocation(getProgram(), "inputImageTexture"+(2+i)); } } public void onInitialized(){ super.onInitialized(); runOnDraw(new Runnable(){ public void run(){ inputTextureHandles[0] = OpenGlUtils.loadTexture(MagicParams.context, "filter/blackboard1024.png"); inputTextureHandles[1] = OpenGlUtils.loadTexture(MagicParams.context, "filter/overlaymap.png"); inputTextureHandles[2] = OpenGlUtils.loadTexture(MagicParams.context, "filter/risemap.png"); } }); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/advanced/MagicRomanceFilter.java ================================================ package com.zero.magicshow.core.filter.advanced; import android.opengl.GLES20; import com.zero.magicshow.R; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.common.utils.OpenGlUtils; import java.nio.ByteBuffer; public class MagicRomanceFilter extends GPUImageFilter{ private int[] mToneCurveTexture = {-1}; private int mToneCurveTextureUniformLocation; public MagicRomanceFilter(){ super(NO_FILTER_VERTEX_SHADER, OpenGlUtils.readShaderFromRawResource(R.raw.romance)); } public void onDestroy(){ super.onDestroy(); GLES20.glDeleteTextures(1, mToneCurveTexture, 0); mToneCurveTexture[0] = -1; } protected void onDrawArraysAfter(){ if (mToneCurveTexture[0] != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE3); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } } protected void onDrawArraysPre(){ if (mToneCurveTexture[0] != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE3); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mToneCurveTexture[0]); GLES20.glUniform1i(mToneCurveTextureUniformLocation, 3); } } public void onInit(){ super.onInit(); mToneCurveTextureUniformLocation = GLES20.glGetUniformLocation(mGLProgId, "curve"); } public void onInitialized(){ super.onInitialized(); runOnDraw(new Runnable(){ public void run(){ GLES20.glGenTextures(1, mToneCurveTexture, 0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mToneCurveTexture[0]); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); byte[] romance_arrayOfByte = new byte[1024]; int[] romance_arrayOfInt1 = { 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 48, 48, 48, 48, 48, 48, 49, 49, 49, 49, 49, 50, 50, 50, 50, 51, 51, 51, 51, 52, 52, 52, 52, 53, 53, 53, 54, 54, 54, 55, 55, 56, 56, 56, 57, 57, 58, 58, 59, 59, 60, 60, 61, 61, 62, 62, 63, 63, 64, 65, 65, 66, 67, 67, 68, 69, 69, 70, 71, 72, 73, 73, 74, 75, 76, 77, 78, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 100, 101, 102, 103, 104, 105, 106, 107, 109, 110, 111, 112, 113, 114, 116, 117, 118, 119, 120, 122, 123, 124, 125, 127, 128, 129, 130, 131, 133, 134, 135, 136, 138, 139, 140, 141, 143, 144, 145, 146, 148, 149, 150, 151, 153, 154, 155, 156, 158, 159, 160, 161, 162, 164, 165, 166, 167, 169, 170, 171, 172, 173, 175, 176, 177, 178, 179, 180, 182, 183, 184, 185, 186, 187, 188, 189, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 211, 212, 213, 214, 215, 216, 217, 218, 218, 219, 220, 221, 222, 222, 223, 224, 225, 226, 226, 227, 228, 229, 229, 230, 231, 232, 232, 233, 234, 234, 235, 236, 237, 237, 238, 239, 239, 240, 241, 241, 242, 243, 243, 244, 245, 245, 246, 247, 247, 248, 249, 249, 250, 251, 251, 252, 252, 253, 254, 254, 255 }; int[] romance_arrayOfInt2 = { 0, 1, 1, 2, 3, 4, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22, 23, 23, 24, 25, 26, 26, 27, 28, 29, 30, 30, 31, 32, 33, 33, 34, 35, 36, 37, 38, 38, 39, 40, 41, 42, 43, 43, 44, 45, 46, 47, 48, 49, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 111, 112, 113, 114, 115, 116, 117, 118, 120, 121, 122, 123, 124, 125, 126, 128, 129, 130, 131, 132, 133, 134, 136, 137, 138, 139, 140, 141, 142, 144, 145, 146, 147, 148, 149, 151, 152, 153, 154, 155, 156, 157, 159, 160, 161, 162, 163, 164, 166, 167, 168, 169, 170, 171, 172, 174, 175, 176, 177, 178, 179, 180, 181, 183, 184, 185, 186, 187, 188, 189, 190, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 }; int[] romance_arrayOfInt3 = { 0, 2, 3, 5, 7, 8, 10, 12, 13, 15, 17, 18, 20, 21, 23, 25, 26, 28, 30, 31, 33, 34, 36, 38, 39, 41, 42, 44, 45, 47, 48, 50, 51, 53, 54, 56, 57, 59, 60, 62, 63, 65, 66, 67, 69, 70, 72, 73, 74, 76, 77, 78, 79, 81, 82, 83, 84, 86, 87, 88, 89, 90, 91, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 106, 107, 108, 109, 110, 111, 112, 112, 113, 114, 115, 116, 116, 117, 118, 119, 119, 120, 121, 122, 122, 123, 124, 124, 125, 126, 126, 127, 128, 128, 129, 130, 130, 131, 131, 132, 133, 133, 134, 134, 135, 136, 136, 137, 137, 138, 139, 139, 140, 140, 141, 141, 142, 143, 143, 144, 144, 145, 146, 146, 147, 147, 148, 149, 149, 150, 150, 151, 152, 152, 153, 154, 154, 155, 155, 156, 157, 157, 158, 159, 159, 160, 161, 162, 162, 163, 164, 164, 165, 166, 167, 168, 168, 169, 170, 171, 172, 172, 173, 174, 175, 176, 177, 177, 178, 179, 180, 181, 182, 183, 184, 185, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 242, 243, 244, 245, 246, 247, 248, 249, 251, 252, 253, 254, 255 }; int[] romance_arrayOfInt4 = { 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 8, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 20, 20, 20, 21, 21, 21, 22, 22, 23, 23, 23, 24, 24, 24, 25, 25, 25, 25, 26, 26, 27, 27, 28, 28, 28, 28, 29, 29, 30, 29, 31, 31, 31, 31, 32, 32, 33, 33, 34, 34, 34, 34, 35, 35, 36, 36, 37, 37, 37, 38, 38, 39, 39, 39, 40, 40, 40, 41, 42, 42, 43, 43, 44, 44, 45, 45, 45, 46, 47, 47, 48, 48, 49, 50, 51, 51, 52, 52, 53, 53, 54, 55, 55, 56, 57, 57, 58, 59, 60, 60, 61, 62, 63, 63, 64, 65, 66, 67, 68, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 88, 89, 90, 91, 93, 94, 95, 96, 97, 98, 100, 101, 103, 104, 105, 107, 108, 110, 111, 113, 115, 116, 118, 119, 120, 122, 123, 125, 127, 128, 130, 132, 134, 135, 137, 139, 141, 143, 144, 146, 148, 150, 152, 154, 156, 158, 160, 163, 165, 167, 169, 171, 173, 175, 178, 180, 182, 185, 187, 189, 192, 194, 197, 199, 201, 204, 206, 209, 211, 214, 216, 219, 221, 224, 226, 229, 232, 234, 236, 239, 241, 245, 247, 250, 252, 255 }; for (int i = 0; i < 256; i++){ romance_arrayOfByte[(i * 4)] = ((byte)romance_arrayOfInt1[i]); romance_arrayOfByte[(1 + i * 4)] = ((byte)romance_arrayOfInt2[i]); romance_arrayOfByte[(2 + i * 4)] = ((byte)romance_arrayOfInt3[i]); romance_arrayOfByte[(3 + i * 4)] = ((byte)romance_arrayOfInt4[i]); } GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, 256, 1, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, ByteBuffer.wrap(romance_arrayOfByte)); } }); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/advanced/MagicSakuraFilter.java ================================================ package com.zero.magicshow.core.filter.advanced; import android.opengl.GLES20; import com.zero.magicshow.R; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.common.utils.OpenGlUtils; import java.nio.ByteBuffer; public class MagicSakuraFilter extends GPUImageFilter{ private int[] mToneCurveTexture = {-1}; private int mToneCurveTextureUniformLocation; private int mTexelHeightUniformLocation; private int mTexelWidthUniformLocation; public MagicSakuraFilter(){ super(NO_FILTER_VERTEX_SHADER, OpenGlUtils.readShaderFromRawResource(R.raw.romance)); } public void onDestroy(){ super.onDestroy(); GLES20.glDeleteTextures(1, mToneCurveTexture, 0); mToneCurveTexture[0] = -1; } protected void onDrawArraysAfter(){ if (mToneCurveTexture[0] != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE3); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } } protected void onDrawArraysPre(){ if (mToneCurveTexture[0] != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE3); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mToneCurveTexture[0]); GLES20.glUniform1i(mToneCurveTextureUniformLocation, 3); } } public void onInit(){ super.onInit(); mToneCurveTextureUniformLocation = GLES20.glGetUniformLocation(mGLProgId, "curve"); mTexelWidthUniformLocation = GLES20.glGetUniformLocation(getProgram(), "texelWidthOffset"); mTexelHeightUniformLocation = GLES20.glGetUniformLocation(getProgram(), "texelHeightOffset"); } public void onInitialized(){ super.onInitialized(); runOnDraw(new Runnable(){ public void run(){ GLES20.glGenTextures(1, mToneCurveTexture, 0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mToneCurveTexture[0]); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); byte[] arrayOfByte = new byte[1024]; int[] arrayOfInt = { 95, 95, 96, 97, 97, 98, 99, 99, 100, 101, 101, 102, 103, 104, 104, 105, 106, 106, 107, 108, 108, 109, 110, 111, 111, 112, 113, 113, 114, 115, 115, 116, 117, 117, 118, 119, 120, 120, 121, 122, 122, 123, 124, 124, 125, 126, 127, 127, 128, 129, 129, 130, 131, 131, 132, 133, 133, 134, 135, 136, 136, 137, 138, 138, 139, 140, 140, 141, 142, 143, 143, 144, 145, 145, 146, 147, 147, 148, 149, 149, 150, 151, 152, 152, 153, 154, 154, 155, 156, 156, 157, 158, 159, 159, 160, 161, 161, 162, 163, 163, 164, 165, 165, 166, 167, 168, 168, 169, 170, 170, 171, 172, 172, 173, 174, 175, 175, 176, 177, 177, 178, 179, 179, 180, 181, 181, 182, 183, 184, 184, 185, 186, 186, 187, 188, 188, 189, 190, 191, 191, 192, 193, 193, 194, 195, 195, 196, 197, 197, 198, 199, 200, 200, 201, 202, 202, 203, 204, 204, 205, 206, 207, 207, 208, 209, 209, 210, 211, 211, 212, 213, 213, 214, 215, 216, 216, 217, 218, 218, 219, 220, 220, 221, 222, 223, 223, 224, 225, 225, 226, 227, 227, 228, 229, 229, 230, 231, 232, 232, 233, 234, 234, 235, 236, 236, 237, 238, 239, 239, 240, 241, 241, 242, 243, 243, 244, 245, 245, 246, 247, 248, 248, 249, 250, 250, 251, 252, 252, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }; for (int i = 0; i < 256; i++) { arrayOfByte[(i * 4)] = ((byte)arrayOfInt[i]); arrayOfByte[(1 + i * 4)] = ((byte)arrayOfInt[i]); arrayOfByte[(2 + i * 4)] = ((byte)arrayOfInt[i]); arrayOfByte[(3 + i * 4)] = ((byte)arrayOfInt[i]); } GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, 256, 1, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, ByteBuffer.wrap(arrayOfByte)); } }); } public void onInputSizeChanged(int width, int height) { super.onInputSizeChanged(width, height); GLES20.glUniform1f(mTexelWidthUniformLocation, (1.0f / (float)width)); GLES20.glUniform1f(mTexelHeightUniformLocation, (1.0f / (float)height)); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/advanced/MagicSierraFilter.java ================================================ package com.zero.magicshow.core.filter.advanced; import android.opengl.GLES20; import com.zero.magicshow.R; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.common.utils.MagicParams; import com.zero.magicshow.common.utils.OpenGlUtils; public class MagicSierraFilter extends GPUImageFilter{ private int[] inputTextureHandles = {-1,-1,-1}; private int[] inputTextureUniformLocations = {-1,-1,-1}; private int mGLStrengthLocation; public MagicSierraFilter(){ super(NO_FILTER_VERTEX_SHADER, OpenGlUtils.readShaderFromRawResource(R.raw.sierra)); } public void onDestroy() { super.onDestroy(); GLES20.glDeleteTextures(inputTextureHandles.length, inputTextureHandles, 0); for(int i = 0; i < inputTextureHandles.length; i++) inputTextureHandles[i] = -1; } protected void onDrawArraysAfter(){ for(int i = 0; i < inputTextureHandles.length && inputTextureHandles[i] != OpenGlUtils.NO_TEXTURE; i++){ GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + (i+3)); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } } protected void onDrawArraysPre(){ for(int i = 0; i < inputTextureHandles.length && inputTextureHandles[i] != OpenGlUtils.NO_TEXTURE; i++){ GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + (i+3) ); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, inputTextureHandles[i]); GLES20.glUniform1i(inputTextureUniformLocations[i], (i+3)); } } public void onInit(){ super.onInit(); for(int i = 0; i < inputTextureUniformLocations.length; i++) inputTextureUniformLocations[i] = GLES20.glGetUniformLocation(getProgram(), "inputImageTexture"+(2+i)); mGLStrengthLocation = GLES20.glGetUniformLocation(mGLProgId, "strength"); } public void onInitialized(){ super.onInitialized(); setFloat(mGLStrengthLocation, 1.0f); runOnDraw(new Runnable(){ public void run(){ inputTextureHandles[0] = OpenGlUtils.loadTexture(MagicParams.context, "filter/sierravignette.png"); inputTextureHandles[1] = OpenGlUtils.loadTexture(MagicParams.context, "filter/overlaymap.png"); inputTextureHandles[2] = OpenGlUtils.loadTexture(MagicParams.context, "filter/sierramap.png"); } }); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/advanced/MagicSketchFilter.java ================================================ package com.zero.magicshow.core.filter.advanced; import android.opengl.GLES20; import com.zero.magicshow.R; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.common.utils.OpenGlUtils; public class MagicSketchFilter extends GPUImageFilter{ private int mSingleStepOffsetLocation; //0.0 - 1.0 private int mStrengthLocation; public MagicSketchFilter(){ super(NO_FILTER_VERTEX_SHADER, OpenGlUtils.readShaderFromRawResource(R.raw.sketch)); } protected void onInit() { super.onInit(); mSingleStepOffsetLocation = GLES20.glGetUniformLocation(getProgram(), "singleStepOffset"); mStrengthLocation = GLES20.glGetUniformLocation(getProgram(), "strength"); } protected void onDestroy() { super.onDestroy(); } private void setTexelSize(final float w, final float h) { setFloatVec2(mSingleStepOffsetLocation, new float[] {1.0f / w, 1.0f / h}); } protected void onInitialized(){ super.onInitialized(); setFloat(mStrengthLocation, 0.5f); } @Override public void onInputSizeChanged(final int width, final int height) { super.onInputSizeChanged(width, height); setTexelSize(width, height); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/advanced/MagicSkinWhitenFilter.java ================================================ package com.zero.magicshow.core.filter.advanced; import android.opengl.GLES20; import com.zero.magicshow.R; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.common.utils.OpenGlUtils; import java.nio.ByteBuffer; public class MagicSkinWhitenFilter extends GPUImageFilter { private int mTexelHeightUniformLocation; private int mTexelWidthUniformLocation; private int mToneCurveTextureUniformLocation; private int[] mToneCurveTexture = new int[] {-1}; public MagicSkinWhitenFilter() { super(NO_FILTER_VERTEX_SHADER, OpenGlUtils.readShaderFromRawResource(R.raw.skinwhiten)); } public void onInit() { super.onInit(); mToneCurveTextureUniformLocation = GLES20.glGetUniformLocation(getProgram(), "curve"); mTexelWidthUniformLocation = GLES20.glGetUniformLocation(getProgram(), "texelWidthOffset"); mTexelHeightUniformLocation = GLES20.glGetUniformLocation(getProgram(), "texelHeightOffset"); } public void onDestroy() { super.onDestroy(); GLES20.glDeleteTextures(1, mToneCurveTexture, 0); mToneCurveTexture[0] = -1; } public void onInitialized() { super.onInitialized(); runOnDraw(new Runnable() { public void run() { GLES20.glActiveTexture(GLES20.GL_TEXTURE3); GLES20.glGenTextures(1, mToneCurveTexture, 0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mToneCurveTexture[0]); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); byte[] arrayOfByte = new byte[1024]; int[] arrayOfInt1 = { 95, 95, 96, 97, 97, 98, 99, 99, 100, 101, 101, 102, 103, 104, 104, 105, 106, 106, 107, 108, 108, 109, 110, 111, 111, 112, 113, 113, 114, 115, 115, 116, 117, 117, 118, 119, 120, 120, 121, 122, 122, 123, 124, 124, 125, 126, 127, 127, 128, 129, 129, 130, 131, 131, 132, 133, 133, 134, 135, 136, 136, 137, 138, 138, 139, 140, 140, 141, 142, 143, 143, 144, 145, 145, 146, 147, 147, 148, 149, 149, 150, 151, 152, 152, 153, 154, 154, 155, 156, 156, 157, 158, 159, 159, 160, 161, 161, 162, 163, 163, 164, 165, 165, 166, 167, 168, 168, 169, 170, 170, 171, 172, 172, 173, 174, 175, 175, 176, 177, 177, 178, 179, 179, 180, 181, 181, 182, 183, 184, 184, 185, 186, 186, 187, 188, 188, 189, 190, 191, 191, 192, 193, 193, 194, 195, 195, 196, 197, 197, 198, 199, 200, 200, 201, 202, 202, 203, 204, 204, 205, 206, 207, 207, 208, 209, 209, 210, 211, 211, 212, 213, 213, 214, 215, 216, 216, 217, 218, 218, 219, 220, 220, 221, 222, 223, 223, 224, 225, 225, 226, 227, 227, 228, 229, 229, 230, 231, 232, 232, 233, 234, 234, 235, 236, 236, 237, 238, 239, 239, 240, 241, 241, 242, 243, 243, 244, 245, 245, 246, 247, 248, 248, 249, 250, 250, 251, 252, 252, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }; int[] arrayOfInt2 = { 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 8, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 20, 20, 20, 21, 21, 21, 22, 22, 23, 23, 23, 24, 24, 24, 25, 25, 25, 25, 26, 26, 27, 27, 28, 28, 28, 28, 29, 29, 30, 29, 31, 31, 31, 31, 32, 32, 33, 33, 34, 34, 34, 34, 35, 35, 36, 36, 37, 37, 37, 38, 38, 39, 39, 39, 40, 40, 40, 41, 42, 42, 43, 43, 44, 44, 45, 45, 45, 46, 47, 47, 48, 48, 49, 50, 51, 51, 52, 52, 53, 53, 54, 55, 55, 56, 57, 57, 58, 59, 60, 60, 61, 62, 63, 63, 64, 65, 66, 67, 68, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 88, 89, 90, 91, 93, 94, 95, 96, 97, 98, 100, 101, 103, 104, 105, 107, 108, 110, 111, 113, 115, 116, 118, 119, 120, 122, 123, 125, 127, 128, 130, 132, 134, 135, 137, 139, 141, 143, 144, 146, 148, 150, 152, 154, 156, 158, 160, 163, 165, 167, 169, 171, 173, 175, 178, 180, 182, 185, 187, 189, 192, 194, 197, 199, 201, 204, 206, 209, 211, 214, 216, 219, 221, 224, 226, 229, 232, 234, 236, 239, 241, 245, 247, 250, 252, 255 }; for (int i = 0; i < 256; i++){ arrayOfByte[(i * 4)] = ((byte)arrayOfInt1[i]); arrayOfByte[(1 + i * 4)] = ((byte)arrayOfInt1[i]); arrayOfByte[(2 + i * 4)] = ((byte)arrayOfInt2[i]); arrayOfByte[(3 + i * 4)] = -1; } GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, 256, 1, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, ByteBuffer.wrap(arrayOfByte)); } }); } protected void onDrawArraysPre() { super.onDrawArraysPre(); if(mToneCurveTexture[0] != -1) { GLES20.glActiveTexture(GLES20.GL_TEXTURE3); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mToneCurveTexture[0]); GLES20.glUniform1i(this.mToneCurveTextureUniformLocation, 3); } } public void onInputSizeChanged(int width, int height) { super.onInputSizeChanged(width, height); GLES20.glUniform1f(mTexelWidthUniformLocation, (1.0f / (float)width)); GLES20.glUniform1f(mTexelHeightUniformLocation, (1.0f / (float)height)); } protected void onDrawArraysAfter() { super.onDrawArraysAfter(); if(mToneCurveTexture[0] != -1) { GLES20.glActiveTexture(GLES20.GL_TEXTURE3); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/advanced/MagicSunriseFilter.java ================================================ package com.zero.magicshow.core.filter.advanced; import android.opengl.GLES20; import com.zero.magicshow.R; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.common.utils.MagicParams; import com.zero.magicshow.common.utils.OpenGlUtils; import java.nio.ByteBuffer; public class MagicSunriseFilter extends GPUImageFilter{ private int mMaskGrey1TextureId = -1; private int mMaskGrey1UniformLocation; private int mMaskGrey2TextureId = -1; private int mMaskGrey2UniformLocation; private int mMaskGrey3TextureId = -1; private int mMaskGrey3UniformLocation; private int[] mToneCurveTexture = { -1 }; private int mToneCurveTextureUniformLocation; public MagicSunriseFilter(){ super(NO_FILTER_VERTEX_SHADER, OpenGlUtils.readShaderFromRawResource(R.raw.sunrise)); } protected void onDestroy(){ super.onDestroy(); GLES20.glDeleteTextures(1, mToneCurveTexture, 0); mToneCurveTexture[0] = -1; GLES20.glDeleteTextures(1, new int[]{mMaskGrey1TextureId}, 0); mMaskGrey1TextureId = -1; GLES20.glDeleteTextures(1, new int[]{mMaskGrey2TextureId}, 0); mMaskGrey2TextureId = -1; GLES20.glDeleteTextures(1, new int[]{mMaskGrey3TextureId}, 0); mMaskGrey3TextureId = -1; } protected void onDrawArraysAfter(){ if (mToneCurveTexture[0] != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE3); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } if (mMaskGrey1TextureId != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE4); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } if (mMaskGrey2TextureId != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE5); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } if (mMaskGrey3TextureId != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE6); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } } protected void onDrawArraysPre(){ if (mToneCurveTexture[0] != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE3); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mToneCurveTexture[0]); GLES20.glUniform1i(mToneCurveTextureUniformLocation, 3); } if (mMaskGrey1TextureId != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE4); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mMaskGrey1TextureId); GLES20.glUniform1i(mMaskGrey1UniformLocation, 4); } if (mMaskGrey2TextureId != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE5); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mMaskGrey2TextureId); GLES20.glUniform1i(mMaskGrey2UniformLocation, 5); } if (mMaskGrey3TextureId != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE6); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mMaskGrey3TextureId); GLES20.glUniform1i(mMaskGrey3UniformLocation, 6); } } protected void onInit(){ super.onInit(); mToneCurveTextureUniformLocation = GLES20.glGetUniformLocation(mGLProgId, "curve"); mMaskGrey1UniformLocation = GLES20.glGetUniformLocation(getProgram(), "grey1Frame"); mMaskGrey2UniformLocation = GLES20.glGetUniformLocation(getProgram(), "grey2Frame"); mMaskGrey3UniformLocation = GLES20.glGetUniformLocation(getProgram(), "grey3Frame"); } public void onInitialized(){ super.onInitialized(); runOnDraw(new Runnable(){ public void run(){ GLES20.glActiveTexture(GLES20.GL_TEXTURE3); GLES20.glGenTextures(1, mToneCurveTexture, 0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mToneCurveTexture[0]); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); byte[] arrayOfByte = new byte[2048]; int[] arrayOfInt1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 25, 26, 27, 28, 30, 31, 32, 34, 35, 36, 38, 39, 41, 42, 44, 45, 47, 49, 50, 52, 54, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 92, 94, 96, 98, 101, 103, 105, 107, 110, 111, 113, 115, 118, 120, 122, 124, 126, 129, 131, 133, 135, 137, 139, 141, 143, 145, 147, 149, 150, 152, 154, 156, 158, 159, 161, 162, 164, 166, 167, 169, 170, 172, 173, 174, 176, 177, 178, 180, 181, 182, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 200, 201, 202, 203, 203, 204, 205, 205, 207, 208, 208, 209, 209, 210, 210, 211, 211, 212, 212, 213, 213, 213, 214, 214, 215, 215, 215, 216, 216, 216, 216, 217, 217, 217, 218, 218, 218, 218, 219, 219, 219, 219, 219, 220, 220, 220, 220, 220, 220, 221, 221, 221, 221, 221, 222, 222, 222, 222, 222, 223, 223, 223, 223, 223, 224, 224, 224, 224, 224, 225, 225, 225, 225, 226, 226, 226, 227, 227, 227, 228, 228, 228, 229, 229, 230, 230, 230, 231, 231, 232, 232, 233, 233, 234, 234, 235, 235, 236, 236, 237, 238, 238, 239, 239, 241, 241, 242, 243, 243, 244, 245, 245, 246, 246, 247, 248, 248, 249, 250, 250, 251, 252, 252, 253, 254, 254, 255 }; int[] arrayOfInt2 = { 0, 1, 3, 4, 5, 7, 8, 10, 11, 12, 14, 15, 17, 18, 19, 21, 22, 24, 25, 27, 28, 30, 31, 33, 34, 36, 37, 39, 40, 42, 44, 45, 47, 48, 50, 52, 54, 55, 57, 59, 61, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 83, 85, 87, 90, 92, 94, 96, 98, 101, 103, 105, 107, 110, 111, 113, 115, 117, 119, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 143, 145, 147, 149, 150, 152, 154, 155, 157, 158, 160, 161, 163, 164, 165, 167, 168, 169, 171, 172, 173, 174, 175, 176, 177, 179, 180, 181, 182, 183, 184, 184, 185, 186, 187, 188, 189, 190, 190, 191, 192, 193, 193, 194, 195, 195, 196, 197, 197, 198, 198, 199, 199, 200, 200, 201, 201, 202, 202, 203, 203, 204, 204, 205, 205, 205, 207, 207, 208, 208, 208, 209, 209, 210, 210, 210, 211, 211, 211, 212, 212, 212, 213, 213, 213, 214, 214, 214, 215, 215, 215, 216, 216, 216, 217, 217, 217, 218, 218, 219, 219, 219, 220, 220, 220, 221, 221, 222, 222, 222, 223, 223, 224, 224, 225, 225, 225, 226, 226, 227, 227, 228, 228, 228, 229, 229, 230, 230, 231, 231, 232, 232, 233, 233, 234, 234, 235, 235, 236, 236, 236, 237, 237, 238, 238, 239, 239, 241, 241, 242, 242, 243, 244, 244, 245, 245, 246, 246, 247, 247, 248, 248, 249, 249, 250, 250, 251, 251, 252, 252, 253, 253, 254, 254, 255 }; int[] arrayOfInt3 = { 0, 1, 3, 4, 5, 6, 8, 9, 10, 11, 13, 14, 15, 17, 18, 19, 21, 22, 23, 25, 26, 28, 29, 30, 32, 33, 35, 36, 38, 39, 41, 43, 44, 46, 47, 49, 51, 53, 54, 56, 58, 60, 62, 64, 66, 68, 69, 71, 73, 76, 78, 80, 82, 83, 85, 87, 89, 91, 93, 95, 97, 100, 102, 104, 106, 108, 110, 111, 113, 115, 117, 119, 121, 123, 125, 127, 129, 130, 132, 134, 136, 138, 139, 141, 143, 145, 146, 148, 150, 151, 153, 155, 156, 158, 159, 161, 162, 164, 165, 167, 168, 169, 171, 172, 173, 175, 176, 177, 179, 180, 181, 182, 183, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 200, 201, 202, 203, 204, 204, 205, 207, 207, 208, 209, 209, 210, 210, 211, 212, 212, 213, 213, 214, 214, 215, 215, 215, 216, 216, 217, 217, 217, 218, 218, 218, 219, 219, 219, 220, 220, 220, 220, 221, 221, 221, 221, 222, 222, 222, 222, 223, 223, 223, 223, 224, 224, 224, 224, 224, 225, 225, 225, 225, 225, 226, 226, 226, 226, 227, 227, 227, 227, 228, 228, 228, 228, 229, 229, 229, 230, 230, 230, 231, 231, 231, 232, 232, 233, 233, 233, 234, 234, 235, 235, 235, 236, 236, 237, 237, 238, 238, 239, 239, 241, 241, 242, 242, 243, 243, 244, 244, 245, 245, 246, 247, 247, 248, 248, 249, 249, 250, 250, 251, 252, 252, 253, 253, 254, 254, 255 }; int[] arrayOfInt4 = { 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 8, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 20, 20, 20, 21, 21, 21, 22, 22, 23, 23, 23, 24, 24, 24, 25, 25, 25, 25, 26, 26, 27, 27, 28, 28, 28, 28, 29, 29, 30, 29, 31, 31, 31, 31, 32, 32, 33, 33, 34, 34, 34, 34, 35, 35, 36, 36, 37, 37, 37, 38, 38, 39, 39, 39, 40, 40, 40, 41, 42, 42, 43, 43, 44, 44, 45, 45, 45, 46, 47, 47, 48, 48, 49, 50, 51, 51, 52, 52, 53, 53, 54, 55, 55, 56, 57, 57, 58, 59, 60, 60, 61, 62, 63, 63, 64, 65, 66, 67, 68, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 88, 89, 90, 91, 93, 94, 95, 96, 97, 98, 100, 101, 103, 104, 105, 107, 108, 110, 111, 113, 115, 116, 118, 119, 120, 122, 123, 125, 127, 128, 130, 132, 134, 135, 137, 139, 141, 143, 144, 146, 148, 150, 152, 154, 156, 158, 160, 163, 165, 167, 169, 171, 173, 175, 178, 180, 182, 185, 187, 189, 192, 194, 197, 199, 201, 204, 206, 209, 211, 214, 216, 219, 221, 224, 226, 229, 232, 234, 236, 239, 241, 245, 247, 250, 252, 255 }; for (int i = 0; i < 256; i++){ arrayOfByte[(i * 4)] = ((byte)arrayOfInt1[i]); arrayOfByte[(1 + i * 4)] = ((byte)arrayOfInt2[i]); arrayOfByte[(2 + i * 4)] = ((byte)arrayOfInt3[i]); arrayOfByte[(3 + i * 4)] = ((byte)arrayOfInt4[i]); } int[] arrayOfInt5 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16, 17, 19, 20, 21, 22, 23, 24, 26, 27, 28, 29, 30, 31, 32, 34, 35, 36, 37, 38, 39, 41, 42, 43, 44, 45, 46, 48, 49, 50, 51, 52, 53, 54, 56, 57, 58, 59, 60, 61, 63, 64, 65, 66, 67, 68, 70, 71, 72, 73, 74, 75, 77, 78, 79, 80, 81, 82, 83, 85, 86, 87, 88, 89, 90, 92, 93, 94, 95, 96, 97, 99, 100, 101, 102, 103, 104, 105, 107, 108, 109, 110, 111, 112, 114, 115, 116, 117, 118, 119, 121, 122, 123, 124, 125, 126, 128, 129, 130, 131, 132, 133, 134, 136, 137, 138, 139, 140, 141, 143, 144, 145, 146, 147, 148, 150, 151, 152, 153, 154, 155, 156, 158, 159, 160, 161, 162, 163, 165, 166, 167, 168, 169, 170, 172, 173, 174, 175, 176, 177, 178, 180, 181, 182, 183, 184, 185, 187, 188, 189, 190, 191, 192, 194, 195, 196, 197, 198, 199, 201, 202, 203, 204, 205, 206, 207, 209, 210, 211, 212, 213, 214, 216, 217, 218, 219, 220, 221, 223, 224, 225, 226, 227, 228, 230, 231, 232, 233, 234, 235, 236, 238, 239, 240, 241, 242, 243, 245, 246, 247, 248, 249, 250, 252, 253, 254, 255 }; int[] arrayOfInt6 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 5, 6, 7, 9, 10, 11, 12, 14, 15, 16, 17, 19, 20, 21, 22, 24, 25, 26, 27, 29, 30, 31, 32, 34, 35, 36, 37, 39, 40, 41, 42, 44, 45, 46, 47, 49, 50, 51, 52, 53, 55, 56, 57, 58, 60, 61, 62, 63, 65, 66, 67, 68, 70, 71, 72, 73, 75, 76, 77, 78, 80, 81, 82, 83, 85, 86, 87, 88, 90, 91, 92, 93, 95, 96, 97, 98, 100, 101, 102, 103, 104, 106, 107, 108, 109, 111, 112, 113, 114, 116, 117, 118, 119, 121, 122, 123, 124, 126, 127, 128, 129, 131, 132, 133, 134, 136, 137, 138, 139, 141, 142, 143, 144, 146, 147, 148, 149, 151, 152, 153, 154, 155, 157, 158, 159, 160, 162, 163, 164, 165, 167, 168, 169, 170, 172, 173, 174, 175, 177, 178, 179, 180, 182, 183, 184, 185, 187, 188, 189, 190, 192, 193, 194, 195, 197, 198, 199, 200, 202, 203, 204, 205, 206, 208, 209, 210, 211, 213, 214, 215, 216, 218, 219, 220, 221, 223, 224, 225, 226, 228, 229, 230, 231, 233, 234, 235, 236, 238, 239, 240, 241, 243, 244, 245, 246, 248, 249, 250, 251, 253, 254, 255 }; int[] arrayOfInt7 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, 26, 28, 29, 30, 31, 32, 33, 34, 36, 37, 38, 39, 40, 41, 43, 44, 45, 46, 47, 48, 49, 51, 52, 53, 54, 55, 56, 57, 59, 60, 61, 62, 63, 64, 65, 67, 68, 69, 70, 71, 72, 74, 75, 76, 77, 78, 79, 80, 82, 83, 84, 85, 86, 87, 88, 90, 91, 92, 93, 94, 95, 96, 98, 99, 100, 101, 102, 103, 105, 106, 107, 108, 109, 110, 111, 113, 114, 115, 116, 117, 118, 119, 121, 122, 123, 124, 125, 126, 128, 129, 130, 131, 132, 133, 134, 136, 137, 138, 139, 140, 141, 142, 144, 145, 146, 147, 148, 149, 150, 152, 153, 154, 155, 156, 157, 159, 160, 161, 162, 163, 164, 165, 167, 168, 169, 170, 171, 172, 173, 175, 176, 177, 178, 179, 180, 181, 183, 184, 185, 186, 187, 188, 190, 191, 192, 193, 194, 195, 196, 198, 199, 200, 201, 202, 203, 204, 206, 207, 208, 209, 210, 211, 213, 214, 215, 216, 217, 218, 219, 221, 222, 223, 224, 225, 226, 227, 229, 230, 231, 232, 233, 234, 235, 237, 238, 239, 240, 241, 242, 244, 245, 246, 247, 248, 249, 250, 252, 253, 254, 255 }; int[] arrayOfInt8 = { 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 12, 12, 13, 14, 14, 15, 15, 16, 17, 17, 18, 19, 19, 20, 21, 22, 22, 23, 24, 24, 25, 26, 27, 27, 28, 29, 30, 31, 31, 32, 33, 34, 34, 35, 36, 37, 38, 39, 39, 40, 41, 42, 43, 44, 44, 45, 46, 47, 48, 49, 50, 51, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 126, 127, 128, 129, 130, 131, 132, 134, 135, 136, 137, 138, 139, 140, 142, 143, 144, 145, 146, 147, 149, 150, 151, 152, 153, 155, 156, 157, 158, 159, 160, 162, 163, 164, 165, 166, 168, 169, 170, 171, 173, 174, 175, 176, 177, 179, 180, 181, 182, 184, 185, 186, 187, 189, 190, 191, 192, 194, 195, 196, 197, 199, 200, 201, 202, 204, 205, 206, 208, 209, 210, 211, 213, 214, 215, 217, 218, 219, 221, 222, 223, 224, 226, 227, 228, 230, 231, 232, 234, 235, 236, 238, 239, 240, 242, 243, 244, 246, 247, 248, 250, 251, 252, 254, 255 }; for (int j = 0; j < 256; j++){ arrayOfByte[(1024 + j * 4)] = ((byte)arrayOfInt5[j]); arrayOfByte[(1 + (1024 + j * 4))] = ((byte)arrayOfInt6[j]); arrayOfByte[(2 + (1024 + j * 4))] = ((byte)arrayOfInt7[j]); arrayOfByte[(3 + (1024 + j * 4))] = ((byte)arrayOfInt8[j]); } GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, 256, 2, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, ByteBuffer.wrap(arrayOfByte)); GLES20.glActiveTexture(GLES20.GL_TEXTURE4); mMaskGrey1TextureId = OpenGlUtils.loadTexture(MagicParams.context, "filter/amaro_mask1.jpg"); GLES20.glActiveTexture(GLES20.GL_TEXTURE5); mMaskGrey2TextureId = OpenGlUtils.loadTexture(MagicParams.context, "filter/amaro_mask2.jpg"); GLES20.glActiveTexture(GLES20.GL_TEXTURE6); mMaskGrey3TextureId = OpenGlUtils.loadTexture(MagicParams.context, "filter/toy_mask1.jpg"); } }); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/advanced/MagicSunsetFilter.java ================================================ package com.zero.magicshow.core.filter.advanced; import android.opengl.GLES20; import com.zero.magicshow.R; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.common.utils.MagicParams; import com.zero.magicshow.common.utils.OpenGlUtils; import java.nio.ByteBuffer; public class MagicSunsetFilter extends GPUImageFilter{ private int mMaskGrey1TextureId = -1; private int mMaskGrey1UniformLocation; private int mMaskGrey2TextureId = -1; private int mMaskGrey2UniformLocation; private int[] mToneCurveTexture = { -1 }; private int mToneCurveTextureUniformLocation; public MagicSunsetFilter(){ super(NO_FILTER_VERTEX_SHADER, OpenGlUtils.readShaderFromRawResource(R.raw.sunset)); } public void onDestroy(){ super.onDestroy(); GLES20.glDeleteTextures(3, new int[]{mToneCurveTexture[0], mMaskGrey1TextureId, mMaskGrey2TextureId}, 0); mToneCurveTexture[0] = -1; mMaskGrey1TextureId = -1; mMaskGrey2TextureId = -1; } protected void onDrawArraysAfter(){ if (mToneCurveTexture[0] != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE3); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } if (mMaskGrey1TextureId != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE4); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } if (mMaskGrey2TextureId != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE5); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } } protected void onDrawArraysPre(){ if (mToneCurveTexture[0] != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE3); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mToneCurveTexture[0]); GLES20.glUniform1i(mToneCurveTextureUniformLocation, 3); } if (mMaskGrey1TextureId != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE4); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mMaskGrey1TextureId); GLES20.glUniform1i(mMaskGrey1UniformLocation, 4); } if (mMaskGrey2TextureId != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE5); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mMaskGrey2TextureId); GLES20.glUniform1i(mMaskGrey2UniformLocation, 5); } } public void onInit(){ super.onInit(); mToneCurveTextureUniformLocation = GLES20.glGetUniformLocation(mGLProgId, "curve"); mMaskGrey1UniformLocation = GLES20.glGetUniformLocation(getProgram(), "grey1Frame"); mMaskGrey2UniformLocation = GLES20.glGetUniformLocation(getProgram(), "grey2Frame"); } public void onInitialized(){ super.onInitialized(); runOnDraw(new Runnable(){ public void run(){ GLES20.glGenTextures(1, mToneCurveTexture, 0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mToneCurveTexture[0]); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); byte[] arrayOfByte = new byte[2048]; int[] arrayOfInt1 = { 0, 1, 2, 3, 5, 5, 7, 8, 9, 10, 11, 12, 13, 15, 16, 16, 18, 19, 20, 21, 23, 24, 25, 26, 27, 29, 30, 31, 32, 33, 35, 36, 38, 39, 40, 41, 42, 44, 45, 47, 48, 49, 51, 52, 54, 55, 56, 59, 60, 62, 63, 64, 66, 67, 70, 71, 72, 74, 76, 78, 79, 80, 83, 84, 85, 88, 89, 90, 93, 94, 95, 98, 99, 100, 102, 104, 106, 107, 108, 109, 112, 113, 114, 116, 117, 118, 119, 120, 122, 124, 125, 126, 128, 129, 130, 131, 132, 132, 133, 135, 136, 137, 138, 139, 140, 141, 142, 142, 143, 145, 146, 147, 148, 148, 149, 150, 151, 151, 152, 153, 154, 155, 155, 156, 157, 157, 158, 159, 160, 160, 161, 162, 162, 163, 164, 165, 165, 166, 167, 167, 168, 169, 169, 170, 171, 171, 172, 173, 173, 174, 175, 175, 176, 177, 177, 178, 178, 179, 179, 180, 181, 181, 182, 183, 183, 184, 185, 185, 186, 187, 188, 188, 189, 190, 190, 191, 192, 193, 193, 194, 194, 194, 195, 196, 197, 197, 198, 199, 200, 201, 201, 202, 203, 204, 204, 205, 206, 207, 208, 208, 208, 209, 210, 211, 212, 212, 213, 214, 215, 216, 217, 218, 218, 219, 220, 221, 222, 222, 223, 224, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 234, 235, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 247, 248, 248, 249, 250, 251, 252, 253, 254, 255 }; int[] arrayOfInt2 = { 0, 1, 2, 3, 4, 5, 6, 7, 9, 9, 10, 12, 12, 13, 14, 16, 16, 17, 19, 20, 20, 22, 23, 24, 25, 26, 27, 29, 30, 31, 32, 33, 35, 36, 37, 39, 40, 41, 42, 43, 44, 46, 47, 49, 50, 51, 53, 54, 56, 57, 59, 61, 62, 64, 65, 66, 69, 70, 72, 73, 76, 77, 78, 80, 82, 84, 85, 87, 89, 90, 93, 94, 95, 98, 99, 100, 103, 104, 106, 108, 109, 111, 112, 114, 116, 117, 118, 120, 122, 123, 124, 125, 126, 129, 130, 131, 132, 133, 135, 136, 137, 138, 139, 140, 141, 142, 143, 145, 146, 147, 148, 149, 150, 151, 152, 152, 153, 154, 155, 156, 157, 158, 158, 159, 160, 161, 162, 162, 163, 164, 165, 165, 166, 167, 167, 168, 169, 170, 170, 171, 172, 172, 173, 173, 174, 175, 175, 176, 177, 177, 178, 178, 178, 179, 179, 180, 181, 181, 182, 182, 183, 184, 184, 185, 185, 186, 187, 187, 188, 188, 189, 190, 190, 191, 191, 192, 193, 193, 194, 194, 194, 195, 195, 196, 197, 197, 198, 199, 199, 200, 201, 202, 202, 203, 204, 204, 205, 206, 207, 208, 208, 208, 209, 210, 210, 211, 212, 213, 214, 215, 215, 216, 217, 218, 219, 220, 221, 222, 222, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 234, 235, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 248, 249, 250, 251, 252, 253, 254, 255 }; int[] arrayOfInt3 = { 0, 1, 2, 3, 4, 5, 5, 7, 8, 9, 9, 11, 12, 12, 13, 14, 16, 16, 17, 18, 20, 20, 21, 22, 23, 25, 25, 26, 27, 29, 30, 31, 31, 32, 34, 35, 36, 37, 39, 40, 41, 41, 42, 44, 45, 46, 47, 48, 50, 51, 52, 53, 54, 56, 57, 59, 60, 61, 63, 64, 65, 66, 67, 69, 71, 72, 73, 74, 76, 78, 79, 80, 82, 83, 84, 85, 88, 89, 90, 92, 93, 94, 95, 98, 99, 100, 102, 103, 104, 106, 107, 108, 111, 112, 113, 114, 116, 117, 118, 119, 120, 122, 123, 124, 125, 126, 128, 129, 130, 131, 132, 133, 135, 136, 137, 138, 139, 140, 141, 142, 143, 145, 146, 147, 147, 148, 149, 150, 151, 152, 153, 154, 154, 155, 156, 157, 158, 159, 159, 160, 161, 162, 162, 163, 164, 165, 166, 166, 167, 168, 169, 169, 170, 171, 172, 172, 173, 174, 175, 175, 176, 177, 178, 178, 178, 179, 179, 180, 181, 182, 182, 183, 184, 185, 185, 186, 187, 188, 188, 189, 190, 191, 191, 192, 193, 194, 194, 194, 195, 196, 197, 198, 198, 199, 200, 201, 202, 203, 203, 204, 205, 206, 207, 208, 208, 209, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 222, 223, 224, 225, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 235, 236, 237, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 248, 249, 250, 251, 252, 253, 254, 255 }; int[] arrayOfInt4 = { 0, 1, 3, 4, 6, 7, 9, 10, 12, 13, 14, 16, 17, 19, 20, 21, 23, 24, 26, 27, 28, 30, 31, 32, 34, 35, 36, 38, 39, 40, 42, 43, 44, 45, 47, 48, 49, 51, 52, 53, 54, 55, 57, 58, 59, 60, 62, 63, 64, 65, 66, 67, 69, 70, 71, 72, 73, 74, 75, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 115, 116, 117, 118, 119, 120, 121, 121, 122, 123, 124, 125, 126, 126, 127, 128, 129, 130, 130, 131, 132, 133, 134, 135, 135, 136, 137, 138, 139, 140, 141, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 230, 231, 232, 233, 234, 235, 235, 236, 237, 238, 239, 239, 240, 241, 242, 243, 243, 244, 245, 245, 246, 247, 247, 248, 249, 249, 250, 251, 251, 252, 252, 253, 253, 254, 254, 255 }; for (int i = 0; i < 256; i++) { arrayOfByte[(i * 4)] = ((byte)arrayOfInt1[i]); arrayOfByte[(1 + i * 4)] = ((byte)arrayOfInt2[i]); arrayOfByte[(2 + i * 4)] = ((byte)arrayOfInt3[i]); arrayOfByte[(3 + i * 4)] = ((byte)arrayOfInt4[i]); } int[] arrayOfInt5 = { 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 8, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 20, 20, 20, 21, 21, 21, 22, 22, 23, 23, 23, 24, 24, 24, 25, 25, 25, 25, 26, 26, 27, 27, 28, 28, 28, 28, 29, 29, 30, 29, 31, 31, 31, 31, 32, 32, 33, 33, 34, 34, 34, 34, 35, 35, 36, 36, 37, 37, 37, 38, 38, 39, 39, 39, 40, 40, 40, 41, 42, 42, 43, 43, 44, 44, 45, 45, 45, 46, 47, 47, 48, 48, 49, 50, 51, 51, 52, 52, 53, 53, 54, 55, 55, 56, 57, 57, 58, 59, 60, 60, 61, 62, 63, 63, 64, 65, 66, 67, 68, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 88, 89, 90, 91, 93, 94, 95, 96, 97, 98, 100, 101, 103, 104, 105, 107, 108, 110, 111, 113, 115, 116, 118, 119, 120, 122, 123, 125, 127, 128, 130, 132, 134, 135, 137, 139, 141, 143, 144, 146, 148, 150, 152, 154, 156, 158, 160, 163, 165, 167, 169, 171, 173, 175, 178, 180, 182, 185, 187, 189, 192, 194, 197, 199, 201, 204, 206, 209, 211, 214, 216, 219, 221, 224, 226, 229, 232, 234, 236, 239, 241, 245, 247, 250, 252, 255 }; for (int j = 0; j < 256; j++) { arrayOfByte[(1024 + j * 4)] = ((byte)arrayOfInt5[j]); arrayOfByte[(1 + (1024 + j * 4))] = ((byte)arrayOfInt5[j]); arrayOfByte[(2 + (1024 + j * 4))] = ((byte)arrayOfInt5[j]); arrayOfByte[(3 + (1024 + j * 4))] = -1; } GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, 256, 2, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, ByteBuffer.wrap(arrayOfByte)); mMaskGrey1TextureId = OpenGlUtils.loadTexture(MagicParams.context, "filter/rise_mask1.jpg"); mMaskGrey2TextureId = OpenGlUtils.loadTexture(MagicParams.context, "filter/rise_mask2.jpg"); } }); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/advanced/MagicSutroFilter.java ================================================ package com.zero.magicshow.core.filter.advanced; import android.opengl.GLES20; import com.zero.magicshow.R; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.common.utils.MagicParams; import com.zero.magicshow.common.utils.OpenGlUtils; public class MagicSutroFilter extends GPUImageFilter{ private int[] inputTextureHandles = {-1,-1,-1,-1,-1}; private int[] inputTextureUniformLocations = {-1,-1,-1,-1,-1}; private int mGLStrengthLocation; public MagicSutroFilter(){ super(NO_FILTER_VERTEX_SHADER, OpenGlUtils.readShaderFromRawResource(R.raw.sutro)); } public void onDestroy() { super.onDestroy(); GLES20.glDeleteTextures(inputTextureHandles.length, inputTextureHandles, 0); for(int i = 0; i < inputTextureHandles.length; i++) inputTextureHandles[i] = -1; } protected void onDrawArraysAfter(){ for(int i = 0; i < inputTextureHandles.length && inputTextureHandles[i] != OpenGlUtils.NO_TEXTURE; i++){ GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + (i+3)); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } } protected void onDrawArraysPre(){ for(int i = 0; i < inputTextureHandles.length && inputTextureHandles[i] != OpenGlUtils.NO_TEXTURE; i++){ GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + (i+3) ); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, inputTextureHandles[i]); GLES20.glUniform1i(inputTextureUniformLocations[i], (i+3)); } } public void onInit(){ super.onInit(); for(int i=0; i < inputTextureUniformLocations.length; i++) inputTextureUniformLocations[i] = GLES20.glGetUniformLocation(getProgram(), "inputImageTexture"+(2+i)); mGLStrengthLocation = GLES20.glGetUniformLocation(mGLProgId, "strength"); } public void onInitialized(){ super.onInitialized(); setFloat(mGLStrengthLocation, 1.0f); runOnDraw(new Runnable(){ public void run(){ inputTextureHandles[0] = OpenGlUtils.loadTexture(MagicParams.context, "filter/vignette_map.png"); inputTextureHandles[1] = OpenGlUtils.loadTexture(MagicParams.context, "filter/sutrometal.png"); inputTextureHandles[2] = OpenGlUtils.loadTexture(MagicParams.context, "filter/softlight.png"); inputTextureHandles[3] = OpenGlUtils.loadTexture(MagicParams.context, "filter/sutroedgeburn.png"); inputTextureHandles[4] = OpenGlUtils.loadTexture(MagicParams.context, "filter/sutrocurves.png"); } }); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/advanced/MagicSweetsFilter.java ================================================ package com.zero.magicshow.core.filter.advanced; import android.opengl.GLES20; import com.zero.magicshow.R; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.common.utils.MagicParams; import com.zero.magicshow.common.utils.OpenGlUtils; import java.nio.ByteBuffer; public class MagicSweetsFilter extends GPUImageFilter{ private int[] mToneCurveTexture = {-1}; private int mToneCurveTextureUniformLocation; private int mMaskGrey1TextureId = -1; private int mMaskGrey1UniformLocation; private int mLowPerformanceUniformLocation; public MagicSweetsFilter(){ super(NO_FILTER_VERTEX_SHADER, OpenGlUtils.readShaderFromRawResource(R.raw.sweets)); } public void onDestroy(){ super.onDestroy(); GLES20.glDeleteTextures(2, new int[]{mToneCurveTexture[0], mMaskGrey1TextureId}, 0); mToneCurveTexture[0] = -1; mMaskGrey1TextureId = -1; } protected void onDrawArraysAfter(){ if (mToneCurveTexture[0] != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE3); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } if (mMaskGrey1TextureId != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE4); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } } protected void onDrawArraysPre(){ if (mToneCurveTexture[0] != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE3); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mToneCurveTexture[0]); GLES20.glUniform1i(mToneCurveTextureUniformLocation, 3); } if (mMaskGrey1TextureId != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE4); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mMaskGrey1TextureId); GLES20.glUniform1i(mMaskGrey1UniformLocation, 4); } } public void onInit(){ super.onInit(); mToneCurveTextureUniformLocation = GLES20.glGetUniformLocation(mGLProgId, "curve"); mMaskGrey1UniformLocation = GLES20.glGetUniformLocation(getProgram(), "grey1Frame"); mLowPerformanceUniformLocation = GLES20.glGetUniformLocation(getProgram(), "lowPerformance"); setInteger(mLowPerformanceUniformLocation, 1); } public void onInitialized(){ super.onInitialized(); runOnDraw(new Runnable(){ public void run(){ GLES20.glGenTextures(1, mToneCurveTexture, 0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mToneCurveTexture[0]); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); byte[] arrayOfByte = new byte[1024]; int[] arrayOfInt = { 0, 1, 2, 2, 3, 4, 5, 6, 6, 7, 8, 9, 10, 10, 11, 12, 13, 14, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 23, 24, 24, 25, 26, 27, 28, 29, 30, 30, 31, 32, 33, 34, 35, 36, 37, 38, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 71, 72, 73, 74, 75, 76, 77, 79, 80, 81, 82, 83, 84, 86, 87, 88, 89, 90, 92, 93, 94, 95, 96, 98, 99, 100, 101, 103, 104, 105, 106, 108, 109, 110, 111, 113, 114, 115, 116, 118, 119, 120, 121, 123, 124, 125, 126, 128, 129, 130, 132, 133, 134, 135, 137, 138, 139, 140, 142, 143, 144, 145, 147, 148, 149, 150, 152, 153, 154, 155, 157, 158, 159, 160, 161, 163, 164, 165, 166, 167, 169, 170, 171, 172, 173, 174, 176, 177, 178, 179, 180, 181, 182, 183, 184, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 209, 210, 211, 212, 213, 214, 215, 216, 217, 217, 218, 219, 220, 221, 222, 222, 223, 224, 225, 226, 227, 227, 228, 229, 230, 230, 231, 232, 233, 234, 234, 235, 236, 237, 237, 238, 239, 240, 240, 241, 242, 243, 243, 244, 245, 246, 246, 247, 248, 248, 249, 250, 251, 251, 252, 253, 254, 254, 255 }; for (int i = 0; i < 256; i++){ arrayOfByte[(i * 4)] = ((byte)arrayOfInt[i]); arrayOfByte[(1 + i * 4)] = ((byte)arrayOfInt[i]); arrayOfByte[(2 + i * 4)] = ((byte)arrayOfInt[i]); arrayOfByte[(3 + i * 4)] = ((byte)i); } GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, 256, 1, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, ByteBuffer.wrap(arrayOfByte)); mMaskGrey1TextureId = OpenGlUtils.loadTexture(MagicParams.context, "filter/rise_mask2.jpg"); } }); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/advanced/MagicTenderFilter.java ================================================ package com.zero.magicshow.core.filter.advanced; import android.opengl.GLES20; import com.zero.magicshow.R; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.common.utils.MagicParams; import com.zero.magicshow.common.utils.OpenGlUtils; import java.nio.ByteBuffer; public class MagicTenderFilter extends GPUImageFilter{ private int[] mToneCurveTexture = {-1}; private int mToneCurveTextureUniformLocation; private int mMaskGrey1TextureId = -1; private int mMaskGrey1UniformLocation; public MagicTenderFilter(){ super(NO_FILTER_VERTEX_SHADER, OpenGlUtils.readShaderFromRawResource(R.raw.tender)); } public void onDestroy(){ super.onDestroy(); GLES20.glDeleteTextures(2, new int[]{mToneCurveTexture[0], mMaskGrey1TextureId}, 0); mToneCurveTexture[0] = -1; mMaskGrey1TextureId = -1; } protected void onDrawArraysAfter(){ if (mToneCurveTexture[0] != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE3); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } if (mMaskGrey1TextureId != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE4); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } } protected void onDrawArraysPre(){ if (mToneCurveTexture[0] != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE3); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mToneCurveTexture[0]); GLES20.glUniform1i(mToneCurveTextureUniformLocation, 3); } if (mMaskGrey1TextureId != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE4); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mMaskGrey1TextureId); GLES20.glUniform1i(mMaskGrey1UniformLocation, 4); } } public void onInit(){ super.onInit(); mToneCurveTextureUniformLocation = GLES20.glGetUniformLocation(mGLProgId, "curve"); mMaskGrey1UniformLocation = GLES20.glGetUniformLocation(getProgram(), "grey1Frame"); } public void onInitialized(){ super.onInitialized(); runOnDraw(new Runnable(){ public void run(){ GLES20.glGenTextures(1, mToneCurveTexture, 0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mToneCurveTexture[0]); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); byte[] arrayOfByte = new byte[1024]; int[] arrayOfInt1 = { 10, 12, 14, 15, 17, 19, 21, 22, 24, 26, 28, 29, 31, 33, 35, 38, 40, 41, 43, 45, 47, 48, 50, 52, 53, 55, 57, 58, 60, 61, 63, 65, 66, 68, 69, 71, 72, 74, 75, 77, 79, 80, 81, 83, 84, 86, 87, 89, 92, 93, 94, 96, 97, 99, 100, 101, 103, 104, 105, 107, 108, 109, 110, 112, 113, 114, 116, 117, 118, 119, 120, 122, 123, 124, 125, 126, 127, 129, 130, 131, 132, 133, 134, 135, 136, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 158, 159, 160, 161, 162, 163, 164, 165, 166, 166, 167, 168, 169, 170, 171, 171, 172, 173, 174, 175, 175, 176, 177, 178, 179, 179, 180, 181, 182, 182, 183, 184, 184, 185, 186, 187, 187, 188, 189, 189, 190, 191, 191, 192, 193, 193, 194, 195, 195, 196, 196, 197, 198, 198, 199, 200, 200, 201, 201, 202, 202, 203, 204, 204, 205, 205, 206, 206, 207, 207, 208, 209, 209, 210, 210, 211, 211, 212, 212, 213, 213, 214, 214, 215, 215, 216, 216, 216, 217, 217, 218, 218, 219, 219, 219, 220, 220, 221, 221, 222, 222, 223, 223, 224, 224, 224, 225, 225, 226, 226, 227, 227, 227, 228, 228, 229, 229, 230, 230, 230, 231, 231, 232, 232, 232, 233, 233, 234, 234, 234, 234, 235, 235, 236, 236, 236, 237, 237, 238, 238, 238, 239, 239, 240, 240, 240, 241, 241, 242, 242 }; int[] arrayOfInt2 = { 10, 12, 14, 15, 17, 19, 19, 21, 22, 24, 26, 28, 29, 31, 33, 35, 36, 36, 38, 40, 41, 43, 45, 47, 48, 50, 52, 52, 53, 55, 57, 58, 60, 61, 63, 65, 66, 68, 69, 69, 71, 72, 74, 75, 77, 79, 80, 81, 83, 84, 86, 86, 87, 89, 90, 92, 93, 94, 96, 97, 99, 100, 101, 103, 103, 104, 105, 107, 108, 109, 110, 112, 113, 114, 116, 117, 118, 119, 120, 122, 122, 123, 124, 125, 126, 127, 129, 130, 131, 132, 133, 134, 135, 136, 138, 139, 140, 141, 142, 143, 144, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 158, 159, 160, 161, 162, 163, 164, 165, 166, 166, 167, 168, 169, 170, 171, 171, 172, 173, 174, 175, 175, 176, 177, 178, 179, 179, 180, 181, 182, 182, 183, 184, 184, 185, 186, 187, 187, 188, 189, 190, 191, 191, 192, 193, 193, 194, 195, 195, 196, 196, 197, 198, 198, 199, 200, 200, 201, 201, 202, 202, 204, 204, 205, 205, 206, 206, 207, 207, 208, 209, 209, 210, 210, 211, 211, 212, 213, 213, 214, 214, 215, 215, 216, 216, 217, 217, 218, 218, 219, 219, 220, 220, 221, 221, 222, 222, 223, 223, 224, 224, 224, 225, 226, 226, 227, 227, 227, 228, 228, 229, 229, 230, 230, 231, 231, 232, 232, 232, 233, 233, 234, 234, 234, 235, 236, 236, 236, 237, 237, 238, 238, 238, 239, 239, 240, 240, 241, 241, 242, 242 }; int[] arrayOfInt3 = { 10, 12, 12, 14, 15, 15, 17, 17, 19, 21, 21, 22, 24, 24, 26, 28, 28, 29, 31, 31, 33, 33, 35, 36, 36, 38, 40, 40, 41, 43, 43, 45, 47, 47, 48, 50, 52, 52, 53, 55, 55, 57, 58, 58, 60, 61, 63, 63, 65, 66, 68, 68, 69, 71, 71, 72, 74, 75, 77, 77, 79, 80, 81, 81, 83, 84, 86, 87, 87, 89, 90, 92, 93, 94, 94, 96, 97, 99, 100, 101, 103, 103, 104, 105, 107, 108, 109, 110, 112, 113, 113, 114, 116, 117, 118, 119, 120, 122, 123, 124, 125, 126, 127, 129, 130, 130, 131, 132, 133, 134, 135, 136, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 154, 155, 156, 157, 158, 158, 159, 160, 161, 162, 163, 164, 165, 166, 166, 167, 169, 170, 171, 171, 172, 173, 174, 175, 175, 176, 178, 179, 179, 180, 181, 182, 182, 183, 184, 185, 186, 187, 187, 188, 189, 190, 191, 191, 192, 193, 193, 195, 195, 196, 196, 197, 198, 199, 200, 200, 201, 201, 202, 203, 204, 204, 205, 206, 206, 207, 207, 209, 209, 210, 210, 211, 212, 212, 213, 213, 214, 215, 215, 216, 217, 217, 218, 218, 219, 219, 220, 220, 221, 222, 222, 223, 223, 224, 224, 225, 225, 226, 227, 227, 227, 228, 229, 229, 230, 230, 231, 231, 232, 232, 233, 233, 234, 234, 235, 235, 236, 236, 237, 238, 238, 238, 239, 240, 240, 240, 241, 242, 242 }; int[] arrayOfInt4 = { 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 8, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 20, 20, 20, 21, 21, 21, 22, 22, 23, 23, 23, 24, 24, 24, 25, 25, 25, 25, 26, 26, 27, 27, 28, 28, 28, 28, 29, 29, 30, 29, 31, 31, 31, 31, 32, 32, 33, 33, 34, 34, 34, 34, 35, 35, 36, 36, 37, 37, 37, 38, 38, 39, 39, 39, 40, 40, 40, 41, 42, 42, 43, 43, 44, 44, 45, 45, 45, 46, 47, 47, 48, 48, 49, 50, 51, 51, 52, 52, 53, 53, 54, 55, 55, 56, 57, 57, 58, 59, 60, 60, 61, 62, 63, 63, 64, 65, 66, 67, 68, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 88, 89, 90, 91, 93, 94, 95, 96, 97, 98, 100, 101, 103, 104, 105, 107, 108, 110, 111, 113, 115, 116, 118, 119, 120, 122, 123, 125, 127, 128, 130, 132, 134, 135, 137, 139, 141, 143, 144, 146, 148, 150, 152, 154, 156, 158, 160, 163, 165, 167, 169, 171, 173, 175, 178, 180, 182, 185, 187, 189, 192, 194, 197, 199, 201, 204, 206, 209, 211, 214, 216, 219, 221, 224, 226, 229, 232, 234, 236, 239, 241, 245, 247, 250, 252, 255 }; for (int i = 0; i < 256; i++){ arrayOfByte[(i * 4)] = ((byte)arrayOfInt1[i]); arrayOfByte[(1 + i * 4)] = ((byte)arrayOfInt2[i]); arrayOfByte[(2 + i * 4)] = ((byte)arrayOfInt3[i]); arrayOfByte[(3 + i * 4)] = ((byte)arrayOfInt4[i]); } GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, 256, 1, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, ByteBuffer.wrap(arrayOfByte)); mMaskGrey1TextureId = OpenGlUtils.loadTexture(MagicParams.context, "filter/bluevintage_mask1.jpg"); } }); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/advanced/MagicToasterFilter.java ================================================ package com.zero.magicshow.core.filter.advanced; import android.opengl.GLES20; import com.zero.magicshow.R; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.common.utils.MagicParams; import com.zero.magicshow.common.utils.OpenGlUtils; public class MagicToasterFilter extends GPUImageFilter{ private int[] inputTextureHandles = {-1,-1,-1,-1,-1}; private int[] inputTextureUniformLocations = {-1,-1,-1,-1,-1}; private int mGLStrengthLocation; public MagicToasterFilter(){ super(NO_FILTER_VERTEX_SHADER, OpenGlUtils.readShaderFromRawResource(R.raw.toaster2_filter_shader)); } public void onDestroy() { super.onDestroy(); GLES20.glDeleteTextures(inputTextureHandles.length, inputTextureHandles, 0); for(int i = 0; i < inputTextureHandles.length; i++) inputTextureHandles[i] = -1; } protected void onDrawArraysAfter(){ for(int i = 0; i < inputTextureHandles.length && inputTextureHandles[i] != OpenGlUtils.NO_TEXTURE; i++){ GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + (i+3)); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } } protected void onDrawArraysPre(){ for(int i = 0; i < inputTextureHandles.length && inputTextureHandles[i] != OpenGlUtils.NO_TEXTURE; i++){ GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + (i+3) ); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, inputTextureHandles[i]); GLES20.glUniform1i(inputTextureUniformLocations[i], (i+3)); } } public void onInit(){ super.onInit(); for(int i = 0; i < inputTextureUniformLocations.length; i++) inputTextureUniformLocations[i] = GLES20.glGetUniformLocation(getProgram(), "inputImageTexture"+(2+i)); mGLStrengthLocation = GLES20.glGetUniformLocation(mGLProgId, "strength"); } public void onInitialized(){ super.onInitialized(); setFloat(mGLStrengthLocation, 1.0f); runOnDraw(new Runnable(){ public void run(){ inputTextureHandles[0] = OpenGlUtils.loadTexture(MagicParams.context, "filter/toastermetal.png"); inputTextureHandles[1] = OpenGlUtils.loadTexture(MagicParams.context, "filter/toastersoftlight.png"); inputTextureHandles[2] = OpenGlUtils.loadTexture(MagicParams.context, "filter/toastercurves.png"); inputTextureHandles[3] = OpenGlUtils.loadTexture(MagicParams.context, "filter/toasteroverlaymapwarm.png"); inputTextureHandles[4] = OpenGlUtils.loadTexture(MagicParams.context, "filter/toastercolorshift.png"); } }); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/advanced/MagicValenciaFilter.java ================================================ package com.zero.magicshow.core.filter.advanced; import android.opengl.GLES20; import com.zero.magicshow.R; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.common.utils.MagicParams; import com.zero.magicshow.common.utils.OpenGlUtils; public class MagicValenciaFilter extends GPUImageFilter{ private int[] inputTextureHandles = {-1,-1}; private int[] inputTextureUniformLocations = {-1,-1}; private int mGLStrengthLocation; public MagicValenciaFilter(){ super(NO_FILTER_VERTEX_SHADER, OpenGlUtils.readShaderFromRawResource(R.raw.valencia)); } protected void onDrawArraysAfter(){ for(int i = 0; i < inputTextureHandles.length && inputTextureHandles[i] != OpenGlUtils.NO_TEXTURE; i++){ GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + (i+3)); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } } protected void onDrawArraysPre(){ for(int i = 0; i < inputTextureHandles.length && inputTextureHandles[i] != OpenGlUtils.NO_TEXTURE; i++){ GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + (i+3) ); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, inputTextureHandles[i]); GLES20.glUniform1i(inputTextureUniformLocations[i], (i+3)); } } public void onInit(){ super.onInit(); for(int i = 0; i < inputTextureUniformLocations.length; i++) inputTextureUniformLocations[i] = GLES20.glGetUniformLocation(getProgram(), "inputImageTexture"+(2+i)); mGLStrengthLocation = GLES20.glGetUniformLocation(mGLProgId, "strength"); } public void onDestroy() { super.onDestroy(); GLES20.glDeleteTextures(inputTextureHandles.length, inputTextureHandles, 0); for(int i = 0; i < inputTextureHandles.length; i++) inputTextureHandles[i] = -1; } public void onInitialized(){ super.onInitialized(); setFloat(mGLStrengthLocation, 1.0f); runOnDraw(new Runnable(){ public void run(){ inputTextureHandles[0] = OpenGlUtils.loadTexture(MagicParams.context, "filter/valenciamap.png"); inputTextureHandles[1] = OpenGlUtils.loadTexture(MagicParams.context, "filter/valenciagradientmap.png"); } }); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/advanced/MagicWaldenFilter.java ================================================ package com.zero.magicshow.core.filter.advanced; import android.opengl.GLES20; import com.zero.magicshow.R; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.common.utils.MagicParams; import com.zero.magicshow.common.utils.OpenGlUtils; public class MagicWaldenFilter extends GPUImageFilter{ private int[] inputTextureHandles = {-1,-1}; private int[] inputTextureUniformLocations = {-1,-1}; private int mGLStrengthLocation; public MagicWaldenFilter(){ super(NO_FILTER_VERTEX_SHADER, OpenGlUtils.readShaderFromRawResource(R.raw.walden)); } public void onDestroy() { super.onDestroy(); GLES20.glDeleteTextures(inputTextureHandles.length, inputTextureHandles, 0); for(int i = 0; i < inputTextureHandles.length; i++) inputTextureHandles[i] = -1; } protected void onDrawArraysAfter(){ for(int i = 0; i < inputTextureHandles.length && inputTextureHandles[i] != OpenGlUtils.NO_TEXTURE; i++){ GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + (i+3)); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } } protected void onDrawArraysPre(){ for(int i = 0; i < inputTextureHandles.length && inputTextureHandles[i] != OpenGlUtils.NO_TEXTURE; i++){ GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + (i+3) ); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, inputTextureHandles[i]); GLES20.glUniform1i(inputTextureUniformLocations[i], (i+3)); } } public void onInit(){ super.onInit(); for(int i = 0; i < inputTextureUniformLocations.length; i++) inputTextureUniformLocations[i] = GLES20.glGetUniformLocation(getProgram(), "inputImageTexture"+(2+i)); mGLStrengthLocation = GLES20.glGetUniformLocation(mGLProgId, "strength"); } public void onInitialized(){ super.onInitialized(); setFloat(mGLStrengthLocation, 1.0f); runOnDraw(new Runnable(){ public void run(){ inputTextureHandles[0] = OpenGlUtils.loadTexture(MagicParams.context, "filter/walden_map.png"); inputTextureHandles[1] = OpenGlUtils.loadTexture(MagicParams.context, "filter/vignette_map.png"); } }); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/advanced/MagicWarmFilter.java ================================================ package com.zero.magicshow.core.filter.advanced; import android.opengl.GLES20; import com.zero.magicshow.R; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.common.utils.MagicParams; import com.zero.magicshow.common.utils.OpenGlUtils; import java.nio.ByteBuffer; public class MagicWarmFilter extends GPUImageFilter{ private int[] mToneCurveTexture = {-1}; private int mToneCurveTextureUniformLocation; private int mMaskGrey1TextureId = -1; private int mMaskGrey1UniformLocation; private int mMaskGrey2TextureId = -1; private int mMaskGrey2UniformLocation; public MagicWarmFilter(){ super(NO_FILTER_VERTEX_SHADER, OpenGlUtils.readShaderFromRawResource(R.raw.warm)); } public void onDestroy(){ super.onDestroy(); GLES20.glDeleteTextures(3, new int[]{mToneCurveTexture[0], mMaskGrey1TextureId, mMaskGrey2TextureId}, 0); mToneCurveTexture[0] = -1; mMaskGrey1TextureId = -1; mMaskGrey2TextureId = -1; } protected void onDrawArraysAfter(){ if (mToneCurveTexture[0] != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE3); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } if (mMaskGrey1TextureId != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE4); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } if (mMaskGrey2TextureId != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE5); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } } protected void onDrawArraysPre(){ if (mToneCurveTexture[0] != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE3); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mToneCurveTexture[0]); GLES20.glUniform1i(mToneCurveTextureUniformLocation, 3); } if (mMaskGrey1TextureId != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE4); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mMaskGrey1TextureId); GLES20.glUniform1i(mMaskGrey1UniformLocation, 4); } if (mMaskGrey2TextureId != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE5); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mMaskGrey2TextureId); GLES20.glUniform1i(mMaskGrey2UniformLocation, 5); } } public void onInit(){ super.onInit(); mToneCurveTextureUniformLocation = GLES20.glGetUniformLocation(mGLProgId, "curve"); mMaskGrey1UniformLocation = GLES20.glGetUniformLocation(getProgram(), "layerImage"); mMaskGrey2UniformLocation = GLES20.glGetUniformLocation(getProgram(), "greyFrame"); } public void onInitialized(){ super.onInitialized(); runOnDraw(new Runnable(){ public void run(){ GLES20.glGenTextures(1, mToneCurveTexture, 0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mToneCurveTexture[0]); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); byte[] arrayOfByte = new byte[2048]; int[] arrayOfInt1 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6, 9, 12, 14, 17, 20, 23, 25, 28, 31, 33, 35, 38, 40, 42, 44, 46, 48, 50, 52, 53, 55, 57, 58, 60, 61, 63, 64, 65, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 80, 81, 82, 83, 83, 84, 85, 85, 86, 87, 87, 88, 88, 89, 90, 90, 91, 91, 92, 93, 93, 94, 94, 95, 96, 96, 97, 98, 99, 99, 100, 101, 102, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 114, 115, 116, 117, 119, 120, 121, 123, 124, 126, 127, 128, 130, 131, 133, 135, 136, 138, 139, 141, 143, 144, 146, 148, 149, 151, 153, 154, 156, 158, 159, 161, 163, 165, 166, 168, 170, 172, 173, 175, 177, 179, 180, 182, 184, 185, 187, 189, 190, 192, 194, 195, 197, 199, 200, 202, 203, 205, 207, 208, 210, 211, 213, 214, 215, 217, 218, 219, 221, 222, 223, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 238, 239, 240, 241, 241, 242, 243, 243, 244, 244, 245, 245, 246, 246, 247, 247, 248, 248, 249, 249, 249, 250, 250, 250, 251, 251, 251, 251, 252, 252, 252, 252, 253, 253, 253, 253, 253, 253, 254, 254, 254, 254, 254, 254, 254, 254, 255, 255, 255, 255, 255, 255 }; int[] arrayOfInt2 = { 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 87, 88, 89, 90, 91, 92, 93, 94, 95, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 235, 236, 237, 238, 239, 240, 241, 242 }; int[] arrayOfInt3 = { 9, 10, 11, 11, 12, 13, 14, 15, 16, 16, 17, 18, 19, 20, 21, 21, 22, 23, 24, 25, 26, 26, 27, 28, 29, 30, 31, 31, 32, 33, 34, 35, 36, 36, 37, 38, 39, 40, 40, 41, 42, 43, 44, 45, 45, 46, 47, 48, 49, 50, 50, 51, 52, 53, 54, 55, 55, 56, 57, 58, 59, 60, 60, 61, 62, 63, 64, 65, 66, 66, 67, 68, 69, 70, 71, 71, 72, 73, 74, 75, 76, 76, 77, 78, 79, 80, 81, 81, 82, 83, 84, 85, 86, 87, 87, 88, 89, 90, 91, 92, 93, 93, 94, 95, 96, 97, 98, 98, 99, 100, 101, 102, 103, 104, 104, 105, 106, 107, 108, 109, 110, 110, 111, 112, 113, 114, 115, 116, 116, 117, 118, 119, 120, 121, 122, 123, 123, 124, 125, 126, 127, 128, 129, 130, 130, 131, 132, 133, 134, 135, 136, 137, 137, 138, 139, 140, 141, 142, 143, 144, 144, 145, 146, 147, 148, 149, 150, 151, 152, 152, 153, 154, 155, 156, 157, 158, 159, 160, 160, 161, 162, 163, 164, 165, 166, 167, 168, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 225, 226, 227, 228, 229, 230 }; int[] arrayOfInt4 = { 0, 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 28, 29, 30, 31, 33, 34, 35, 37, 38, 40, 41, 42, 44, 45, 47, 48, 50, 51, 53, 54, 56, 58, 59, 61, 62, 64, 65, 67, 69, 70, 72, 73, 75, 77, 78, 80, 82, 83, 85, 86, 88, 90, 91, 93, 94, 96, 98, 99, 101, 102, 104, 105, 107, 108, 110, 111, 113, 114, 116, 117, 119, 120, 122, 123, 124, 126, 127, 129, 130, 131, 133, 134, 136, 137, 138, 140, 141, 142, 144, 145, 146, 147, 149, 150, 151, 153, 154, 155, 156, 157, 159, 160, 161, 162, 163, 165, 166, 167, 168, 169, 170, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 203, 204, 205, 206, 207, 208, 208, 209, 210, 211, 212, 212, 213, 214, 215, 216, 216, 217, 218, 218, 219, 220, 221, 221, 222, 223, 223, 224, 225, 225, 226, 227, 227, 228, 228, 229, 230, 230, 231, 231, 232, 233, 233, 234, 234, 235, 235, 236, 236, 237, 238, 238, 239, 239, 240, 240, 241, 241, 242, 242, 243, 243, 244, 244, 245, 245, 246, 246, 247, 247, 248, 248, 249, 249, 249, 250, 250, 251, 251, 252, 252, 253, 253, 254, 254, 255, 255 }; for (int i = 0; i < 256; i++){ arrayOfByte[(i * 4)] = ((byte)arrayOfInt1[i]); arrayOfByte[(1 + i * 4)] = ((byte)arrayOfInt2[i]); arrayOfByte[(2 + i * 4)] = ((byte)arrayOfInt3[i]); arrayOfByte[(3 + i * 4)] = ((byte)arrayOfInt4[i]); } int[] arrayOfInt5 = { 0, 1, 1, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 11, 11, 11, 12, 13, 13, 14, 15, 15, 16, 17, 18, 18, 19, 20, 21, 21, 22, 23, 24, 24, 25, 26, 27, 28, 28, 28, 29, 30, 31, 31, 32, 33, 34, 35, 36, 36, 37, 38, 39, 39, 40, 41, 41, 42, 43, 44, 45, 46, 47, 47, 48, 49, 50, 51, 52, 53, 54, 55, 55, 56, 57, 58, 59, 60, 61, 62, 63, 63, 64, 65, 66, 68, 69, 70, 71, 71, 72, 73, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 86, 87, 88, 89, 90, 92, 93, 94, 95, 95, 97, 98, 99, 100, 102, 103, 104, 105, 106, 108, 109, 110, 111, 112, 114, 115, 116, 117, 118, 119, 122, 123, 124, 125, 126, 127, 129, 130, 131, 132, 133, 134, 135, 137, 138, 139, 141, 142, 143, 144, 145, 146, 148, 149, 150, 151, 152, 154, 155, 156, 157, 158, 159, 161, 162, 164, 165, 166, 167, 168, 169, 170, 171, 173, 174, 175, 176, 177, 178, 179, 180, 183, 184, 185, 186, 187, 188, 190, 191, 192, 193, 194, 195, 196, 198, 199, 200, 201, 202, 203, 205, 206, 207, 208, 209, 210, 212, 213, 214, 215, 216, 217, 219, 220, 221, 222, 223, 224, 226, 227, 228, 229, 230, 231, 233, 234, 235, 236, 237, 239, 240, 241, 242, 243, 243, 244, 246, 247, 248, 249, 250, 251, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 }; int[] arrayOfInt6 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 28, 29, 30, 31, 32, 33, 34, 35, 37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 47, 48, 49, 50, 51, 52, 53, 54, 55, 55, 56, 57, 58, 60, 61, 62, 63, 63, 64, 65, 66, 67, 68, 69, 70, 71, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 80, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 133, 134, 135, 136, 137, 138, 139, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 154, 155, 156, 157, 158, 159, 161, 162, 164, 165, 166, 167, 168, 169, 170, 171, 173, 174, 175, 176, 177, 178, 179, 180, 182, 183, 184, 185, 186, 187, 190, 191, 192, 193, 194, 195, 196, 198, 199, 200, 201, 202, 203, 205, 206, 207, 208, 209, 210, 212, 213, 214, 215, 216, 217, 220, 221, 222, 223, 224, 226, 227, 228, 229, 230, 231, 233, 234, 235, 236, 237, 239, 240, 241, 242, 243, 244, 246, 247, 249, 250, 251, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 }; int[] arrayOfInt7 = { 45, 45, 46, 46, 47, 47, 47, 47, 48, 48, 49, 49, 50, 50, 50, 51, 51, 52, 52, 53, 53, 54, 54, 55, 55, 55, 55, 56, 56, 57, 57, 58, 58, 59, 59, 60, 60, 61, 61, 62, 62, 63, 63, 63, 63, 64, 64, 65, 65, 66, 66, 67, 67, 68, 69, 69, 70, 70, 71, 71, 71, 72, 72, 73, 73, 74, 75, 75, 76, 76, 77, 78, 78, 79, 79, 80, 80, 80, 81, 82, 82, 83, 84, 84, 85, 86, 87, 87, 88, 89, 89, 90, 91, 92, 92, 93, 94, 95, 95, 95, 96, 97, 98, 98, 99, 100, 101, 102, 103, 103, 104, 105, 106, 107, 108, 109, 110, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 135, 136, 137, 138, 139, 141, 142, 143, 144, 146, 147, 148, 149, 150, 151, 152, 154, 156, 157, 158, 159, 160, 161, 162, 165, 166, 167, 168, 169, 170, 171, 173, 175, 176, 177, 178, 179, 180, 182, 183, 184, 186, 187, 188, 190, 191, 192, 193, 194, 195, 196, 198, 199, 200, 201, 202, 203, 205, 206, 207, 208, 209, 210, 212, 213, 214, 215, 216, 217, 217, 219, 220, 221, 222, 223, 224, 226, 227, 227, 228, 229, 230, 231, 233, 234, 235, 235, 236, 237, 239, 240, 241, 241, 242, 243, 244, 246, 246, 247, 248, 249, 250, 251, 251, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }; int[] arrayOfInt8 = { 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 8, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 20, 20, 20, 21, 21, 21, 22, 22, 23, 23, 23, 24, 24, 24, 25, 25, 25, 25, 26, 26, 27, 27, 28, 28, 28, 28, 29, 29, 30, 29, 31, 31, 31, 31, 32, 32, 33, 33, 34, 34, 34, 34, 35, 35, 36, 36, 37, 37, 37, 38, 38, 39, 39, 39, 40, 40, 40, 41, 42, 42, 43, 43, 44, 44, 45, 45, 45, 46, 47, 47, 48, 48, 49, 50, 51, 51, 52, 52, 53, 53, 54, 55, 55, 56, 57, 57, 58, 59, 60, 60, 61, 62, 63, 63, 64, 65, 66, 67, 68, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 88, 89, 90, 91, 93, 94, 95, 96, 97, 98, 100, 101, 103, 104, 105, 107, 108, 110, 111, 113, 115, 116, 118, 119, 120, 122, 123, 125, 127, 128, 130, 132, 134, 135, 137, 139, 141, 143, 144, 146, 148, 150, 152, 154, 156, 158, 160, 163, 165, 167, 169, 171, 173, 175, 178, 180, 182, 185, 187, 189, 192, 194, 197, 199, 201, 204, 206, 209, 211, 214, 216, 219, 221, 224, 226, 229, 232, 234, 236, 239, 241, 245, 247, 250, 252, 255 }; for (int j = 0; j < 256; j++){ arrayOfByte[(1024 + j * 4)] = ((byte)arrayOfInt5[j]); arrayOfByte[(1 + (1024 + j * 4))] = ((byte)arrayOfInt6[j]); arrayOfByte[(2 + (1024 + j * 4))] = ((byte)arrayOfInt7[j]); arrayOfByte[(3 + (1024 + j * 4))] = ((byte)arrayOfInt8[j]); } GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, 256, 2, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, ByteBuffer.wrap(arrayOfByte)); mMaskGrey1TextureId = OpenGlUtils.loadTexture(MagicParams.context, "filter/warm_layer1.jpg"); mMaskGrey2TextureId = OpenGlUtils.loadTexture(MagicParams.context, "filter/bluevintage_mask1.jpg"); } }); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/advanced/MagicWhiteCatFilter.java ================================================ package com.zero.magicshow.core.filter.advanced; import android.opengl.GLES20; import com.zero.magicshow.R; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.common.utils.OpenGlUtils; import java.nio.ByteBuffer; public class MagicWhiteCatFilter extends GPUImageFilter{ private int[] mToneCurveTexture = {-1}; private int mToneCurveTextureUniformLocation; public MagicWhiteCatFilter(){ super(NO_FILTER_VERTEX_SHADER, OpenGlUtils.readShaderFromRawResource(R.raw.whitecat)); } public void onDestroy(){ super.onDestroy(); GLES20.glDeleteTextures(1, mToneCurveTexture, 0); mToneCurveTexture[0] = -1; } protected void onDrawArraysAfter(){ if (mToneCurveTexture[0] != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE3); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } } protected void onDrawArraysPre(){ if (mToneCurveTexture[0] != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE3); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mToneCurveTexture[0]); GLES20.glUniform1i(mToneCurveTextureUniformLocation, 3); } } public void onInit(){ super.onInit(); mToneCurveTextureUniformLocation = GLES20.glGetUniformLocation(mGLProgId, "curve"); } public void onInitialized(){ super.onInitialized(); runOnDraw(new Runnable(){ public void run(){ GLES20.glGenTextures(1, mToneCurveTexture, 0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mToneCurveTexture[0]); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); byte[] arrayOfByte = new byte[2048]; int[] arrayOfInt1 = { 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 16, 17, 18, 19, 20, 22, 23, 24, 25, 26, 28, 29, 30, 31, 32, 33, 35, 36, 37, 38, 39, 41, 42, 43, 44, 45, 46, 48, 49, 50, 51, 52, 54, 55, 56, 57, 58, 59, 61, 62, 63, 64, 65, 66, 67, 69, 70, 71, 72, 73, 74, 75, 77, 78, 79, 80, 81, 82, 83, 85, 86, 87, 88, 89, 90, 91, 92, 93, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 249, 250, 251, 252, 253, 254, 255, 255, 255, 255, 255, 255 }; int[] arrayOfInt2 = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 4, 5, 6, 7, 8, 10, 11, 12, 12, 13, 14, 16, 17, 18, 19, 19, 20, 22, 23, 24, 25, 26, 26, 28, 29, 30, 31, 32, 33, 35, 35, 36, 37, 38, 39, 41, 42, 42, 43, 44, 45, 46, 48, 49, 50, 50, 51, 52, 54, 55, 56, 57, 58, 58, 59, 61, 62, 63, 64, 65, 66, 66, 67, 69, 70, 71, 72, 73, 74, 75, 75, 77, 78, 79, 80, 81, 82, 83, 85, 85, 86, 87, 88, 89, 90, 91, 92, 93, 93, 95, 96, 97, 98, 99, 100, 101, 102, 103, 103, 104, 105, 107, 108, 109, 110, 111, 112, 113, 114, 114, 115, 116, 117, 118, 119, 120, 121, 123, 124, 125, 126, 127, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 182, 183, 184, 185, 186, 187, 188, 189, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 217, 218, 219, 220, 221, 222, 223, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 236, 237, 238, 239, 240, 240 }; for (int i = 0; i < 256; i++){ arrayOfByte[(i * 4)] = ((byte)arrayOfInt1[i]); arrayOfByte[(1 + i * 4)] = ((byte)arrayOfInt1[i]); arrayOfByte[(2 + i * 4)] = ((byte)arrayOfInt2[i]); arrayOfByte[(3 + i * 4)] = -1; } int[] arrayOfInt3 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6, 9, 14, 17, 19, 22, 25, 27, 30, 34, 36, 39, 41, 43, 45, 49, 51, 52, 54, 55, 57, 58, 61, 63, 64, 65, 67, 68, 69, 72, 73, 75, 76, 77, 78, 81, 82, 83, 84, 86, 87, 88, 90, 91, 93, 94, 95, 96, 97, 99, 100, 101, 102, 103, 105, 106, 108, 109, 110, 111, 112, 113, 115, 116, 117, 118, 119, 120, 121, 123, 124, 125, 126, 126, 127, 128, 130, 131, 132, 133, 134, 135, 136, 138, 138, 139, 140, 141, 142, 144, 145, 146, 146, 147, 148, 149, 151, 152, 153, 153, 154, 155, 156, 158, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 168, 170, 171, 172, 172, 173, 174, 175, 176, 177, 178, 179, 180, 180, 181, 183, 183, 184, 185, 186, 186, 188, 189, 190, 190, 191, 192, 193, 194, 195, 196, 196, 197, 198, 199, 200, 201, 201, 202, 203, 204, 204, 206, 207, 207, 208, 209, 209, 211, 212, 212, 213, 214, 214, 215, 217, 217, 218, 219, 219, 220, 221, 222, 223, 224, 224, 225, 226, 227, 228, 228, 229, 230, 230, 231, 233, 233, 234, 235, 235, 236, 237, 238, 239, 239, 240, 241, 241, 242, 243, 244, 245, 245, 246, 247, 248, 249, 249, 250, 250, 251, 252, 253, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }; int[] arrayOfInt4 = { 0, 2, 4, 6, 8, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 32, 34, 36, 38, 40, 42, 44, 46, 47, 49, 51, 53, 54, 56, 58, 60, 61, 63, 65, 66, 68, 70, 71, 73, 74, 76, 77, 79, 80, 82, 83, 85, 86, 88, 89, 91, 92, 93, 95, 96, 98, 99, 100, 101, 103, 104, 105, 107, 108, 109, 110, 111, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 124, 125, 126, 127, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 198, 199, 200, 201, 202, 203, 204, 205, 206, 206, 207, 208, 209, 210, 211, 212, 212, 213, 214, 215, 216, 216, 217, 218, 219, 219, 220, 221, 222, 222, 223, 224, 224, 225, 226, 226, 227, 228, 228, 229, 230, 230, 231, 232, 232, 233, 233, 234, 235, 235, 236, 236, 237, 237, 238, 238, 239, 239, 240, 240, 241, 241, 242, 242, 243, 243, 244, 244, 245, 245, 245, 246, 246, 247, 247, 247, 248, 248, 248, 249, 249, 249, 250, 250, 250, 251, 251, 251, 252, 252, 252, 252, 253, 253, 253, 253, 254, 254, 254, 254, 254, 255, 255, 255 }; int[] arrayOfInt5 = { 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 8, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 20, 20, 20, 21, 21, 21, 22, 22, 23, 23, 23, 24, 24, 24, 25, 25, 25, 25, 26, 26, 27, 27, 28, 28, 28, 28, 29, 29, 30, 29, 31, 31, 31, 31, 32, 32, 33, 33, 34, 34, 34, 34, 35, 35, 36, 36, 37, 37, 37, 38, 38, 39, 39, 39, 40, 40, 40, 41, 42, 42, 43, 43, 44, 44, 45, 45, 45, 46, 47, 47, 48, 48, 49, 50, 51, 51, 52, 52, 53, 53, 54, 55, 55, 56, 57, 57, 58, 59, 60, 60, 61, 62, 63, 63, 64, 65, 66, 67, 68, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 88, 89, 90, 91, 93, 94, 95, 96, 97, 98, 100, 101, 103, 104, 105, 107, 108, 110, 111, 113, 115, 116, 118, 119, 120, 122, 123, 125, 127, 128, 130, 132, 134, 135, 137, 139, 141, 143, 144, 146, 148, 150, 152, 154, 156, 158, 160, 163, 165, 167, 169, 171, 173, 175, 178, 180, 182, 185, 187, 189, 192, 194, 197, 199, 201, 204, 206, 209, 211, 214, 216, 219, 221, 224, 226, 229, 232, 234, 236, 239, 241, 245, 247, 250, 252, 255 }; for (int j = 0; j < 256; j++){ arrayOfByte[(1024 + j * 4)] = ((byte)arrayOfInt4[j]); arrayOfByte[(1 + (1024 + j * 4))] = ((byte)arrayOfInt3[j]); arrayOfByte[(2 + (1024 + j * 4))] = ((byte)arrayOfInt5[j]); arrayOfByte[(3 + (1024 + j * 4))] = -1; } GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, 256, 2, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, ByteBuffer.wrap(arrayOfByte)); } }); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/advanced/MagicXproIIFilter.java ================================================ package com.zero.magicshow.core.filter.advanced; import android.opengl.GLES20; import com.zero.magicshow.R; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.common.utils.MagicParams; import com.zero.magicshow.common.utils.OpenGlUtils; public class MagicXproIIFilter extends GPUImageFilter{ private int[] inputTextureHandles = {-1,-1}; private int[] inputTextureUniformLocations = {-1,-1}; private int mGLStrengthLocation; public MagicXproIIFilter(){ super(NO_FILTER_VERTEX_SHADER, OpenGlUtils.readShaderFromRawResource(R.raw.xproii_filter_shader)); } public void onDestroy() { super.onDestroy(); GLES20.glDeleteTextures(inputTextureHandles.length, inputTextureHandles, 0); for(int i = 0; i < inputTextureHandles.length; i++) inputTextureHandles[i] = -1; } protected void onDrawArraysAfter(){ for(int i = 0; i < inputTextureHandles.length && inputTextureHandles[i] != OpenGlUtils.NO_TEXTURE; i++){ GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + (i+3)); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } } protected void onDrawArraysPre(){ for(int i = 0; i < inputTextureHandles.length && inputTextureHandles[i] != OpenGlUtils.NO_TEXTURE; i++){ GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + (i+3) ); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, inputTextureHandles[i]); GLES20.glUniform1i(inputTextureUniformLocations[i], (i + 3)); } } public void onInit(){ super.onInit(); for(int i = 0; i < inputTextureUniformLocations.length; i++) inputTextureUniformLocations[i] = GLES20.glGetUniformLocation(getProgram(), "inputImageTexture"+(2+i)); mGLStrengthLocation = GLES20.glGetUniformLocation(mGLProgId, "strength"); } public void onInitialized(){ super.onInitialized(); setFloat(mGLStrengthLocation, 1.0f); runOnDraw(new Runnable(){ public void run(){ inputTextureHandles[0] = OpenGlUtils.loadTexture(MagicParams.context, "filter/xpromap.png"); inputTextureHandles[1] = OpenGlUtils.loadTexture(MagicParams.context, "filter/vignettemap_new.png"); } }); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/base/MagicBaseGroupFilter.java ================================================ package com.zero.magicshow.core.filter.base; import android.graphics.Bitmap; import android.opengl.GLES20; import com.zero.magicshow.common.utils.OpenGlUtils; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import java.nio.FloatBuffer; import java.nio.IntBuffer; import java.util.List; public class MagicBaseGroupFilter extends GPUImageFilter{ protected static int[] frameBuffers = null; protected static int[] frameBufferTextures = null; private int frameWidth = -1; private int frameHeight = -1; protected List filters; public MagicBaseGroupFilter(List filters){ this.filters = filters; } @Override public void onDestroy() { for (GPUImageFilter filter : filters) { filter.destroy(); } destroyFramebuffers(); } @Override public void init() { for (GPUImageFilter filter : filters) { filter.init(); } } @Override public void onInputSizeChanged(final int width, final int height) { super.onInputSizeChanged(width, height); int size = filters.size(); for (int i = 0; i < size; i++) { filters.get(i).onInputSizeChanged(width, height); } if(frameBuffers != null && (frameWidth != width || frameHeight != height || frameBuffers.length != size-1)){ destroyFramebuffers(); frameWidth = width; frameHeight = height; } if (frameBuffers == null) { frameBuffers = new int[size]; frameBufferTextures = new int[size]; for (int i = 0; i < size; i++) { GLES20.glGenFramebuffers(1, frameBuffers, i); GLES20.glGenTextures(1, frameBufferTextures, i); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, frameBufferTextures[i]); GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, width, height, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null); //设置放大过滤为使用纹理中坐标最接近的若干个颜色,通过加权平均算法得到需要绘制的像素颜色 GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); //设置缩小过滤为使用纹理中坐标最接近的一个像素的颜色作为需要绘制的像素颜色 GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); //设置环绕方向S,截取纹理坐标到[1/2n,1-1/2n]。将导致永远不会与border融合 GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); //设置环绕方向T,截取纹理坐标到[1/2n,1-1/2n]。将导致永远不会与border融合 GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, frameBuffers[i]); GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, frameBufferTextures[i], 0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); } } } // public void onDisplaySizeChanged(final int width, final int height) { // super.onDisplaySizeChanged(width, height); // int size = filters.size(); // for (int i = 0; i < size; i++) { // filters.get(i).onDisplaySizeChanged(width, height); // } // } @Override public int onDrawFrame(final int textureId, final FloatBuffer cubeBuffer, final FloatBuffer textureBuffer) { if (frameBuffers == null || frameBufferTextures == null) { return OpenGlUtils.NOT_INIT; } int size = filters.size(); int previousTexture = textureId; for (int i = 0; i < size; i++) { GPUImageFilter filter = filters.get(i); boolean isNotLast = i < size - 1; if (isNotLast) { GLES20.glViewport(0, 0, mIntputWidth, mIntputHeight); GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, frameBuffers[i]); GLES20.glClearColor(0, 0, 0, 0); filter.onDrawFrame(previousTexture, mGLCubeBuffer, mGLTextureBuffer); GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); previousTexture = frameBufferTextures[i]; }else{ GLES20.glViewport(0, 0, mOutputWidth, mOutputHeight); filter.onDrawFrame(previousTexture, cubeBuffer, textureBuffer); } } return OpenGlUtils.ON_DRAWN; } @Override public int onDrawFrame(final int textureId) { // return onDrawFrame(textureId,mGLCubeBuffer,mGLTextureBuffer); if (frameBuffers == null || frameBufferTextures == null) { return OpenGlUtils.NOT_INIT; } int size = filters.size(); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); // Log.e("HongLi","filters size:" + size + "mOutputWidth:" + mOutputWidth + ";mOutputHeight:" + mOutputHeight + ";mIntputWidth:" + mIntputWidth + ";mIntputHeight:" + mIntputHeight); int previousTexture = textureId; GLES20.glViewport(0,0,mOutputWidth,mOutputHeight); for (int i = 0; i < size; i++) { GPUImageFilter filter = filters.get(i); boolean isNotLast = i < size - 1; if (isNotLast) { //绑定FrameBuffer GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, frameBuffers[i]); //为FrameBuffer挂载Texture[1]来存储颜色 GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, frameBufferTextures[i], 0); //绑定FrameBuffer后的绘制会绘制到frameBufferTextures[i]上了 filter.onDrawFrame(previousTexture, mGLCubeBuffer, mGLTextureBuffer); //解除绑定位置很重要,如果下面没有纹理绘制了不能解除,否则获取纹理会出问题 GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); previousTexture = frameBufferTextures[i]; }else{ GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, frameBuffers[i]); //为FrameBuffer挂载Texture[1]来存储颜色 GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, frameBufferTextures[i], 0); filter.onDrawFrame(previousTexture, mGLCubeBuffer, mGLTextureBuffer); } } //费时费力,每次都获取bitmap // GLES20.glDeleteTextures(frameBufferTextures.length, frameBufferTextures, 0); // GLES20.glDeleteFramebuffers(frameBuffers.length, frameBuffers, 0); // int nextTextureId = textureId; // IntBuffer ib = IntBuffer.allocate(mOutputWidth * mOutputHeight); // Bitmap mBitmap = Bitmap.createBitmap(mOutputWidth, mOutputHeight, Bitmap.Config.ARGB_8888); // for(GPUImageFilter imageFilter:filters){ // if(!imageFilter.hasChange()){ // continue; // } // imageFilter.onDrawFrame(nextTextureId,mGLCubeBuffer, mGLTextureBuffer); // GLES20.glReadPixels(0, 0, mOutputWidth, mOutputHeight, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, ib); // mBitmap.copyPixelsFromBuffer(IntBuffer.wrap(ib.array())); // nextTextureId = OpenGlUtils.loadTexture(mBitmap, OpenGlUtils.NO_TEXTURE, false); // } // mBitmap.recycle(); return OpenGlUtils.ON_DRAWN; } public void onDrawFrameNormal(final int textureId,int width,int height){ int nextTextureId = textureId; IntBuffer ib = IntBuffer.allocate(width * height); Bitmap mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); for(GPUImageFilter imageFilter:filters){ imageFilter.onDrawFrame(nextTextureId,mGLCubeBuffer, mGLTextureBuffer); GLES20.glReadPixels(0, 0, width, height, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, ib); mBitmap.copyPixelsFromBuffer(IntBuffer.wrap(ib.array())); nextTextureId = OpenGlUtils.loadTexture(mBitmap, OpenGlUtils.NO_TEXTURE, false); } mBitmap.recycle(); } private void destroyFramebuffers() { if (frameBufferTextures != null) { GLES20.glDeleteTextures(frameBufferTextures.length, frameBufferTextures, 0); frameBufferTextures = null; } if (frameBuffers != null) { GLES20.glDeleteFramebuffers(frameBuffers.length, frameBuffers, 0); frameBuffers = null; } } public int getSize(){ return filters.size(); } public GPUImageFilter getFristFilter(){ return filters.get(0); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/base/MagicCameraInputFilter.java ================================================ package com.zero.magicshow.core.filter.base; import android.opengl.GLES11Ext; import android.opengl.GLES20; import com.zero.magicshow.R; import com.zero.magicshow.common.utils.MagicParams; import com.zero.magicshow.common.utils.OpenGlUtils; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import java.nio.FloatBuffer; public class MagicCameraInputFilter extends GPUImageFilter{ private float[] mTextureTransformMatrix; private int mTextureTransformMatrixLocation; private int mSingleStepOffsetLocation; private int mParamsLocation; private int[] mFrameBuffers = null; private int[] mFrameBufferTextures = null; private int mFrameWidth = -1; private int mFrameHeight = -1; public MagicCameraInputFilter(){ super(OpenGlUtils.readShaderFromRawResource(R.raw.default_vertex) , OpenGlUtils.readShaderFromRawResource(R.raw.default_fragment)); } protected void onInit() { super.onInit(); mTextureTransformMatrixLocation = GLES20.glGetUniformLocation(mGLProgId, "textureTransform"); mSingleStepOffsetLocation = GLES20.glGetUniformLocation(getProgram(), "singleStepOffset"); mParamsLocation = GLES20.glGetUniformLocation(getProgram(), "params"); setBeautyLevel(MagicParams.beautyLevel); } public void setTextureTransformMatrix(float[] mtx){ mTextureTransformMatrix = mtx; } @Override public int onDrawFrame(int textureId) { GLES20.glUseProgram(mGLProgId); runPendingOnDrawTasks(); if(!isInitialized()) { return OpenGlUtils.NOT_INIT; } mGLCubeBuffer.position(0); GLES20.glVertexAttribPointer(mGLAttribPosition, 2, GLES20.GL_FLOAT, false, 0, mGLCubeBuffer); GLES20.glEnableVertexAttribArray(mGLAttribPosition); mGLTextureBuffer.position(0); GLES20.glVertexAttribPointer(mGLAttribTextureCoordinate, 2, GLES20.GL_FLOAT, false, 0, mGLTextureBuffer); GLES20.glEnableVertexAttribArray(mGLAttribTextureCoordinate); GLES20.glUniformMatrix4fv(mTextureTransformMatrixLocation, 1, false, mTextureTransformMatrix, 0); if(textureId != OpenGlUtils.NO_TEXTURE){ GLES20.glActiveTexture(GLES20.GL_TEXTURE0); GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textureId); GLES20.glUniform1i(mGLUniformTexture, 0); } GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); GLES20.glDisableVertexAttribArray(mGLAttribPosition); GLES20.glDisableVertexAttribArray(mGLAttribTextureCoordinate); GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, 0); return OpenGlUtils.ON_DRAWN; } @Override public int onDrawFrame(int textureId, FloatBuffer vertexBuffer, FloatBuffer textureBuffer) { GLES20.glUseProgram(mGLProgId); runPendingOnDrawTasks(); if(!isInitialized()) { return OpenGlUtils.NOT_INIT; } vertexBuffer.position(0); GLES20.glVertexAttribPointer(mGLAttribPosition, 2, GLES20.GL_FLOAT, false, 0, vertexBuffer); GLES20.glEnableVertexAttribArray(mGLAttribPosition); textureBuffer.position(0); GLES20.glVertexAttribPointer(mGLAttribTextureCoordinate, 2, GLES20.GL_FLOAT, false, 0, textureBuffer); GLES20.glEnableVertexAttribArray(mGLAttribTextureCoordinate); GLES20.glUniformMatrix4fv(mTextureTransformMatrixLocation, 1, false, mTextureTransformMatrix, 0); if(textureId != OpenGlUtils.NO_TEXTURE){ GLES20.glActiveTexture(GLES20.GL_TEXTURE0); GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textureId); GLES20.glUniform1i(mGLUniformTexture, 0); } GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); GLES20.glDisableVertexAttribArray(mGLAttribPosition); GLES20.glDisableVertexAttribArray(mGLAttribTextureCoordinate); GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, 0); return OpenGlUtils.ON_DRAWN; } public int onDrawToTexture(final int textureId) { if(mFrameBuffers == null) return OpenGlUtils.NO_TEXTURE; runPendingOnDrawTasks(); GLES20.glViewport(0, 0, mFrameWidth, mFrameHeight); GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, mFrameBuffers[0]); GLES20.glUseProgram(mGLProgId); if(!isInitialized()) { return OpenGlUtils.NOT_INIT; } mGLCubeBuffer.position(0); GLES20.glVertexAttribPointer(mGLAttribPosition, 2, GLES20.GL_FLOAT, false, 0, mGLCubeBuffer); GLES20.glEnableVertexAttribArray(mGLAttribPosition); mGLTextureBuffer.position(0); GLES20.glVertexAttribPointer(mGLAttribTextureCoordinate, 2, GLES20.GL_FLOAT, false, 0, mGLTextureBuffer); GLES20.glEnableVertexAttribArray(mGLAttribTextureCoordinate); GLES20.glUniformMatrix4fv(mTextureTransformMatrixLocation, 1, false, mTextureTransformMatrix, 0); if(textureId != OpenGlUtils.NO_TEXTURE){ GLES20.glActiveTexture(GLES20.GL_TEXTURE0); GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textureId); GLES20.glUniform1i(mGLUniformTexture, 0); } GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); GLES20.glDisableVertexAttribArray(mGLAttribPosition); GLES20.glDisableVertexAttribArray(mGLAttribTextureCoordinate); GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, 0); GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); GLES20.glViewport(0, 0, mOutputWidth, mOutputHeight); return mFrameBufferTextures[0]; } public void initCameraFrameBuffer(int width, int height) { if(mFrameBuffers != null && (mFrameWidth != width || mFrameHeight != height)) destroyFramebuffers(); if (mFrameBuffers == null) { mFrameWidth = width; mFrameHeight = height; mFrameBuffers = new int[1]; mFrameBufferTextures = new int[1]; GLES20.glGenFramebuffers(1, mFrameBuffers, 0); GLES20.glGenTextures(1, mFrameBufferTextures, 0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mFrameBufferTextures[0]); GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, width, height, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, mFrameBuffers[0]); GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, mFrameBufferTextures[0], 0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); } } public void destroyFramebuffers() { if (mFrameBufferTextures != null) { GLES20.glDeleteTextures(1, mFrameBufferTextures, 0); mFrameBufferTextures = null; } if (mFrameBuffers != null) { GLES20.glDeleteFramebuffers(1, mFrameBuffers, 0); mFrameBuffers = null; } mFrameWidth = -1; mFrameHeight = -1; } private void setTexelSize(final float w, final float h) { setFloatVec2(mSingleStepOffsetLocation, new float[] {2.0f / w, 2.0f / h}); } @Override public void onInputSizeChanged(final int width, final int height) { super.onInputSizeChanged(width, height); setTexelSize(width, height); } public void setBeautyLevel(int level){ switch (level) { case 0: setFloat(mParamsLocation, 0.0f); break; case 1: setFloat(mParamsLocation, 1.0f); break; case 2: setFloat(mParamsLocation, 0.8f); break; case 3: setFloat(mParamsLocation,0.6f); break; case 4: setFloat(mParamsLocation, 0.4f); break; case 5: setFloat(mParamsLocation,0.33f); break; default: break; } } @Override protected void onDestroy() { super.onDestroy(); destroyFramebuffers(); } public void onBeautyLevelChanged(){ setBeautyLevel(MagicParams.beautyLevel); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/base/MagicLookupFilter.java ================================================ package com.zero.magicshow.core.filter.base; import android.opengl.GLES20; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.common.utils.MagicParams; import com.zero.magicshow.common.utils.OpenGlUtils; public class MagicLookupFilter extends GPUImageFilter { public static final String LOOKUP_FRAGMENT_SHADER = ""+ "varying highp vec2 textureCoordinate;\n" + " \n" + " uniform sampler2D inputImageTexture;\n" + " uniform sampler2D inputImageTexture2; // lookup texture\n" + " \n" + " void main()\n" + " {\n" + " lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n" + " \n" + " mediump float blueColor = textureColor.b * 63.0;\n" + " \n" + " mediump vec2 quad1;\n" + " quad1.y = floor(floor(blueColor) / 8.0);\n" + " quad1.x = floor(blueColor) - (quad1.y * 8.0);\n" + " \n" + " mediump vec2 quad2;\n" + " quad2.y = floor(ceil(blueColor) / 8.0);\n" + " quad2.x = ceil(blueColor) - (quad2.y * 8.0);\n" + " \n" + " highp vec2 texPos1;\n" + " texPos1.x = (quad1.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.r);\n" + " texPos1.y = (quad1.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.g);\n" + " \n" + " highp vec2 texPos2;\n" + " texPos2.x = (quad2.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.r);\n" + " texPos2.y = (quad2.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.g);\n" + " \n" + " lowp vec4 newColor1 = texture2D(inputImageTexture2, texPos1);\n" + " lowp vec4 newColor2 = texture2D(inputImageTexture2, texPos2);\n" + " \n" + " lowp vec4 newColor = mix(newColor1, newColor2, fract(blueColor));\n" + " gl_FragColor = vec4(newColor.rgb, textureColor.w);\n" + " }"; protected String table; public MagicLookupFilter(String table) { super(NO_FILTER_VERTEX_SHADER,LOOKUP_FRAGMENT_SHADER); this.table = table; } public int mLookupTextureUniform; public int mLookupSourceTexture = OpenGlUtils.NO_TEXTURE; protected void onInit(){ super.onInit(); mLookupTextureUniform = GLES20.glGetUniformLocation(getProgram(), "inputImageTexture2"); } protected void onInitialized(){ super.onInitialized(); runOnDraw(new Runnable(){ public void run(){ mLookupSourceTexture = OpenGlUtils.loadTexture(MagicParams.context, table); } }); } protected void onDestroy(){ super.onDestroy(); int[] texture = new int[]{mLookupSourceTexture}; GLES20.glDeleteTextures(1, texture, 0); mLookupSourceTexture = -1; } protected void onDrawArraysAfter(){ if (mLookupSourceTexture != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE3); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); } } protected void onDrawArraysPre(){ if (mLookupSourceTexture != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE3); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mLookupSourceTexture); GLES20.glUniform1i(mLookupTextureUniform, 3); } } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/base/gpuimage/GPUImageBrightnessFilter.java ================================================ /* * Copyright (C) 2012 CyberAgent * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.zero.magicshow.core.filter.base.gpuimage; import android.opengl.GLES20; /** * brightness value ranges from -1.0 to 1.0, with 0.0 as the normal level */ public class GPUImageBrightnessFilter extends GPUImageFilter { public static final String BRIGHTNESS_FRAGMENT_SHADER = "" + "varying highp vec2 textureCoordinate;\n" + " \n" + " uniform sampler2D inputImageTexture;\n" + " uniform lowp float brightness;\n" + " \n" + " void main()\n" + " {\n" + " lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n" + " \n" + " gl_FragColor = vec4((textureColor.rgb + vec3(brightness)), textureColor.w);\n" + " }"; private int mBrightnessLocation; private float mBrightness; public GPUImageBrightnessFilter() { this(0.0f); } public boolean hasChange(){ return mBrightness != 0.0; } public GPUImageBrightnessFilter(final float brightness) { super(NO_FILTER_VERTEX_SHADER, BRIGHTNESS_FRAGMENT_SHADER); mBrightness = brightness; } @Override public void onInit() { super.onInit(); mBrightnessLocation = GLES20.glGetUniformLocation(getProgram(), "brightness"); } @Override public void onInitialized() { super.onInitialized(); setBrightness(mBrightness); } public void setBrightness(final float brightness) { mBrightness = brightness; setFloat(mBrightnessLocation, mBrightness); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/base/gpuimage/GPUImageContrastFilter.java ================================================ /* * Copyright (C) 2012 CyberAgent * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.zero.magicshow.core.filter.base.gpuimage; import android.opengl.GLES20; /** * Changes the contrast of the image.
*
* contrast value ranges from 0.0 to 4.0, with 1.0 as the normal level */ public class GPUImageContrastFilter extends GPUImageFilter { public static final String CONTRAST_FRAGMENT_SHADER = "" + "varying highp vec2 textureCoordinate;\n" + " \n" + " uniform sampler2D inputImageTexture;\n" + " uniform lowp float contrast;\n" + " \n" + " void main()\n" + " {\n" + " lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n" + " \n" + " gl_FragColor = vec4(((textureColor.rgb - vec3(0.5)) * contrast + vec3(0.5)), textureColor.w);\n" + " }"; private int mContrastLocation; private float mContrast; public GPUImageContrastFilter() { this(1.0f); } public GPUImageContrastFilter(float contrast) { super(NO_FILTER_VERTEX_SHADER, CONTRAST_FRAGMENT_SHADER); mContrast = contrast; } @Override public void onInit() { super.onInit(); mContrastLocation = GLES20.glGetUniformLocation(getProgram(), "contrast"); } @Override public void onInitialized() { super.onInitialized(); setContrast(mContrast); } public void setContrast(final float contrast) { mContrast = contrast; setFloat(mContrastLocation, mContrast); } public boolean hasChange(){ return mContrast != 1.0; } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/base/gpuimage/GPUImageExposureFilter.java ================================================ /* * Copyright (C) 2012 CyberAgent * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.zero.magicshow.core.filter.base.gpuimage; import android.opengl.GLES20; /** * exposure: The adjusted exposure (-10.0 - 10.0, with 0.0 as the default) */ public class GPUImageExposureFilter extends GPUImageFilter { public static final String EXPOSURE_FRAGMENT_SHADER = "" + " varying highp vec2 textureCoordinate;\n" + " \n" + " uniform sampler2D inputImageTexture;\n" + " uniform highp float exposure;\n" + " \n" + " void main()\n" + " {\n" + " highp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n" + " \n" + " gl_FragColor = vec4(textureColor.rgb * pow(2.0, exposure), textureColor.w);\n" + " } "; private int mExposureLocation; private float mExposure; public GPUImageExposureFilter() { this(0.0f); } public boolean hasChange(){ return mExposure != 0.0; } public GPUImageExposureFilter(final float exposure) { super(NO_FILTER_VERTEX_SHADER, EXPOSURE_FRAGMENT_SHADER); mExposure = exposure; } @Override public void onInit() { super.onInit(); mExposureLocation = GLES20.glGetUniformLocation(getProgram(), "exposure"); } @Override public void onInitialized() { super.onInitialized(); setExposure(mExposure); } public void setExposure(final float exposure) { mExposure = exposure; setFloat(mExposureLocation, mExposure); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/base/gpuimage/GPUImageFilter.java ================================================ /* * Copyright (C) 2012 CyberAgent * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.zero.magicshow.core.filter.base.gpuimage; import android.graphics.PointF; import android.opengl.GLES20; import com.zero.magicshow.common.utils.OpenGlUtils; import com.zero.magicshow.common.utils.Rotation; import com.zero.magicshow.common.utils.TextureRotationUtil; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import java.util.LinkedList; public class GPUImageFilter { public static final String NO_FILTER_VERTEX_SHADER = "" + "attribute vec4 position;\n" + "attribute vec4 inputTextureCoordinate;\n" + " \n" + "varying vec2 textureCoordinate;\n" + " \n" + "void main()\n" + "{\n" + " gl_Position = position;\n" + " textureCoordinate = inputTextureCoordinate.xy;\n" + "}"; public static final String NO_FILTER_FRAGMENT_SHADER = "" + "varying highp vec2 textureCoordinate;\n" + " \n" + "uniform sampler2D inputImageTexture;\n" + " \n" + "void main()\n" + "{\n" + " gl_FragColor = texture2D(inputImageTexture, textureCoordinate);\n" + "}"; private final LinkedList mRunOnDraw; private final String mVertexShader; private final String mFragmentShader; protected int mGLProgId; protected int mGLAttribPosition; protected int mGLUniformTexture; protected int mGLAttribTextureCoordinate; protected int mGLStrengthLocation; protected int mIntputWidth; protected int mIntputHeight; protected boolean mIsInitialized; protected FloatBuffer mGLCubeBuffer; protected FloatBuffer mGLTextureBuffer; protected int mOutputWidth, mOutputHeight; public GPUImageFilter() { this(NO_FILTER_VERTEX_SHADER, NO_FILTER_FRAGMENT_SHADER); } public GPUImageFilter(final String vertexShader, final String fragmentShader) { mRunOnDraw = new LinkedList<>(); mVertexShader = vertexShader; mFragmentShader = fragmentShader; mGLCubeBuffer = ByteBuffer.allocateDirect(TextureRotationUtil.CUBE.length * 4) .order(ByteOrder.nativeOrder()) .asFloatBuffer(); mGLCubeBuffer.put(TextureRotationUtil.CUBE).position(0); mGLTextureBuffer = ByteBuffer.allocateDirect(TextureRotationUtil.TEXTURE_NO_ROTATION.length * 4) .order(ByteOrder.nativeOrder()) .asFloatBuffer(); mGLTextureBuffer.put(TextureRotationUtil.getRotation(Rotation.NORMAL, false, true)).position(0); } public void init() { onInit(); mIsInitialized = true; onInitialized(); } public boolean hasChange(){ return true; } protected void onInit() { mGLProgId = OpenGlUtils.loadProgram(mVertexShader, mFragmentShader); mGLAttribPosition = GLES20.glGetAttribLocation(mGLProgId, "position"); mGLUniformTexture = GLES20.glGetUniformLocation(mGLProgId, "inputImageTexture"); mGLAttribTextureCoordinate = GLES20.glGetAttribLocation(mGLProgId, "inputTextureCoordinate"); mGLStrengthLocation = GLES20.glGetUniformLocation(mGLProgId, "strength"); mIsInitialized = true; } protected void onInitialized() { setFloat(mGLStrengthLocation, 1.0f); } public final void destroy() { mIsInitialized = false; GLES20.glDeleteProgram(mGLProgId); onDestroy(); } protected void onDestroy() { } public void onInputSizeChanged(final int width, final int height) { mIntputWidth = width; mIntputHeight = height; // Log.e("HongLi","in small onInputSizeChanged mIntputWidth:" + mIntputWidth + ";mIntputHeight:" + mIntputHeight + ";mOutputWidth:" + mOutputWidth + ";mOutputHeight:" + mOutputHeight); // mIntputWidth = 1024; // mIntputHeight = 1574; // mOutputWidth = 1024; // mOutputHeight = 1574; } public void onOutputSizeChanged(final int width, final int height){ mOutputWidth = width; mOutputHeight = height; } public void onDrawFrameNormal(final int textureId,int width,int height){} public int onDrawFrame(final int textureId, final FloatBuffer cubeBuffer, final FloatBuffer textureBuffer) { GLES20.glUseProgram(mGLProgId); runPendingOnDrawTasks(); if (!mIsInitialized) { return OpenGlUtils.NOT_INIT; } cubeBuffer.position(0); GLES20.glVertexAttribPointer(mGLAttribPosition, 2, GLES20.GL_FLOAT, false, 0, cubeBuffer); GLES20.glEnableVertexAttribArray(mGLAttribPosition); textureBuffer.position(0); GLES20.glVertexAttribPointer(mGLAttribTextureCoordinate, 2, GLES20.GL_FLOAT, false, 0, textureBuffer); GLES20.glEnableVertexAttribArray(mGLAttribTextureCoordinate); if (textureId != OpenGlUtils.NO_TEXTURE) { //激活纹理单元1 GLES20.glActiveTexture(GLES20.GL_TEXTURE0); //绑定2D纹理 GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId); //将纹理设置给Shader GLES20.glUniform1i(mGLUniformTexture, 0); } onDrawArraysPre(); GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); GLES20.glDisableVertexAttribArray(mGLAttribPosition); GLES20.glDisableVertexAttribArray(mGLAttribTextureCoordinate); onDrawArraysAfter(); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); return OpenGlUtils.ON_DRAWN; } public int onDrawFrame(final int textureId) { GLES20.glUseProgram(mGLProgId); runPendingOnDrawTasks(); if (!mIsInitialized) return OpenGlUtils.NOT_INIT; mGLCubeBuffer.position(0); GLES20.glVertexAttribPointer(mGLAttribPosition, 2, GLES20.GL_FLOAT, false, 0, mGLCubeBuffer); GLES20.glEnableVertexAttribArray(mGLAttribPosition); mGLTextureBuffer.position(0); GLES20.glVertexAttribPointer(mGLAttribTextureCoordinate, 2, GLES20.GL_FLOAT, false, 0, mGLTextureBuffer); GLES20.glEnableVertexAttribArray(mGLAttribTextureCoordinate); if (textureId != OpenGlUtils.NO_TEXTURE) { GLES20.glActiveTexture(GLES20.GL_TEXTURE0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId); GLES20.glUniform1i(mGLUniformTexture, 0); } onDrawArraysPre(); GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); GLES20.glDisableVertexAttribArray(mGLAttribPosition); GLES20.glDisableVertexAttribArray(mGLAttribTextureCoordinate); onDrawArraysAfter(); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); return OpenGlUtils.ON_DRAWN; } protected void onDrawArraysPre() {} protected void onDrawArraysAfter() {} protected void runPendingOnDrawTasks() { while (!mRunOnDraw.isEmpty()) { mRunOnDraw.removeFirst().run(); } } public boolean isInitialized() { return mIsInitialized; } public int getIntputWidth() { return mIntputWidth; } public int getIntputHeight() { return mIntputHeight; } public int getProgram() { return mGLProgId; } public int getAttribPosition() { return mGLAttribPosition; } public int getAttribTextureCoordinate() { return mGLAttribTextureCoordinate; } public int getUniformTexture() { return mGLUniformTexture; } protected void setInteger(final int location, final int intValue) { runOnDraw(new Runnable() { @Override public void run() { GLES20.glUniform1i(location, intValue); } }); } protected void setFloat(final int location, final float floatValue) { runOnDraw(new Runnable() { @Override public void run() { GLES20.glUniform1f(location, floatValue); } }); } protected void setFloatVec2(final int location, final float[] arrayValue) { runOnDraw(new Runnable() { @Override public void run() { GLES20.glUniform2fv(location, 1, FloatBuffer.wrap(arrayValue)); } }); } protected void setFloatVec3(final int location, final float[] arrayValue) { runOnDraw(new Runnable() { @Override public void run() { GLES20.glUniform3fv(location, 1, FloatBuffer.wrap(arrayValue)); } }); } protected void setFloatVec4(final int location, final float[] arrayValue) { runOnDraw(new Runnable() { @Override public void run() { GLES20.glUniform4fv(location, 1, FloatBuffer.wrap(arrayValue)); } }); } protected void setFloatArray(final int location, final float[] arrayValue) { runOnDraw(new Runnable() { @Override public void run() { GLES20.glUniform1fv(location, arrayValue.length, FloatBuffer.wrap(arrayValue)); } }); } protected void setPoint(final int location, final PointF point) { runOnDraw(new Runnable() { @Override public void run() { float[] vec2 = new float[2]; vec2[0] = point.x; vec2[1] = point.y; GLES20.glUniform2fv(location, 1, vec2, 0); } }); } protected void setUniformMatrix3f(final int location, final float[] matrix) { runOnDraw(new Runnable() { @Override public void run() { GLES20.glUniformMatrix3fv(location, 1, false, matrix, 0); } }); } protected void setUniformMatrix4f(final int location, final float[] matrix) { runOnDraw(new Runnable() { @Override public void run() { GLES20.glUniformMatrix4fv(location, 1, false, matrix, 0); } }); } protected void runOnDraw(final Runnable runnable) { synchronized (mRunOnDraw) { mRunOnDraw.addLast(runnable); } } public void onDisplaySizeChanged(final int width, final int height) { mOutputWidth = width; mOutputHeight = height; } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/base/gpuimage/GPUImageHueFilter.java ================================================ /* * Copyright (C) 2012 CyberAgent * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.zero.magicshow.core.filter.base.gpuimage; import android.opengl.GLES20; public class GPUImageHueFilter extends GPUImageFilter { public static final String HUE_FRAGMENT_SHADER = "" + "precision highp float;\n" + "varying highp vec2 textureCoordinate;\n" + "\n" + "uniform sampler2D inputImageTexture;\n" + "uniform mediump float hueAdjust;\n" + "const highp vec4 kRGBToYPrime = vec4 (0.299, 0.587, 0.114, 0.0);\n" + "const highp vec4 kRGBToI = vec4 (0.595716, -0.274453, -0.321263, 0.0);\n" + "const highp vec4 kRGBToQ = vec4 (0.211456, -0.522591, 0.31135, 0.0);\n" + "\n" + "const highp vec4 kYIQToR = vec4 (1.0, 0.9563, 0.6210, 0.0);\n" + "const highp vec4 kYIQToG = vec4 (1.0, -0.2721, -0.6474, 0.0);\n" + "const highp vec4 kYIQToB = vec4 (1.0, -1.1070, 1.7046, 0.0);\n" + "\n" + "void main ()\n" + "{\n" + " // Sample the input pixel\n" + " highp vec4 color = texture2D(inputImageTexture, textureCoordinate);\n" + "\n" + " // Convert to YIQ\n" + " highp float YPrime = dot (color, kRGBToYPrime);\n" + " highp float I = dot (color, kRGBToI);\n" + " highp float Q = dot (color, kRGBToQ);\n" + "\n" + " // Calculate the hue and chroma\n" + " highp float hue = atan (Q, I);\n" + " highp float chroma = sqrt (I * I + Q * Q);\n" + "\n" + " // Make the user's adjustments\n" + " hue += (-hueAdjust); //why negative rotation?\n" + "\n" + " // Convert back to YIQ\n" + " Q = chroma * sin (hue);\n" + " I = chroma * cos (hue);\n" + "\n" + " // Convert back to RGB\n" + " highp vec4 yIQ = vec4 (YPrime, I, Q, 0.0);\n" + " color.r = dot (yIQ, kYIQToR);\n" + " color.g = dot (yIQ, kYIQToG);\n" + " color.b = dot (yIQ, kYIQToB);\n" + "\n" + " // Save the result\n" + " gl_FragColor = color;\n" + "}\n"; private float mHue; private int mHueLocation; public GPUImageHueFilter() { this(0.0f); } public boolean hasChange(){ return mHue != 0.0; } public GPUImageHueFilter(final float hue) { super(NO_FILTER_VERTEX_SHADER, HUE_FRAGMENT_SHADER); mHue = hue; } @Override public void onInit() { super.onInit(); mHueLocation = GLES20.glGetUniformLocation(getProgram(), "hueAdjust"); } @Override public void onInitialized() { super.onInitialized(); setHue(mHue); } public void setHue(final float hue) { mHue = hue; float hueAdjust = (mHue % 360.0f) * (float) Math.PI / 180.0f; setFloat(mHueLocation, hueAdjust); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/base/gpuimage/GPUImageSaturationFilter.java ================================================ /* * Copyright (C) 2012 CyberAgent * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.zero.magicshow.core.filter.base.gpuimage; import android.opengl.GLES20; /** * saturation: The degree of saturation or desaturation to apply to the image (0.0 - 2.0, with 1.0 as the default) */ public class GPUImageSaturationFilter extends GPUImageFilter { public static final String SATURATION_FRAGMENT_SHADER = "" + " varying highp vec2 textureCoordinate;\n" + " \n" + " uniform sampler2D inputImageTexture;\n" + " uniform lowp float saturation;\n" + " \n" + " // Values from \"Graphics Shaders: Theory and Practice\" by Bailey and Cunningham\n" + " const mediump vec3 luminanceWeighting = vec3(0.2125, 0.7154, 0.0721);\n" + " \n" + " void main()\n" + " {\n" + " lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n" + " lowp float luminance = dot(textureColor.rgb, luminanceWeighting);\n" + " lowp vec3 greyScaleColor = vec3(luminance);\n" + " \n" + " gl_FragColor = vec4(mix(greyScaleColor, textureColor.rgb, saturation), textureColor.w);\n" + " \n" + " }"; private int mSaturationLocation; private float mSaturation; public GPUImageSaturationFilter() { this(1.0f); } public boolean hasChange(){ return mSaturation != 0.0; } public GPUImageSaturationFilter(final float saturation) { super(NO_FILTER_VERTEX_SHADER, SATURATION_FRAGMENT_SHADER); mSaturation = saturation; } @Override public void onInit() { super.onInit(); mSaturationLocation = GLES20.glGetUniformLocation(getProgram(), "saturation"); } @Override public void onInitialized() { super.onInitialized(); setSaturation(mSaturation); } public void setSaturation(final float saturation) { mSaturation = saturation; setFloat(mSaturationLocation, mSaturation); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/base/gpuimage/GPUImageSharpenFilter.java ================================================ /* * Copyright (C) 2012 CyberAgent * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.zero.magicshow.core.filter.base.gpuimage; import android.opengl.GLES20; /** * Sharpens the picture.
*
* sharpness: from -4.0 to 4.0, with 0.0 as the normal level */ public class GPUImageSharpenFilter extends GPUImageFilter { public static final String SHARPEN_VERTEX_SHADER = "" + "attribute vec4 position;\n" + "attribute vec4 inputTextureCoordinate;\n" + "\n" + "uniform float imageWidthFactor; \n" + "uniform float imageHeightFactor; \n" + "uniform float sharpness;\n" + "\n" + "varying vec2 textureCoordinate;\n" + "varying vec2 leftTextureCoordinate;\n" + "varying vec2 rightTextureCoordinate; \n" + "varying vec2 topTextureCoordinate;\n" + "varying vec2 bottomTextureCoordinate;\n" + "\n" + "varying float centerMultiplier;\n" + "varying float edgeMultiplier;\n" + "\n" + "void main()\n" + "{\n" + " gl_Position = position;\n" + " \n" + " mediump vec2 widthStep = vec2(imageWidthFactor, 0.0);\n" + " mediump vec2 heightStep = vec2(0.0, imageHeightFactor);\n" + " \n" + " textureCoordinate = inputTextureCoordinate.xy;\n" + " leftTextureCoordinate = inputTextureCoordinate.xy - widthStep;\n" + " rightTextureCoordinate = inputTextureCoordinate.xy + widthStep;\n" + " topTextureCoordinate = inputTextureCoordinate.xy + heightStep; \n" + " bottomTextureCoordinate = inputTextureCoordinate.xy - heightStep;\n" + " \n" + " centerMultiplier = 1.0 + 4.0 * sharpness;\n" + " edgeMultiplier = sharpness;\n" + "}"; public static final String SHARPEN_FRAGMENT_SHADER = "" + "precision highp float;\n" + "\n" + "varying highp vec2 textureCoordinate;\n" + "varying highp vec2 leftTextureCoordinate;\n" + "varying highp vec2 rightTextureCoordinate; \n" + "varying highp vec2 topTextureCoordinate;\n" + "varying highp vec2 bottomTextureCoordinate;\n" + "\n" + "varying highp float centerMultiplier;\n" + "varying highp float edgeMultiplier;\n" + "\n" + "uniform sampler2D inputImageTexture;\n" + "\n" + "void main()\n" + "{\n" + " mediump vec3 textureColor = texture2D(inputImageTexture, textureCoordinate).rgb;\n" + " mediump vec3 leftTextureColor = texture2D(inputImageTexture, leftTextureCoordinate).rgb;\n" + " mediump vec3 rightTextureColor = texture2D(inputImageTexture, rightTextureCoordinate).rgb;\n" + " mediump vec3 topTextureColor = texture2D(inputImageTexture, topTextureCoordinate).rgb;\n" + " mediump vec3 bottomTextureColor = texture2D(inputImageTexture, bottomTextureCoordinate).rgb;\n" + "\n" + " gl_FragColor = vec4((textureColor * centerMultiplier - (leftTextureColor * edgeMultiplier + rightTextureColor * edgeMultiplier + topTextureColor * edgeMultiplier + bottomTextureColor * edgeMultiplier)), texture2D(inputImageTexture, bottomTextureCoordinate).w);\n" + "}"; private int mSharpnessLocation; private float mSharpness; private int mImageWidthFactorLocation; private int mImageHeightFactorLocation; public GPUImageSharpenFilter() { this(0.0f); } public boolean hasChange(){ return mSharpness != 0.0; } public GPUImageSharpenFilter(final float sharpness) { super(SHARPEN_VERTEX_SHADER, SHARPEN_FRAGMENT_SHADER); mSharpness = sharpness; } @Override public void onInit() { super.onInit(); mSharpnessLocation = GLES20.glGetUniformLocation(getProgram(), "sharpness"); mImageWidthFactorLocation = GLES20.glGetUniformLocation(getProgram(), "imageWidthFactor"); mImageHeightFactorLocation = GLES20.glGetUniformLocation(getProgram(), "imageHeightFactor"); setSharpness(mSharpness); } @Override public void onInputSizeChanged(final int width, final int height) { super.onInputSizeChanged(width, height); setFloat(mImageWidthFactorLocation, 1.0f / width); setFloat(mImageHeightFactorLocation, 1.0f / height); } public void setSharpness(final float sharpness) { mSharpness = sharpness; setFloat(mSharpnessLocation, mSharpness); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/utils/MagicFilterFactory.java ================================================ package com.zero.magicshow.core.filter.utils; import com.zero.magicshow.core.filter.advanced.MagicAmaroFilter; import com.zero.magicshow.core.filter.advanced.MagicAntiqueFilter; import com.zero.magicshow.core.filter.advanced.MagicBlackCatFilter; import com.zero.magicshow.core.filter.advanced.MagicBrannanFilter; import com.zero.magicshow.core.filter.advanced.MagicBrooklynFilter; import com.zero.magicshow.core.filter.advanced.MagicCalmFilter; import com.zero.magicshow.core.filter.advanced.MagicCoolFilter; import com.zero.magicshow.core.filter.advanced.MagicCrayonFilter; import com.zero.magicshow.core.filter.advanced.MagicEarlyBirdFilter; import com.zero.magicshow.core.filter.advanced.MagicEmeraldFilter; import com.zero.magicshow.core.filter.advanced.MagicEvergreenFilter; import com.zero.magicshow.core.filter.advanced.MagicFairytaleFilter; import com.zero.magicshow.core.filter.advanced.MagicFreudFilter; import com.zero.magicshow.core.filter.advanced.MagicHealthyFilter; import com.zero.magicshow.core.filter.advanced.MagicHefeFilter; import com.zero.magicshow.core.filter.advanced.MagicHudsonFilter; import com.zero.magicshow.core.filter.advanced.MagicImageAdjustFilter; import com.zero.magicshow.core.filter.advanced.MagicInkwellFilter; import com.zero.magicshow.core.filter.advanced.MagicKevinFilter; import com.zero.magicshow.core.filter.advanced.MagicLatteFilter; import com.zero.magicshow.core.filter.advanced.MagicLomoFilter; import com.zero.magicshow.core.filter.advanced.MagicN1977Filter; import com.zero.magicshow.core.filter.advanced.MagicNashvilleFilter; import com.zero.magicshow.core.filter.advanced.MagicNostalgiaFilter; import com.zero.magicshow.core.filter.advanced.MagicPixarFilter; import com.zero.magicshow.core.filter.advanced.MagicRiseFilter; import com.zero.magicshow.core.filter.advanced.MagicRomanceFilter; import com.zero.magicshow.core.filter.advanced.MagicSakuraFilter; import com.zero.magicshow.core.filter.advanced.MagicSierraFilter; import com.zero.magicshow.core.filter.advanced.MagicSketchFilter; import com.zero.magicshow.core.filter.advanced.MagicSkinWhitenFilter; import com.zero.magicshow.core.filter.advanced.MagicSunriseFilter; import com.zero.magicshow.core.filter.advanced.MagicSunsetFilter; import com.zero.magicshow.core.filter.advanced.MagicSutroFilter; import com.zero.magicshow.core.filter.advanced.MagicSweetsFilter; import com.zero.magicshow.core.filter.advanced.MagicTenderFilter; import com.zero.magicshow.core.filter.advanced.MagicToasterFilter; import com.zero.magicshow.core.filter.advanced.MagicValenciaFilter; import com.zero.magicshow.core.filter.advanced.MagicWaldenFilter; import com.zero.magicshow.core.filter.advanced.MagicWarmFilter; import com.zero.magicshow.core.filter.advanced.MagicWhiteCatFilter; import com.zero.magicshow.core.filter.advanced.MagicXproIIFilter; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageBrightnessFilter; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageContrastFilter; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageExposureFilter; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageHueFilter; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageSaturationFilter; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageSharpenFilter; public class MagicFilterFactory{ private static MagicFilterType filterType = MagicFilterType.NONE; public static GPUImageFilter initFilters(MagicFilterType type){ filterType = type; switch (type) { case WHITECAT: return new MagicWhiteCatFilter(); case BLACKCAT: return new MagicBlackCatFilter(); case SKINWHITEN: return new MagicSkinWhitenFilter(); case ROMANCE: return new MagicRomanceFilter(); case SAKURA: return new MagicSakuraFilter(); case AMARO: return new MagicAmaroFilter(); case WALDEN: return new MagicWaldenFilter(); case ANTIQUE: return new MagicAntiqueFilter(); case CALM: return new MagicCalmFilter(); case BRANNAN: return new MagicBrannanFilter(); case BROOKLYN: return new MagicBrooklynFilter(); case EARLYBIRD: return new MagicEarlyBirdFilter(); case FREUD: return new MagicFreudFilter(); case HEFE: return new MagicHefeFilter(); case HUDSON: return new MagicHudsonFilter(); case INKWELL: return new MagicInkwellFilter(); case KEVIN: return new MagicKevinFilter(); case LOMO: return new MagicLomoFilter(); case N1977: return new MagicN1977Filter(); case NASHVILLE: return new MagicNashvilleFilter(); case PIXAR: return new MagicPixarFilter(); case RISE: return new MagicRiseFilter(); case SIERRA: return new MagicSierraFilter(); case SUTRO: return new MagicSutroFilter(); case TOASTER2: return new MagicToasterFilter(); case VALENCIA: return new MagicValenciaFilter(); case XPROII: return new MagicXproIIFilter(); case EVERGREEN: return new MagicEvergreenFilter(); case HEALTHY: return new MagicHealthyFilter(); case COOL: return new MagicCoolFilter(); case EMERALD: return new MagicEmeraldFilter(); case LATTE: return new MagicLatteFilter(); case WARM: return new MagicWarmFilter(); case TENDER: return new MagicTenderFilter(); case SWEETS: return new MagicSweetsFilter(); case NOSTALGIA: return new MagicNostalgiaFilter(); case FAIRYTALE: return new MagicFairytaleFilter(); case SUNRISE: return new MagicSunriseFilter(); case SUNSET: return new MagicSunsetFilter(); case CRAYON: return new MagicCrayonFilter(); case SKETCH: return new MagicSketchFilter(); //image adjust case BRIGHTNESS: return new GPUImageBrightnessFilter(); case CONTRAST: return new GPUImageContrastFilter(); case EXPOSURE: return new GPUImageExposureFilter(); case HUE: return new GPUImageHueFilter(); case SATURATION: return new GPUImageSaturationFilter(); case SHARPEN: return new GPUImageSharpenFilter(); case IMAGE_ADJUST: return new MagicImageAdjustFilter(); default: return null; } } public static MagicFilterType getCurrentFilterType(){ return filterType; } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/filter/utils/MagicFilterType.java ================================================ package com.zero.magicshow.core.filter.utils; /** * Created by why8222 on 2016/2/25. */ public enum MagicFilterType { NONE, FAIRYTALE, SUNRISE, SUNSET, WHITECAT, BLACKCAT, SKINWHITEN, HEALTHY, SWEETS, ROMANCE, SAKURA, WARM, ANTIQUE, NOSTALGIA, CALM, LATTE, TENDER, COOL, EMERALD, EVERGREEN, CRAYON, SKETCH, AMARO, BRANNAN, BROOKLYN, EARLYBIRD, FREUD, HEFE, HUDSON, INKWELL, KEVIN, LOMO, N1977, NASHVILLE, PIXAR, RISE, SIERRA, SUTRO, TOASTER2, VALENCIA, WALDEN, XPROII, //image adjust CONTRAST, BRIGHTNESS, EXPOSURE, HUE, SATURATION, SHARPEN, IMAGE_ADJUST } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/widget/BubbleSeekBar.java ================================================ package com.zero.magicshow.core.widget; import android.content.Context; import android.graphics.PixelFormat; import android.graphics.Point; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.os.IBinder; import android.support.v4.view.GravityCompat; import android.support.v7.widget.AppCompatSeekBar; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.util.Log; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; import android.widget.FrameLayout; import android.widget.SeekBar; import android.widget.TextView; import com.zero.magicshow.R; public class BubbleSeekBar extends AppCompatSeekBar{ private Drawable mThumbDrawable; private BubbleIndicator mBubbleIndicator; private boolean mIsListenerSet = false; private OnBubbleSeekBarChangeListener mOnBubbleSeekBarChangeListener; private int start = 0; private int end= 100; public BubbleSeekBar(Context context) { this(context, null); } public BubbleSeekBar(Context context, AttributeSet attrs) { this(context, attrs, 0); } public BubbleSeekBar(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mBubbleIndicator = new BubbleIndicator(context); setOnSeekBarChangeListener(mOnSeekBarChangeListener); } @Override public void setThumb(Drawable thumb) { super.setThumb(thumb); mThumbDrawable = thumb; } public void setRange(int start, int end){ this.start = start; this.end = end; } public void setMax(){ super.setMax(100); } private SeekBar.OnSeekBarChangeListener mOnSeekBarChangeListener = new SeekBar.OnSeekBarChangeListener() { @Override public void onStopTrackingTouch(SeekBar seekBar) { mBubbleIndicator.hideIndicator(); if(mOnBubbleSeekBarChangeListener != null) mOnBubbleSeekBarChangeListener.onStopTrackingTouch(seekBar); } @Override public void onStartTrackingTouch(SeekBar seekBar) { mBubbleIndicator.showIndicator(seekBar, mThumbDrawable.getBounds()); if(mOnBubbleSeekBarChangeListener != null) mOnBubbleSeekBarChangeListener.onStartTrackingTouch(seekBar); } @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if(fromUser) mBubbleIndicator.moveIndicator(mThumbDrawable.getBounds(), start + (int) ((end - start) * progress / 100.0f)); if(mOnBubbleSeekBarChangeListener != null) mOnBubbleSeekBarChangeListener.onProgressChanged(seekBar, progress, fromUser); } }; /** * Use OnBubbleSeekBarChangeListener instead of OnSeekBarChangeListener * * @param l The seek bar notification listener * * @see OnBubbleSeekBarChangeListener */ public void setOnSeekBarChangeListener(SeekBar.OnSeekBarChangeListener l) { if(mIsListenerSet) Log.e("BubbleSeekBar","Use OnBubbleSeekBarChangeListener instead of OnSeekBarChangeListener!!!!!"); else super.setOnSeekBarChangeListener(l); mIsListenerSet = true; } public void setOnBubbleSeekBarChangeListener(OnBubbleSeekBarChangeListener l){ this.mOnBubbleSeekBarChangeListener = l; } public interface OnBubbleSeekBarChangeListener{ void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser); void onStartTrackingTouch(SeekBar seekBar); void onStopTrackingTouch(SeekBar seekBar); } public class BubbleIndicator { private final WindowManager mWindowManager; private boolean mShowing; private int[] mDrawingLocation = new int[2]; Point screenSize = new Point(); private Floater mPopupView; public BubbleIndicator(Context context) { mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); mPopupView = new Floater(context); DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics(); screenSize.set(displayMetrics.widthPixels, displayMetrics.heightPixels); } public void showIndicator(View parent, Rect touchBounds) { if (isShowing()) { return; } IBinder windowToken = parent.getWindowToken(); if (windowToken != null) { WindowManager.LayoutParams p = createPopupLayout(windowToken); p.gravity = Gravity.TOP | GravityCompat.START; updateLayoutParamsForPosiion(parent, p); mShowing = true; translateViewIntoPosition(touchBounds.centerX()); invokePopup(p); } } private WindowManager.LayoutParams createPopupLayout(IBinder windowToken) { WindowManager.LayoutParams p = new WindowManager.LayoutParams(); p.gravity = Gravity.START | Gravity.TOP; p.width = ViewGroup.LayoutParams.MATCH_PARENT; p.height = ViewGroup.LayoutParams.MATCH_PARENT; p.format = PixelFormat.TRANSLUCENT; p.flags = computeFlags(p.flags); p.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL; p.token = windowToken; p.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN; return p; } private void invokePopup(WindowManager.LayoutParams p) { mWindowManager.addView(mPopupView, p); } public void moveIndicator(Rect touchBounds, int progress) { if (!isShowing()) { return; } translateViewIntoPosition(touchBounds.centerX()); mPopupView.setProgressText(progress); } public void hideIndicator(){ if (!isShowing()) { return; } mShowing = false; mWindowManager.removeView(mPopupView); } private void translateViewIntoPosition(final int x) { mPopupView.setFloatOffset(x + mDrawingLocation[0]); } private void updateLayoutParamsForPosiion(View anchor, WindowManager.LayoutParams p) { measureFloater(); int measuredHeight = mPopupView.getMeasuredHeight(); anchor.getLocationInWindow(mDrawingLocation); p.x = 0; p.y = mDrawingLocation[1] - measuredHeight; p.width = screenSize.x; p.height = measuredHeight; } private void measureFloater() { int specWidth = View.MeasureSpec.makeMeasureSpec(screenSize.x, View.MeasureSpec.EXACTLY); int specHeight = View.MeasureSpec.makeMeasureSpec(screenSize.y, View.MeasureSpec.AT_MOST); mPopupView.measure(specWidth, specHeight); } private boolean isShowing() { return mShowing; } private int computeFlags(int curFlags) { curFlags &= ~( WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); curFlags |= WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES; curFlags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; curFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS; return curFlags; } } private class Floater extends FrameLayout{ public TextView mMarker; private int mOffset; public Floater(Context context) { super(context); mMarker = new TextView(context); mMarker.setText("0%"); mMarker.setGravity(Gravity.CENTER); mMarker.setBackgroundResource(R.drawable.tooltip_bg); addView(mMarker, new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP)); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { measureChildren(widthMeasureSpec, heightMeasureSpec); int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightSie = mMarker.getMeasuredHeight(); setMeasuredDimension(widthSize, heightSie); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { int centerDiffX = (mMarker.getMeasuredWidth() - mMarker.getPaddingLeft()) / 2; int offset = mOffset - centerDiffX; mMarker.layout(offset, 0, offset + mMarker.getMeasuredWidth(), mMarker.getMeasuredHeight()); } public void setFloatOffset(int x) { mOffset = x; int centerDiffX = (mMarker.getMeasuredWidth() - mMarker.getPaddingLeft()) / 2; int offset = mOffset - centerDiffX; mMarker.offsetLeftAndRight(offset - mMarker.getLeft()); } public void setProgressText(int progress){ mMarker.setText(""+progress+"%"); } } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/widget/MagicCameraView.java ================================================ package com.zero.magicshow.core.widget; import android.app.Activity; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.SurfaceTexture; import android.hardware.Camera; import android.opengl.EGL14; import android.opengl.GLES20; import android.util.AttributeSet; import android.util.Log; import android.view.SurfaceHolder; import com.zero.magicshow.common.base.MagicBaseView; import com.zero.magicshow.common.iface.GravityCallBack; import com.zero.magicshow.common.utils.CameraBitmapUtil; import com.zero.magicshow.common.utils.GravityUtil; import com.zero.magicshow.common.utils.MagicParams; import com.zero.magicshow.common.utils.OpenGlUtils; import com.zero.magicshow.common.utils.Rotation; import com.zero.magicshow.common.utils.SavePictureTask; import com.zero.magicshow.common.utils.TextureRotationUtil; import com.zero.magicshow.core.camera.CameraEngine; import com.zero.magicshow.core.camera.utils.CameraInfo; import com.zero.magicshow.core.encoder.video.TextureMovieEncoder; import com.zero.magicshow.core.filter.advanced.MagicBeautyFilter; import com.zero.magicshow.core.filter.base.MagicCameraInputFilter; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.core.filter.utils.MagicFilterType; import java.io.File; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import java.nio.IntBuffer; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; /** * Created by why8222 on 2016/2/25. */ public class MagicCameraView extends MagicBaseView { private MagicCameraInputFilter cameraInputFilter; private MagicBeautyFilter beautyFilter; private SurfaceTexture surfaceTexture; public MagicCameraView(Context context) { this(context, null); } private boolean recordingEnabled; private int recordingStatus; private static final int RECORDING_OFF = 0; private static final int RECORDING_ON = 1; private static final int RECORDING_RESUMED = 2; private static TextureMovieEncoder videoEncoder = new TextureMovieEncoder(); private File outputFile; private int afterShootDegree = 90;//默认必须是90,为什么?不告诉你 private int frontShootDegree = -90;//默认必须是90,为什么?不告诉你 public MagicCameraView(Context context, AttributeSet attrs) { super(context, attrs); this.getHolder().addCallback(this); outputFile = new File(MagicParams.videoPath,MagicParams.videoName); recordingStatus = -1; recordingEnabled = false; scaleType = ScaleType.CENTER_CROP; GravityUtil.getInstance().init(getContext(),gravityCallBack); GravityUtil.getInstance().start((Activity) getContext()); setZOrderOnTop(true); setZOrderMediaOverlay(true); } private GravityCallBack gravityCallBack = new GravityCallBack() { @Override public void onGravityChange(int direction) { Log.e("HongLi","direction:" + direction); if(direction == GravityUtil.DIRECTION_LAND_LEFT){ afterShootDegree = 0; }else if(direction == GravityUtil.DIRECTION_LAND_RIGHT){ afterShootDegree = 0; }else if(direction == GravityUtil.DIRECTION_PORTRAIT_POSITIVE){ afterShootDegree = 90; }else if(direction == GravityUtil.DIRECTION_PORTRAIT_NEGATIVE){ afterShootDegree = -90; } } }; @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { super.onSurfaceCreated(gl, config); recordingEnabled = videoEncoder.isRecording(); if (recordingEnabled) recordingStatus = RECORDING_RESUMED; else recordingStatus = RECORDING_OFF; if(cameraInputFilter == null) cameraInputFilter = new MagicCameraInputFilter(); cameraInputFilter.init(); if (textureId == OpenGlUtils.NO_TEXTURE) { textureId = OpenGlUtils.getExternalOESTextureID(); if (textureId != OpenGlUtils.NO_TEXTURE) { surfaceTexture = new SurfaceTexture(textureId); surfaceTexture.setOnFrameAvailableListener(onFrameAvailableListener); } } } @Override public void onSurfaceChanged(GL10 gl, int width, int height) { super.onSurfaceChanged(gl, width, height); openCamera(); } @Override public void onDrawFrame(GL10 gl) { super.onDrawFrame(gl); if(surfaceTexture == null) return; surfaceTexture.updateTexImage(); if (recordingEnabled) { switch (recordingStatus) { case RECORDING_OFF: CameraInfo info = CameraEngine.getCameraInfo(); if(null == info){ return; } videoEncoder.setPreviewSize(info.previewWidth, info.pictureHeight); videoEncoder.setTextureBuffer(gLTextureBuffer); videoEncoder.setCubeBuffer(gLCubeBuffer); videoEncoder.startRecording(new TextureMovieEncoder.EncoderConfig( outputFile, info.previewWidth, info.pictureHeight, 1000000, EGL14.eglGetCurrentContext(), info)); recordingStatus = RECORDING_ON; break; case RECORDING_RESUMED: videoEncoder.updateSharedContext(EGL14.eglGetCurrentContext()); recordingStatus = RECORDING_ON; break; case RECORDING_ON: break; default: throw new RuntimeException("unknown status " + recordingStatus); } } else { switch (recordingStatus) { case RECORDING_ON: case RECORDING_RESUMED: videoEncoder.stopRecording(); recordingStatus = RECORDING_OFF; break; case RECORDING_OFF: break; default: throw new RuntimeException("unknown status " + recordingStatus); } } float[] mtx = new float[16]; surfaceTexture.getTransformMatrix(mtx); cameraInputFilter.setTextureTransformMatrix(mtx); int id = textureId; if(filter == null){ cameraInputFilter.onDrawFrame(textureId, gLCubeBuffer, gLTextureBuffer); }else{ id = cameraInputFilter.onDrawToTexture(textureId); filter.onDrawFrame(id, gLCubeBuffer, gLTextureBuffer); } videoEncoder.setTextureId(id); videoEncoder.frameAvailable(surfaceTexture); } private SurfaceTexture.OnFrameAvailableListener onFrameAvailableListener = new SurfaceTexture.OnFrameAvailableListener() { @Override public void onFrameAvailable(SurfaceTexture surfaceTexture) { requestRender(); } }; @Override public void setFilter(MagicFilterType type) { super.setFilter(type); videoEncoder.setFilter(type); } private void openCamera(){ if(CameraEngine.getCamera() == null) CameraEngine.openCamera(); CameraInfo info = CameraEngine.getCameraInfo(); if(info == null){ return; } if(info.orientation == 90 || info.orientation == 270){ imageWidth = info.previewHeight; imageHeight = info.previewWidth; }else{ imageWidth = info.previewWidth; imageHeight = info.previewHeight; } cameraInputFilter.onInputSizeChanged(imageWidth, imageHeight); adjustSize(info.orientation, info.isFront, true); if(surfaceTexture != null) CameraEngine.startPreview(surfaceTexture); } @Override public void surfaceDestroyed(SurfaceHolder holder) { super.surfaceDestroyed(holder); CameraEngine.releaseCamera(true); } public void changeRecordingState(boolean isRecording) { recordingEnabled = isRecording; } protected void onFilterChanged(){ super.onFilterChanged(); cameraInputFilter.onDisplaySizeChanged(surfaceWidth, surfaceHeight); if(filter != null) cameraInputFilter.initCameraFrameBuffer(imageWidth, imageHeight); else cameraInputFilter.destroyFramebuffers(); } @Override public void savePicture(final SavePictureTask savePictureTask) { final long startTakeTime = System.nanoTime() / 1000000; CameraEngine.takePicture(null, null, new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { CameraEngine.stopPreview(); // CameraEngine.releaseCamera(); final Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length); Log.e("HongLi","end take:" + (System.nanoTime() / 1000000 - startTakeTime) + ";recycler:" + bitmap.isRecycled()); queueEvent(new Runnable() { @Override public void run() { final long startDrawTime = System.nanoTime() / 1000000; Log.e("HongLi", "before drawPhoto bitmap:" + bitmap.isRecycled()); final Bitmap photo = drawPhoto(bitmap,null != CameraEngine.getCameraInfo() && CameraEngine.getCameraInfo().isFront); Log.e("HongLi","end darw:" + (System.nanoTime() / 1000000 - startDrawTime)); GLES20.glViewport(0, 0, surfaceWidth, surfaceHeight); if (photo != null){ savePictureTask.execute(photo); } CameraEngine.releaseCamera(true); } }); // CameraEngine.startPreview(); // CameraEngine.releaseCamera(); } }); } private Bitmap drawPhoto(Bitmap bitmap,boolean isRotated){ // if(afterShootDegree != 0 && !isRotated){ // //需要旋转角度 // Log.e("HongLi","需要旋转:" + afterShootDegree); // bitmap = BaseUtil.rotateBitmapByDegree(bitmap,afterShootDegree); // }else if(frontShootDegree !=0 && isRotated){ // Log.e("HongLi","需要旋转:" + frontShootDegree); // bitmap = BaseUtil.rotateBitmapByDegree(bitmap,frontShootDegree); // } bitmap = CameraBitmapUtil.handlerCameraBitmap((Activity) getContext(), bitmap, CameraEngine.cameraID); // BaseUtil.saveBitmap(bitmap,"/sdcard/DCIM/test3.jpg"); final int width = bitmap.getWidth(); final int height = bitmap.getHeight(); Log.e("HongLi","width:" + width + ";height:" + height + ";is recycler:" + bitmap.isRecycled()); final int[] mFrameBuffers = new int[1]; final int[] mFrameBufferTextures = new int[1]; // if(beautyFilter == null) // beautyFilter = new MagicBeautyFilter(); //TODO 此处不需要任何滤镜,只是使用父类即可 GPUImageFilter beautyFilter = new GPUImageFilter(); beautyFilter.init(); beautyFilter.onDisplaySizeChanged(width, height); beautyFilter.onInputSizeChanged(width, height); if(filter != null) { filter.onInputSizeChanged(width, height); filter.onDisplaySizeChanged(width, height); } GLES20.glGenFramebuffers(1, mFrameBuffers, 0); GLES20.glGenTextures(1, mFrameBufferTextures, 0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mFrameBufferTextures[0]); GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, width, height, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); final int textureId = OpenGlUtils.loadTexture(bitmap, OpenGlUtils.NO_TEXTURE, true); FloatBuffer gLCubeBuffer = ByteBuffer.allocateDirect(TextureRotationUtil.CUBE.length * 4) .order(ByteOrder.nativeOrder()) .asFloatBuffer(); FloatBuffer gLTextureBuffer = ByteBuffer.allocateDirect(TextureRotationUtil.TEXTURE_NO_ROTATION.length * 4) .order(ByteOrder.nativeOrder()) .asFloatBuffer(); gLCubeBuffer.put(TextureRotationUtil.CUBE).position(0); // if(isRotated) // gLTextureBuffer.put(TextureRotationUtil.getRotation(Rotation.NORMAL, false, false)).position(0); // else // gLTextureBuffer.put(TextureRotationUtil.getRotation(Rotation.NORMAL, false, true)).position(0); gLTextureBuffer.put(TextureRotationUtil.getRotation(Rotation.NORMAL, false, true)).position(0); GLES20.glViewport(0, 0, width, height); GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, mFrameBuffers[0]); GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, mFrameBufferTextures[0], 0); if(filter == null){ beautyFilter.onDrawFrame(textureId, gLCubeBuffer, gLTextureBuffer); }else{ beautyFilter.onDrawFrame(textureId); GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, mFrameBuffers[0]); GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, mFrameBufferTextures[0], 0); filter.onDrawFrame(mFrameBufferTextures[0], gLCubeBuffer, gLTextureBuffer); } final IntBuffer ib = IntBuffer.allocate(width * height); GLES20.glReadPixels(0, 0, width, height, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, ib); Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); result.copyPixelsFromBuffer(ib); GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); GLES20.glDeleteTextures(1, new int[]{textureId}, 0); GLES20.glDeleteFramebuffers(mFrameBuffers.length, mFrameBuffers, 0); GLES20.glDeleteTextures(mFrameBufferTextures.length, mFrameBufferTextures, 0); beautyFilter.destroy(); beautyFilter = null; if(filter != null) { filter.onDisplaySizeChanged(surfaceWidth, surfaceHeight); filter.onInputSizeChanged(imageWidth, imageHeight); } // result = BaseUtil.rotateBitmapByDegree(result,-afterShootDegree); return result; } public void onBeautyLevelChanged() { cameraInputFilter.onBeautyLevelChanged(); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/widget/MagicImageView.java ================================================ package com.zero.magicshow.core.widget; import android.content.Context; import android.graphics.Bitmap; import android.util.AttributeSet; import android.util.Log; import com.zero.magicshow.core.beautify.MagicJni; import com.zero.magicshow.core.filter.advanced.MagicImageAdjustFilter; import com.zero.magicshow.core.filter.base.gpuimage.GPUImageFilter; import com.zero.magicshow.core.filter.utils.MagicFilterType; import com.zero.magicshow.common.utils.SavePictureTask; import com.zero.magicshow.common.utils.OpenGlUtils; import com.zero.magicshow.common.base.MagicBaseView; import java.nio.ByteBuffer; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; /** * Created by why8222 on 2016/2/25. */ public class MagicImageView extends MagicBaseView{ private final GPUImageFilter imageInput; private ByteBuffer _bitmapHandler = null; private Bitmap originBitmap = null; public MagicImageView(Context context) { this(context, null); } public MagicImageView(Context context, AttributeSet attrs) { super(context, attrs); imageInput = new GPUImageFilter(); } @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { super.onSurfaceCreated(gl, config); imageInput.init(); } @Override public void onSurfaceChanged(GL10 gl, int width, int height) { super.onSurfaceChanged(gl, width, height); adjustSize(0, false, false); } @Override public void onDrawFrame(GL10 gl) { super.onDrawFrame(gl); if(textureId == OpenGlUtils.NO_TEXTURE) textureId = OpenGlUtils.loadTexture(getBitmap(), OpenGlUtils.NO_TEXTURE); if(filter == null) imageInput.onDrawFrame(textureId, gLCubeBuffer, gLTextureBuffer); else filter.onDrawFrame(textureId, gLCubeBuffer, gLTextureBuffer); } @Override public void savePicture(SavePictureTask savePictureTask) { // String tempFilePath = BaseUtil.getRandomTempImagePath(); // BaseUtil.saveBitmap(originBitmap, BaseUtil.getRandomTempImagePath()); savePictureTask.execute(originBitmap); } //还原 public void restore(){ if(filter != null){ setFilter(MagicFilterType.NONE); }else{ setImageBitmap(originBitmap); } } //应用 public void commit(){ if(filter != null){ getBitmapFromGL(originBitmap, false); deleteTextures(); setFilter(MagicFilterType.NONE); }else if(null != _bitmapHandler){ originBitmap.recycle(); originBitmap = MagicJni.jniGetBitmapFromStoredBitmapData(_bitmapHandler); } } protected void onGetBitmapFromGL(Bitmap bitmap){ originBitmap = bitmap; storeBitmap(originBitmap, false); } protected void storeBitmap(Bitmap bitmap,boolean recyle){ // if(_bitmapHandler != null) // freeBitmap(); // _bitmapHandler = MagicJni.jniStoreBitmapData(bitmap); setImageBitmap(bitmap); if(recyle) bitmap.recycle(); } public void setImageBitmap(Bitmap bitmap) { if (bitmap == null || bitmap.isRecycled()) return; Log.e("HongLi","imageWidth:" + bitmap.getWidth() + ";imageHeight:" + bitmap.getHeight()); setBitmap(bitmap); imageWidth = bitmap.getWidth(); imageHeight = bitmap.getHeight(); adjustSize(0, false, false); requestRender(); } public void initMagicBeautify(){ if(_bitmapHandler == null){ Log.e("MagicSDK", "please storeBitmap first!!"); return; } MagicJni.jniInitMagicBeautify(_bitmapHandler); } public void uninitMagicBeautify(){ if(_bitmapHandler == null){ Log.e("MagicSDK", "please storeBitmap first!!"); return; } MagicJni.jniUnInitMagicBeautify(); } public void setBitmap(Bitmap bitmap){ if(_bitmapHandler != null) freeBitmap(); _bitmapHandler = MagicJni.jniStoreBitmapData(bitmap); originBitmap = bitmap; } public void freeBitmap(){ if(_bitmapHandler == null) return; MagicJni.jniFreeBitmapData(_bitmapHandler); _bitmapHandler = null; } public Bitmap getBitmap(){ if(_bitmapHandler == null) return null; return MagicJni.jniGetBitmapFromStoredBitmapData(_bitmapHandler); } public void setSkinSmooth(float level){ if(_bitmapHandler == null) return; if(level > 10 || level < 0){ Log.e("MagicSDK","Skin Smooth level must in [0,10]"); return; } MagicJni.jniStartSkinSmooth(level); reftreshDisplay(); if(magicListener != null) magicListener.onEnd(); } public void setWhiteSkin(float level){ if(_bitmapHandler == null) return; if(level > 5 || level < 0){ Log.e("MagicSDK","Skin white level must in [1,5]"); return; } // long startTime = System.nanoTime() / 1000000; // Log.e("HongLi","before jni:" + 0); MagicJni.jniStartWhiteSkin(level); // BaseUtil.saveBitmap(originBitmap,"/sdcard/DCIM/test2.jpg"); // Log.e("HongLi","end jni:" + (System.nanoTime() / 1000000 - startTime)); reftreshDisplay(); // Log.e("HongLi","end refresh:" + (System.nanoTime() / 1000000 - startTime)); if(magicListener != null) magicListener.onEnd(); } public void adjustFilter(float range,MagicFilterType type){ if(!(filter instanceof MagicImageAdjustFilter)){ return; } ((MagicImageAdjustFilter)filter).setImageFilter(range,type); requestRender(); // reftreshDisplay(); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/core/widget/TwoLineSeekBar.java ================================================ package com.zero.magicshow.core.widget; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.util.AttributeSet; import android.view.GestureDetector; import android.view.MotionEvent; import android.view.View; import android.widget.Scroller; import com.zero.magicshow.R; import java.util.Map; import java.util.TreeMap; public class TwoLineSeekBar extends View { private float mDefaultAreaRadius = 0.0f; private OnSeekDefaultListener mDefaultListener; private OnSeekDownListener mDownListener; private GestureDetector mGestureDetector; private SeekBarGestureListener mGestureListener; private Paint mHighLightLinePaint; private Paint mLinePaint1; private Paint mLinePaint2; private OnSeekChangeListener mListener; private float mNailOffset; private Paint mNailPaint; private Map mSavedColors; private Scroller mScroller; private float mSeekLength; private float mSeekLineEnd; private float mSeekLineStart; private int mStartValue; private float mStep; private float mThumbOffset; private Paint mThumbPaint; private float mThumbRadius = 8.0f; private float mNailRadius = 5.0f; private float mNailStrokeWidth = 0.0f; private float mLineWidth = 0.0f; private int mMaxValue = 0x64; private int mCurrentValue = 0x32; private int mDefaultValue = 0x32; private boolean mEnableTouch = true; private Rect mCircleRect = new Rect(); private boolean mIsGlobalDrag = true; private boolean mIsTouchCircle = false; private boolean mSupportSingleTap = true; public TwoLineSeekBar(Context context, AttributeSet attrs) { super(context, attrs); mThumbRadius = dpToPixel(mThumbRadius); mNailRadius = dpToPixel(mNailRadius); mNailStrokeWidth = context.getResources().getDimension(R.dimen.seekbar_nail_stroke_width); mLineWidth = context.getResources().getDimension(R.dimen.seekbar_line_width); mDefaultAreaRadius = ((((mThumbRadius - mNailRadius) - mNailStrokeWidth) + mThumbRadius) / 2.0f); init(); } private void init() { mScroller = new Scroller(getContext()); mGestureListener = new SeekBarGestureListener(); mGestureDetector = new GestureDetector(getContext(), mGestureListener); mNailPaint = new Paint(); mNailPaint.setAntiAlias(true); mNailPaint.setColor(Color.parseColor("#ffd600")); mNailPaint.setStrokeWidth(mNailStrokeWidth); mNailPaint.setStyle(Paint.Style.STROKE); mThumbPaint = new Paint(); mThumbPaint.setAntiAlias(true); mThumbPaint.setColor(Color.parseColor("#ffffff")); mThumbPaint.setStyle(Paint.Style.FILL); mLinePaint1 = new Paint(); mLinePaint1.setAntiAlias(true); mLinePaint1.setColor(Color.parseColor("#ffffff")); mLinePaint1.setAlpha(0xc8); mLinePaint2 = new Paint(); mLinePaint2.setAntiAlias(true); mLinePaint2.setColor(Color.parseColor("#ffffff")); mLinePaint2.setAlpha(0xc8); mHighLightLinePaint = new Paint(); mHighLightLinePaint.setAntiAlias(true); mHighLightLinePaint.setColor(Color.parseColor("#ffd600")); mHighLightLinePaint.setAlpha(0xc8); mSupportSingleTap = true; } public float dpToPixel(float dp) { return (getResources().getDisplayMetrics().density * dp); } public void setSingleTapSupport(boolean support) { mSupportSingleTap = support; } protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int hmode = MeasureSpec.getMode(heightMeasureSpec); if(hmode == -0x8000) { int hsize = Math.round((mThumbRadius * 2.0f)); hsize += (getPaddingTop() + getPaddingBottom()); int wsize = MeasureSpec.getSize(widthMeasureSpec); setMeasuredDimension(wsize, hsize); return; } super.onMeasure(widthMeasureSpec, heightMeasureSpec); } protected void onDraw(Canvas canvas) { if(mSeekLength == 0) { int width = getWidth(); mSeekLength = ((float)((width - getPaddingLeft()) - getPaddingRight()) - (mThumbRadius * 2.0f)); mSeekLineStart = ((float)getPaddingLeft() + mThumbRadius); mSeekLineEnd = ((float)(width - getPaddingRight()) - mThumbRadius); int currValue = Math.max(0x0, mCurrentValue); mNailOffset = ((mSeekLength * (float)mDefaultValue) / (float)mMaxValue); if((mDefaultValue == 0) || (mDefaultValue == mMaxValue)) { mThumbOffset = ((mSeekLength * (float)currValue) / (float)mMaxValue); } else { float defaultAreaLength = mDefaultAreaRadius * 2.0f; if(currValue < mDefaultValue) { mThumbOffset = (((mSeekLength - defaultAreaLength) * (float)currValue) / (float)mMaxValue); } else if(currValue > mDefaultValue) { mThumbOffset = ((((mSeekLength - defaultAreaLength) * (float)currValue) / (float)mMaxValue) + (mDefaultAreaRadius * 2.0f)); } else { mThumbOffset = mNailOffset; } } } float top = (float)(getMeasuredHeight() / 0x2) - (mLineWidth / 2.0f); float bottom = top + mLineWidth; float right1 = ((mSeekLineStart + mNailOffset) + (mNailStrokeWidth / 2.0f)) - mNailRadius; if(right1 > mSeekLineStart) { canvas.drawRect(mSeekLineStart, top, right1, bottom, mLinePaint1); } float left2 = right1 + (mNailRadius * 2.0f); if(mSeekLineEnd > left2) { canvas.drawRect(left2, top, mSeekLineEnd, bottom, mLinePaint2); } float nailX = mSeekLineStart + mNailOffset; float nailY = (float)(getMeasuredHeight() / 0x2); canvas.drawCircle(nailX, nailY, mNailRadius, mNailPaint); float thumbX = mSeekLineStart + mThumbOffset; float thumbY = (float)(getMeasuredHeight() / 0x2); float highLightLeft = thumbX + mThumbRadius; float highLightRight = nailX - mNailRadius; if(thumbX > nailX) { highLightLeft = nailX + mNailRadius; highLightRight = thumbX - mThumbRadius; } canvas.drawRect(highLightLeft, top, highLightRight, bottom, mHighLightLinePaint); canvas.drawCircle(thumbX, thumbY, mThumbRadius, mThumbPaint); mCircleRect.top = (int)(thumbY - mThumbRadius); mCircleRect.left = (int)(thumbX - mThumbRadius); mCircleRect.right = (int)(mThumbRadius + thumbX); mCircleRect.bottom = (int)(mThumbRadius + thumbY); if(mScroller.computeScrollOffset()) { mThumbOffset = (float)mScroller.getCurrY(); invalidate(); } super.onDraw(canvas); } public boolean onTouchEvent(MotionEvent event) { if(event.getAction() == 0) { if(!mIsGlobalDrag) { mIsTouchCircle = mCircleRect.contains((int)event.getX(), (int)event.getY()); } } if((!mIsGlobalDrag) && (!mIsTouchCircle)) { return true; } if(mEnableTouch) { if(!mGestureDetector.onTouchEvent(event)) { if((0x1 == event.getAction()) || (0x3 == event.getAction())) { mIsTouchCircle = false; mGestureListener.onUp(event); if(mListener != null) { mListener.onSeekStopped(((float)(mCurrentValue + mStartValue) * mStep), mStep); } return true; } return false; } } return true; } public void setLineColor(String color) { mHighLightLinePaint.setColor(Color.parseColor(color)); mNailPaint.setColor(Color.parseColor(color)); invalidate(); } public void setBaseLineColor(String color) { mLinePaint1.setColor(Color.parseColor(color)); mLinePaint2.setColor(Color.parseColor(color)); } public void setThumbColor(String color) { mThumbPaint.setColor(Color.parseColor(color)); } public void setEnabled(boolean enabled) { if(enabled == isEnabled()) { return; } super.setEnabled(enabled); mEnableTouch = enabled; if(mSavedColors == null) { mSavedColors = new TreeMap(); } if(enabled) { int color = (Integer)mSavedColors.get("mNailPaint").intValue(); mNailPaint.setColor(color); color = (Integer)mSavedColors.get("mThumbPaint").intValue(); mThumbPaint.setColor(color); color = (Integer)mSavedColors.get("mLinePaint1").intValue(); mLinePaint1.setColor(color); color = (Integer)mSavedColors.get("mLinePaint2").intValue(); mLinePaint2.setColor(color); color = (Integer)mSavedColors.get("mHighLightLinePaint").intValue(); mHighLightLinePaint.setColor(color); return; } mSavedColors.put("mNailPaint", Integer.valueOf(mNailPaint.getColor())); mSavedColors.put("mThumbPaint", Integer.valueOf(mThumbPaint.getColor())); mSavedColors.put("mLinePaint1", Integer.valueOf(mLinePaint1.getColor())); mSavedColors.put("mLinePaint2", Integer.valueOf(mLinePaint2.getColor())); mSavedColors.put("mHighLightLinePaint", Integer.valueOf(mHighLightLinePaint.getColor())); mNailPaint.setColor(Color.parseColor("#505050")); mThumbPaint.setColor(Color.parseColor("#505050")); mLinePaint1.setColor(Color.parseColor("#505050")); mLinePaint2.setColor(Color.parseColor("#505050")); mHighLightLinePaint.setColor(Color.parseColor("#505050")); } public void setThumbSize(float size) { mThumbRadius = size; } public void setSeekLength(int startValue, int endValue, int circleValue, float step) { mDefaultValue = Math.round(((float)(circleValue - startValue) / step)); mMaxValue = Math.round(((float)(endValue - startValue) / step)); mStartValue = Math.round(((float)startValue / step)); mStep = step; } public void setDefaultValue(float value) { mCurrentValue = (Math.round((value / mStep)) - mStartValue); if(mDefaultListener != null) { mDefaultListener.onSeekDefaulted(value); } updateThumbOffset(); invalidate(); } public float getValue() { return ((float)(mCurrentValue + mStartValue) * mStep); } public void setValue(float value) { int newValue = Math.round((value / mStep)) - mStartValue; if(newValue == mCurrentValue) { return; } mCurrentValue = newValue; if(mListener != null) { mListener.onSeekChanged((mStep * value), mStep); } updateThumbOffset(); postInvalidate(); } public void setOnSeekChangeListener(OnSeekChangeListener listener) { mListener = listener; } public OnSeekChangeListener getOnSeekChangeListener() { return mListener; } public void setOnDefaultListener(OnSeekDefaultListener listener) { mDefaultListener = listener; } public void setOnSeekDownListener(OnSeekDownListener listener) { mDownListener = listener; } private void setValueInternal(int value) { if(mCurrentValue == value) { return; } mCurrentValue = value; if(mListener != null) { mListener.onSeekChanged(((float)(mStartValue + value) * mStep), mStep); } } private void updateThumbOffset() { if((mDefaultValue == 0) || (mDefaultValue == mMaxValue)) { if(mCurrentValue <= 0) { mThumbOffset = 0.0f; return; } if(mCurrentValue == mMaxValue) { mThumbOffset = (mSeekLineEnd - mSeekLineStart); return; } if(mCurrentValue == mDefaultValue) { mThumbOffset = mNailOffset; return; } mThumbOffset = (((float)mCurrentValue * mSeekLength) / (float)mMaxValue); return; } float defaultAreaLength = mDefaultAreaRadius * 2.0f; if(mCurrentValue <= 0) { mThumbOffset = 0.0f; return; } if(mCurrentValue == mMaxValue) { mThumbOffset = (mSeekLineEnd - mSeekLineStart); return; } if(mCurrentValue < mDefaultValue) { mThumbOffset = (((mSeekLength - defaultAreaLength) * (float)mCurrentValue) / (float)mMaxValue); return; } if(mCurrentValue > mDefaultValue) { mThumbOffset = ((((mSeekLength - defaultAreaLength) * (float)mCurrentValue) / (float)mMaxValue) + defaultAreaLength); return; } mThumbOffset = mNailOffset; } public void reset() { mSeekLength = 0.0f; mSeekLineStart = 0.0f; mSeekLineEnd = 0.0f; mNailOffset = 0.0f; mThumbOffset = 0.0f; mMaxValue = 0x0; mCurrentValue = 0x7fffffff; mDefaultValue = 0x0; mStartValue = 0x0; mStep = 0.0f; mScroller.abortAnimation(); } class SeekBarGestureListener extends GestureDetector.SimpleOnGestureListener { public boolean onUp(MotionEvent e) { float initThumbOffset = mThumbOffset; updateThumbOffset(); mScroller.startScroll(0x0, Math.round(initThumbOffset), 0x0, Math.round((mThumbOffset - initThumbOffset)), 0x0); mThumbOffset = initThumbOffset; invalidate(); return true; } public boolean onDown(MotionEvent e) { if(mDownListener != null) { mDownListener.onSeekDown(); } return true; } public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { mThumbOffset -= distanceX; if (mThumbOffset < mSeekLineStart - mThumbRadius) { mThumbOffset = mSeekLineStart - mThumbRadius; } if (mThumbOffset > mSeekLineEnd - mThumbRadius) { mThumbOffset = mSeekLineEnd - mThumbRadius; } float newValue; if (mThumbOffset < mNailOffset - mDefaultAreaRadius) { newValue = mThumbOffset * (-2 + mMaxValue) / (mSeekLength - 2.0f * mDefaultAreaRadius); } else if (mThumbOffset > mNailOffset + mDefaultAreaRadius) { newValue = 1.0F + (mDefaultValue + (mThumbOffset - mNailOffset - mDefaultAreaRadius) * (-2 + mMaxValue) / (mSeekLength - 2.0f * mDefaultAreaRadius)); } else { newValue = mDefaultValue; } if ((mDefaultValue == 0) || (mDefaultValue == mMaxValue)) { newValue = mThumbOffset * mMaxValue / mSeekLength; } if (newValue < 0.0f) { newValue = 0.0f; } if (newValue > mMaxValue) { newValue = mMaxValue; } setValueInternal(Math.round(newValue)); invalidate(); return true; } public boolean onSingleTapUp(MotionEvent e) { if(!mSupportSingleTap) { return false; } int newValue = mCurrentValue - 1; if(e.getX() > mThumbOffset) { newValue = mCurrentValue + 1; } if(newValue < 0) { newValue = 0; } if(newValue > mMaxValue) { newValue = mMaxValue; } setValueInternal(Math.round(newValue)); float initThumbOffset = mThumbOffset; updateThumbOffset(); mScroller.startScroll(0x0, Math.round(initThumbOffset), 0x0, Math.round((mThumbOffset - initThumbOffset)), 0x190); mThumbOffset = initThumbOffset; postInvalidate(); if(mListener != null) { mListener.onSeekStopped(((float)(mCurrentValue + mStartValue) * mStep), mStep); } return true; } } public void setIsGlobalDrag(boolean mIsGlobalDrag) { this.mIsGlobalDrag = mIsGlobalDrag; } public static abstract interface OnSeekDefaultListener{ public abstract void onSeekDefaulted(float value); } public static abstract interface OnSeekDownListener{ public abstract void onSeekDown(); } public static abstract interface OnSeekChangeListener{ public abstract void onSeekChanged(float value, float step); public abstract void onSeekStopped(float value, float step); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/view/edit/ImageEditFragment.java ================================================ package com.zero.magicshow.view.edit; import android.support.v4.app.Fragment; import com.zero.magicshow.common.iface.DialogYesOrNoCallBack; import com.zero.magicshow.common.utils.BaseUtil; import com.zero.magicshow.core.MagicEngine; public abstract class ImageEditFragment extends Fragment { protected onHideListener mOnHideListener; public void doFinishAction(){ if(isChanged()){ BaseUtil.openYesOrNoDialog(getActivity(), "是否应用修改?", "是否应用修改?", "是", "否", new DialogYesOrNoCallBack() { @Override public void onYesClick() { onDialogButtonClick(); MagicEngine.getInstance().commitImage(); } @Override public void onNoClick() { onDialogButtonClick(); MagicEngine.getInstance().restoreImage(); } }); }else if(null != mOnHideListener){ mOnHideListener.onAfterHide(); } } public void doSaveConfigeAction(){ if(isChanged()){ MagicEngine.getInstance().commitImage(); } if(mOnHideListener != null){ mOnHideListener.onAfterHide(); } } public void setOnHideListener(onHideListener l){ this.mOnHideListener = l; } protected abstract boolean isChanged(); protected void onDialogButtonClick(){ if(mOnHideListener != null){ mOnHideListener.onAfterHide(); } } public interface onHideListener{ void onAfterHide(); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/view/edit/ImageEditManager.java ================================================ package com.zero.magicshow.view.edit; import android.content.Context; import android.support.v4.app.Fragment; import android.view.ViewGroup; import com.zero.magicshow.R; import com.zero.magicshow.activity.AlbumActivity; import com.zero.magicshow.view.edit.adjust.ImageEditAdjustView; import com.zero.magicshow.view.edit.beauty.ImageEditBeautyView; import com.zero.magicshow.view.edit.filter.ImageEditFilterView; import com.zero.magicshow.view.edit.iface.ImageEditNavListener; import com.zero.magicshow.view.edit.navigation.ImageEditNavigationView; import java.util.HashMap; /** * Created by hongli on 2017/8/22. */ public class ImageEditManager { public static void initAdjustView(Context context, HashMap fragmentHashMap, ViewGroup blockNavigation, ImageEditFragment.onHideListener mOnHideListener, ImageEditNavListener imageEditNavListener){ ImageEditAdjustView adjustView = new ImageEditAdjustView(); adjustView.setOnHideListener(mOnHideListener); ImageEditNavigationView adjustNavView = ImageEditNavigationView.builder(context) .setIconRes(R.drawable.selector_image_edit) .setName(context.getResources().getString(R.string.edit_edit)) .setType(AlbumActivity.IMAGE_EDIT_TYPE_ADJUST) .setListener(imageEditNavListener); fragmentHashMap.put(AlbumActivity.IMAGE_EDIT_TYPE_ADJUST,adjustView); blockNavigation.addView(adjustNavView); } public static void initBeautyView(Context context, HashMap fragmentHashMap, ViewGroup blockNavigation, ImageEditFragment.onHideListener mOnHideListener, ImageEditNavListener imageEditNavListener){ ImageEditBeautyView beautyView = new ImageEditBeautyView(); beautyView.setOnHideListener(mOnHideListener); ImageEditNavigationView beautyNavView = ImageEditNavigationView.builder(context) .setIconRes(R.drawable.selector_image_beauty) .setName(context.getResources().getString(R.string.edit_beauty)) .setType(AlbumActivity.IMAGE_EDIT_TYPE_BEAUTY) .setListener(imageEditNavListener); fragmentHashMap.put(AlbumActivity.IMAGE_EDIT_TYPE_BEAUTY,beautyView); blockNavigation.addView(beautyNavView); } public static void initFilterView(Context context, HashMap fragmentHashMap, ViewGroup blockNavigation, ImageEditFragment.onHideListener mOnHideListener, ImageEditNavListener imageEditNavListener){ ImageEditFilterView filterView = new ImageEditFilterView(); filterView.setOnHideListener(mOnHideListener); ImageEditNavigationView filterNavView = ImageEditNavigationView.builder(context) .setIconRes(R.drawable.selector_image_filter) .setName(context.getResources().getString(R.string.edit_filter)) .setType(AlbumActivity.IMAGE_EDIT_TYPE_FILTER) .setListener(imageEditNavListener); fragmentHashMap.put(AlbumActivity.IMAGE_EDIT_TYPE_FILTER,filterView); blockNavigation.addView(filterNavView); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/view/edit/adjust/ImageEditAdjustView.java ================================================ package com.zero.magicshow.view.edit.adjust; import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.RadioGroup; import android.widget.RadioGroup.OnCheckedChangeListener; import android.widget.TextView; import com.zero.magicshow.R; import com.zero.magicshow.core.MagicEngine; import com.zero.magicshow.core.filter.utils.MagicFilterType; import com.zero.magicshow.view.edit.ImageEditFragment; import com.zero.magicshow.core.widget.TwoLineSeekBar; import com.zero.magicshow.core.widget.TwoLineSeekBar.OnSeekChangeListener; import static com.zero.magicshow.core.filter.utils.MagicFilterType.IMAGE_ADJUST; public class ImageEditAdjustView extends ImageEditFragment { private TwoLineSeekBar mSeekBar; private float contrast = -50.0f; private float exposure = 0.0f; private float saturation = 0.0f; private float sharpness = 0.0f; private float brightness = 0.0f; private float hue = 0.0f; private RadioGroup mRadioGroup; private MagicFilterType type = MagicFilterType.NONE; private ImageView mLabel; private TextView mVal; private LinearLayout mLinearLayout; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_image_edit_adjust, container, false); } @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); mRadioGroup = (RadioGroup)getView().findViewById(R.id.fragment_adjust_radiogroup); mRadioGroup.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup group, int checkedId) { if(checkedId != -1){ mLinearLayout.setVisibility(View.VISIBLE); } if(checkedId == R.id.fragment_radio_contrast){ type = MagicFilterType.CONTRAST; mSeekBar.reset(); mSeekBar.setSeekLength(-100, 100, -50, 1); mSeekBar.setValue(contrast); mVal.setText(""+contrast); mLabel.setBackgroundResource(R.drawable.selector_image_edit_adjust_contrast); }else if(checkedId == R.id.fragment_radio_exposure){ type = MagicFilterType.EXPOSURE; mSeekBar.reset(); mSeekBar.setSeekLength(-100, 100, 0, 1); mSeekBar.setValue(exposure); mVal.setText(""+exposure); mLabel.setBackgroundResource(R.drawable.selector_image_edit_adjust_exposure); }else if(checkedId == R.id.fragment_radio_saturation){ type = MagicFilterType.SATURATION; mSeekBar.reset(); mSeekBar.setSeekLength(-100, 100, 0, 1); mSeekBar.setValue(saturation); mVal.setText(""+saturation); mLabel.setBackgroundResource(R.drawable.selector_image_edit_adjust_saturation); }else if(checkedId == R.id.fragment_radio_sharpness){ type = MagicFilterType.SHARPEN; mSeekBar.reset(); mSeekBar.setSeekLength(-100, 100, 0, 1); mSeekBar.setValue(sharpness); mVal.setText(""+sharpness); mLabel.setBackgroundResource(R.drawable.selector_image_edit_adjust_sharpness); }else if(checkedId == R.id.fragment_radio_bright){ type = MagicFilterType.BRIGHTNESS; mSeekBar.reset(); mSeekBar.setSeekLength(-100, 100, 0, 1); mSeekBar.setValue(brightness); mVal.setText(""+brightness); mLabel.setBackgroundResource(R.drawable.selector_image_edit_adjust_bright); }else if(checkedId == R.id.fragment_radio_hue){ type = MagicFilterType.HUE; mSeekBar.reset(); mSeekBar.setSeekLength(0, 360, 0, 1); mSeekBar.setValue(hue); mVal.setText(""+hue); mLabel.setBackgroundResource(R.drawable.selector_image_edit_adjust_hue); } } }); mSeekBar = (TwoLineSeekBar)view.findViewById(R.id.item_seek_bar); mSeekBar.setOnSeekChangeListener(mOnSeekChangeListener); mVal = (TextView)view.findViewById(R.id.item_val); mLabel = (ImageView)view.findViewById(R.id.item_label); mLinearLayout = (LinearLayout)view.findViewById(R.id.seek_bar_item_menu); MagicEngine.getInstance().setFilter(IMAGE_ADJUST); mRadioGroup.getChildAt(0).performClick(); } @Override public void onHiddenChanged(boolean hidden) { super.onHiddenChanged(hidden); if(hidden){ contrast = -50.0f; exposure = 0.0f; saturation = 0.0f; sharpness = 0.0f; brightness = 0.0f; hue = 0.0f; mRadioGroup.clearCheck(); MagicEngine.getInstance().setFilter(MagicFilterType.NONE); mLinearLayout.setVisibility(View.INVISIBLE); type = MagicFilterType.NONE; mRadioGroup.getChildAt(0).performClick(); }else{ MagicEngine.getInstance().setFilter(IMAGE_ADJUST); } } protected boolean isChanged(){ return contrast != -50.0f || exposure != 0.0f || saturation != 0.0f || sharpness != 0.0f || brightness != 0.0f || hue != 0.0f; } protected float range(final int percentage, final float start, final float end) { return (end - start) * percentage / 100.0f + start; } protected int range(final int percentage, final int start, final int end) { return (end - start) * percentage / 100 + start; } private float convertToProgress(float value){ if(mRadioGroup.getCheckedRadioButtonId() == R.id.fragment_radio_contrast){ contrast = value; return range(Math.round((value + 100) / 2), 0.0f, 4.0f); }else if(mRadioGroup.getCheckedRadioButtonId() == R.id.fragment_radio_exposure){ exposure = value; return range(Math.round((value + 100) / 2), -2.0f, 2.0f); }else if(mRadioGroup.getCheckedRadioButtonId() == R.id.fragment_radio_saturation){ saturation = value; return range(Math.round((value + 100) / 2), 0.0f, 2.0f); }else if(mRadioGroup.getCheckedRadioButtonId() == R.id.fragment_radio_sharpness){ sharpness = value; return range(Math.round((value + 100) / 2), -4.0f, 4.0f); }else if(mRadioGroup.getCheckedRadioButtonId() == R.id.fragment_radio_bright){ brightness = value; return range(Math.round((value + 100) / 2), -0.5f, 0.5f); }else if(mRadioGroup.getCheckedRadioButtonId() == R.id.fragment_radio_hue){ hue = value; return range(Math.round(100 * value / 360.0f), 0.0f, 360.0f); } return 0; } private OnSeekChangeListener mOnSeekChangeListener = new OnSeekChangeListener() { @Override public void onSeekStopped(float value, float step) { mVal.setText(""+value); mLabel.setPressed(value != 0.0f); Log.e("HongLi","percent:" + convertToProgress(value)); MagicEngine.getInstance().adjustFilter(convertToProgress(value), type); } @Override public void onSeekChanged(float value, float step) { } }; } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/view/edit/beauty/ImageEditBeautyView.java ================================================ package com.zero.magicshow.view.edit.beauty; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.RadioGroup; import android.widget.RadioGroup.OnCheckedChangeListener; import android.widget.RelativeLayout; import android.widget.SeekBar; import com.zero.magicshow.R; import com.zero.magicshow.core.MagicEngine; import com.zero.magicshow.view.edit.ImageEditFragment; import com.zero.magicshow.core.widget.BubbleSeekBar; public class ImageEditBeautyView extends ImageEditFragment { private RadioGroup mRadioGroup; private RelativeLayout mSkinSmoothView; private RelativeLayout mSkinColorView; private BubbleSeekBar mSmoothBubbleSeekBar; private BubbleSeekBar mWhiteBubbleSeekBar; private boolean isSmoothed = false; private boolean isWhiten = false; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_image_edit_beauty, container, false); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public void onViewCreated(View view, Bundle savedInstanceState) { mSkinSmoothView = (RelativeLayout) getView().findViewById(R.id.fragment_beauty_skin); mSkinColorView = (RelativeLayout) getView().findViewById(R.id.fragment_beauty_color); mRadioGroup = (RadioGroup)getView().findViewById(R.id.fragment_beauty_radiogroup); mRadioGroup.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup group, int checkedId) { if(checkedId == R.id.fragment_beauty_btn_skinsmooth){ mSkinSmoothView.setVisibility(View.VISIBLE); mSkinColorView.setVisibility(View.GONE); }else if(checkedId == R.id.fragment_beauty_btn_skincolor){ mSkinColorView.setVisibility(View.VISIBLE); mSkinSmoothView.setVisibility(View.GONE); } } }); mSmoothBubbleSeekBar = (BubbleSeekBar) view.findViewById(R.id.fragment_beauty_skin_seekbar); mSmoothBubbleSeekBar.setOnBubbleSeekBarChangeListener(mOnSmoothBubbleSeekBarChangeListener); mWhiteBubbleSeekBar = (BubbleSeekBar) view.findViewById(R.id.fragment_beauty_white_seekbar); mWhiteBubbleSeekBar.setOnBubbleSeekBarChangeListener(mOnColorBubbleSeekBarChangeListener); init(); super.onViewCreated(view, savedInstanceState); } private void init(){ MagicEngine.getInstance().initBeauty(); } @Override public void onHiddenChanged(boolean hidden) { super.onHiddenChanged(hidden); if(!hidden){ mSmoothBubbleSeekBar.setProgress(0); mWhiteBubbleSeekBar.setProgress(0); init(); }else{ MagicEngine.getInstance().uninitBeauty(); isWhiten = false; isSmoothed = false; } } private BubbleSeekBar.OnBubbleSeekBarChangeListener mOnSmoothBubbleSeekBarChangeListener = new BubbleSeekBar.OnBubbleSeekBarChangeListener() { @Override public void onStopTrackingTouch(final SeekBar seekBar) { new Thread(new Runnable() { @Override public void run() { float level = seekBar.getProgress() / 10.0f; if(level < 0) level = 0; MagicEngine.getInstance().setSkinSmooth(level); if(seekBar.getProgress() != 0) isSmoothed = true; else isSmoothed = false; } }).start(); } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { } }; private BubbleSeekBar.OnBubbleSeekBarChangeListener mOnColorBubbleSeekBarChangeListener = new BubbleSeekBar.OnBubbleSeekBarChangeListener() { @Override public void onStopTrackingTouch(SeekBar seekBar) { float level = seekBar.getProgress() / 20.0f; if(level < 1) level = 1; MagicEngine.getInstance().setWhiteSkin(level); if(seekBar.getProgress() != 0) isWhiten = true; else isWhiten = false; } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { } }; @Override protected boolean isChanged() { return isWhiten || isSmoothed; } @Override protected void onDialogButtonClick() { super.onDialogButtonClick(); MagicEngine.getInstance().uninitBeauty(); } } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/view/edit/filter/ImageEditFilterView.java ================================================ package com.zero.magicshow.view.edit.filter; import android.os.Bundle; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import com.zero.magicshow.R; import com.zero.magicshow.adapter.FilterAdapter; import com.zero.magicshow.common.utils.Constants; import com.zero.magicshow.core.MagicEngine; import com.zero.magicshow.core.filter.utils.MagicFilterType; import com.zero.magicshow.view.edit.ImageEditFragment; public class ImageEditFilterView extends ImageEditFragment { private RecyclerView recyclerView; private View rootView; private ImageView btnClose,btnFavourite; private FilterAdapter filterAdapter; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { rootView = inflater.inflate(R.layout.fragment_image_edit_filter, container, false); return rootView; } @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onCreate(savedInstanceState); init(); } private void init(){ initView(); initData(); initListener(); } private void initView(){ recyclerView = (RecyclerView)rootView.findViewById(R.id.image_edit_filter_recyclerview); btnClose = (ImageView)rootView.findViewById(R.id.image_edit_filter_close); btnFavourite = (ImageView)rootView.findViewById(R.id.image_edit_filter_favourite); } private void initData(){ LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext()); linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); recyclerView.setLayoutManager(linearLayoutManager); filterAdapter = new FilterAdapter(getContext(), Constants.FILTER_TYPES); recyclerView.setAdapter(filterAdapter); filterAdapter.setOnFilterChangeListener(onFilterChangeListener); } private void initListener(){ btnClose.setOnClickListener(onClickListener); btnFavourite.setOnClickListener(onClickListener); } @Override public void onHiddenChanged(boolean hidden) { if(!hidden){ filterAdapter.refreshList(); } } @Override protected boolean isChanged() { return MagicEngine.getInstance().getFilterType() != MagicFilterType.NONE; } private FilterAdapter.onFilterChangeListener onFilterChangeListener = new FilterAdapter.onFilterChangeListener(){ @Override public void onFilterChanged(MagicFilterType filterType) { // magicEngine.setFilter(filterType); MagicEngine.getInstance().setFilter(filterType); } }; private void doCloseAction(){ } private void doFavouriteAction(){ } private View.OnClickListener onClickListener = new View.OnClickListener() { @Override public void onClick(View v) { if(v == btnClose){ doCloseAction(); }else if(v == btnFavourite){ doFavouriteAction(); } } }; } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/view/edit/iface/ImageEditNavListener.java ================================================ package com.zero.magicshow.view.edit.iface; import android.view.View; /** * Created by hongli on 2017/8/22. */ public interface ImageEditNavListener { public void onClick(View view, String type); } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/view/edit/navigation/ImageEditNavigationView.java ================================================ package com.zero.magicshow.view.edit.navigation; import android.content.Context; import android.support.annotation.Nullable; import android.util.AttributeSet; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import com.zero.magicshow.R; import com.zero.magicshow.view.edit.iface.ImageEditNavListener; import com.zero.zerolib.util.BaseUtil; /** * Created by hongli on 2017/8/22. */ public class ImageEditNavigationView extends LinearLayout{ private ImageView ivIcon; private TextView tvName; private ImageEditNavListener imageEditNavListener; private String type;//导航类型 private ImageEditNavigationView(Context context) { super(context); init(); } public ImageEditNavigationView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(); } public ImageEditNavigationView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init(){ initView(); initData(); initListener(); } private void initView(){ ivIcon = new ImageView(getContext()); this.addView(ivIcon); tvName = new TextView(getContext()); this.addView(tvName); } private void initData(){ LayoutParams iconParam = new LayoutParams(BaseUtil.dipToPix(getContext(),25), BaseUtil.dipToPix(getContext(),25)); iconParam.gravity = Gravity.CENTER; ivIcon.setLayoutParams(iconParam); ivIcon.setScaleType(ImageView.ScaleType.FIT_XY); LayoutParams nameParam = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, BaseUtil.dipToPix(getContext(),25)); nameParam.gravity = Gravity.CENTER; tvName.setLayoutParams(nameParam); tvName.setText(getResources().getString(R.string.edit_edit)); tvName.setTextSize(14); tvName.setTextColor(getResources().getColor(R.color.selector_image_edit)); tvName.setGravity(Gravity.CENTER); LayoutParams rootParam = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); rootParam.weight = 1; this.setLayoutParams(rootParam); this.setPadding(0,BaseUtil.dipToPix(getContext(),10),0,BaseUtil.dipToPix(getContext(),10)); this.setOrientation(LinearLayout.VERTICAL); } private void initListener(){ this.setOnClickListener(onClickListener); } public static ImageEditNavigationView builder(Context context){ return new ImageEditNavigationView(context); } public ImageEditNavigationView setType(String type){ this.type = type; return this; } public ImageEditNavigationView setName(String name){ tvName.setText(name); return this; } public ImageEditNavigationView setIconRes(int resId){ // ivIcon.setImageResource(resId); ivIcon.setBackgroundResource(resId); return this; } public ImageEditNavigationView setListener(ImageEditNavListener imageEditNavListener){ this.imageEditNavListener = imageEditNavListener; return this; } private OnClickListener onClickListener = new OnClickListener() { @Override public void onClick(View v) { if(null != imageEditNavListener){ imageEditNavListener.onClick(v,type); } } }; } ================================================ FILE: MagicShow/src/main/java/com/zero/magicshow/viewmanager/CameraManager.java ================================================ package com.zero.magicshow.viewmanager; import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.widget.ImageView; /** * Created by hongli on 2017/9/1. */ public class CameraManager { public static ObjectAnimator getShutterAnim(ImageView btnShutter){ ObjectAnimator animator = ObjectAnimator.ofFloat(btnShutter,"rotation",0,360); animator.setDuration(500); animator.setRepeatCount(ValueAnimator.INFINITE); return animator; } } ================================================ FILE: MagicShow/src/main/res/anim/bottom_sliding_in.xml ================================================ ================================================ FILE: MagicShow/src/main/res/anim/bottom_sliding_out.xml ================================================ ================================================ FILE: MagicShow/src/main/res/color/selector_image_back.xml ================================================ ================================================ FILE: MagicShow/src/main/res/color/selector_image_edit.xml ================================================ ================================================ FILE: MagicShow/src/main/res/color/selector_image_edit_yellow.xml ================================================ ================================================ FILE: MagicShow/src/main/res/drawable/btn_camera_beauty.xml ================================================ ================================================ FILE: MagicShow/src/main/res/drawable/btn_camera_filter.xml ================================================ ================================================ FILE: MagicShow/src/main/res/drawable/btn_camera_shutter.xml ================================================ ================================================ FILE: MagicShow/src/main/res/drawable/btn_layout_filters_bar_close.xml ================================================ ================================================ FILE: MagicShow/src/main/res/drawable/corners_yuanjiao_dialog.xml ================================================ ================================================ FILE: MagicShow/src/main/res/drawable/seekbar_progress.xml ================================================ ================================================ FILE: MagicShow/src/main/res/drawable/seekbar_progress_light.xml ================================================ ================================================ FILE: MagicShow/src/main/res/drawable/seekbar_thumb.xml ================================================ ================================================ FILE: MagicShow/src/main/res/drawable/seekbar_thumb_light.xml ================================================ ================================================ FILE: MagicShow/src/main/res/drawable/selector_filter_favorite_btn.xml ================================================ ================================================ FILE: MagicShow/src/main/res/drawable/selector_filter_selected.xml ================================================ ================================================ FILE: MagicShow/src/main/res/drawable/selector_image_adds.xml ================================================ ================================================ FILE: MagicShow/src/main/res/drawable/selector_image_back.xml ================================================ ================================================ FILE: MagicShow/src/main/res/drawable/selector_image_beauty.xml ================================================ ================================================ FILE: MagicShow/src/main/res/drawable/selector_image_edit.xml ================================================ ================================================ FILE: MagicShow/src/main/res/drawable/selector_image_edit_adjust_bright.xml ================================================ ================================================ FILE: MagicShow/src/main/res/drawable/selector_image_edit_adjust_contrast.xml ================================================ ================================================ FILE: MagicShow/src/main/res/drawable/selector_image_edit_adjust_exposure.xml ================================================ ================================================ FILE: MagicShow/src/main/res/drawable/selector_image_edit_adjust_hue.xml ================================================ ================================================ FILE: MagicShow/src/main/res/drawable/selector_image_edit_adjust_saturation.xml ================================================ ================================================ FILE: MagicShow/src/main/res/drawable/selector_image_edit_adjust_sharpness.xml ================================================ ================================================ FILE: MagicShow/src/main/res/drawable/selector_image_edit_adjust_vibrance.xml ================================================ ================================================ FILE: MagicShow/src/main/res/drawable/selector_image_filter.xml ================================================ ================================================ FILE: MagicShow/src/main/res/drawable/selector_image_fragment_skin.xml ================================================ ================================================ FILE: MagicShow/src/main/res/drawable/selector_image_frame.xml ================================================ ================================================ FILE: MagicShow/src/main/res/drawable/selector_image_save.xml ================================================ ================================================ FILE: MagicShow/src/main/res/drawable/selector_rewardcamera.xml ================================================ ================================================ FILE: MagicShow/src/main/res/drawable/take_filter_favorite_btn.xml ================================================ ================================================ FILE: MagicShow/src/main/res/layout/activity_camera.xml ================================================ ================================================ FILE: MagicShow/src/main/res/layout/activity_image.xml ================================================ ================================================ FILE: MagicShow/src/main/res/layout/activity_main.xml ================================================