Android filters based on OpenGL (idea from GPUImage for iOS)

Overview

GPUImage for Android

License Download Maven Central Build Status

Idea from: iOS GPUImage framework

Goal is to have something as similar to GPUImage as possible. Vertex and fragment shaders are exactly the same. That way it makes it easier to port filters from GPUImage iOS to Android.

Requirements

  • Android 2.2 or higher (OpenGL ES 2.0)

Usage

Gradle dependency

repositories {
    mavenCentral()
}

dependencies {
    implementation 'jp.co.cyberagent.android:gpuimage:2.x.x'
}

Sample Code

With preview:

Java:

@Override
public void onCreate(final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity);

    Uri imageUri = ...;
    gpuImage = new GPUImage(this);
    gpuImage.setGLSurfaceView((GLSurfaceView) findViewById(R.id.surfaceView));
    gpuImage.setImage(imageUri); // this loads image on the current thread, should be run in a thread
    gpuImage.setFilter(new GPUImageSepiaFilter());

    // Later when image should be saved saved:
    gpuImage.saveToPictures("GPUImage", "ImageWithFilter.jpg", null);
}

Kotlin:

public override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_gallery)

    val imageUri: Uri = ...
    gpuImage = GPUImage(this)
    gpuImage.setGLSurfaceView(findViewById<GLSurfaceView>(R.id.surfaceView))
    gpuImage.setImage(imageUri) // this loads image on the current thread, should be run in a thread
    gpuImage.setFilter(GPUImageSepiaFilter())

    // Later when image should be saved saved:
    gpuImage.saveToPictures("GPUImage", "ImageWithFilter.jpg", null)
}

Using GPUImageView

<jp.co.cyberagent.android.gpuimage.GPUImageView
    android:id="@+id/gpuimageview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:gpuimage_show_loading="false"
    app:gpuimage_surface_type="texture_view" /> <!-- surface_view or texture_view -->

Java:

@Override
public void onCreate(final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity);

    Uri imageUri = ...;
    gpuImageView = findViewById(R.id.gpuimageview);
    gpuImageView.setImage(imageUri); // this loads image on the current thread, should be run in a thread
    gpuImageView.setFilter(new GPUImageSepiaFilter());

    // Later when image should be saved saved:
    gpuImageView.saveToPictures("GPUImage", "ImageWithFilter.jpg", null);
}

Kotlin:

public override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_gallery)

    val imageUri: Uri = ...
    gpuImageView = findViewById<GPUImageView>(R.id.gpuimageview)
    gpuImageView.setImage(imageUri) // this loads image on the current thread, should be run in a thread
    gpuImageView.setFilter(GPUImageSepiaFilter())

    // Later when image should be saved saved:
    gpuImageView.saveToPictures("GPUImage", "ImageWithFilter.jpg", null)
}

Without preview:

Java:

public void onCreate(final Bundle savedInstanceState) {
    public void onCreate(final Bundle savedInstanceState) {
    Uri imageUri = ...;
    gpuImage = new GPUImage(context);
    gpuImage.setFilter(new GPUImageSobelEdgeDetection());
    gpuImage.setImage(imageUri);
    gpuImage.saveToPictures("GPUImage", "ImageWithFilter.jpg", null);
}

Kotlin:

public override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_gallery)
    val imageUri: Uri = ...
    gpuImage = GPUImage(this)
    gpuImage.setFilter(GPUImageSepiaFilter())
    gpuImage.setImage(imageUri)
    gpuImage.saveToPictures("GPUImage", "ImageWithFilter.jpg", null)
}

Support status of GPUImage for iOS shaders

  • Saturation
  • Contrast
  • Brightness
  • Levels
  • Exposure
  • RGB
  • RGB Diation
  • Hue
  • White Balance
  • Monochrome
  • False Color
  • Sharpen
  • Unsharp Mask
  • Transform Operation
  • Crop
  • Gamma
  • Highlights and Shadows
  • Haze
  • Sepia Tone
  • Amatorka
  • Miss Etikate
  • Soft Elegance
  • Color Inversion
  • Solarize
  • Vibrance
  • Highlight and Shadow Tint
  • Luminance
  • Luminance Threshold
  • Average Color
  • Average Luminance
  • Average Luminance Threshold
  • Adaptive Threshold
  • Polar Pixellate
  • Pixellate
  • Polka Dot
  • Halftone
  • Crosshatch
  • Sobel Edge Detection
  • Prewitt Edge Detection
  • Canny Edge Detection
  • Threshold Sobel EdgeDetection
  • Harris Corner Detector
  • Noble Corner Detector
  • Shi Tomasi Feature Detector
  • Colour FAST Feature Detector
  • Low Pass Filter
  • High Pass Filter
  • Sketch Filter
  • Threshold Sketch Filter
  • Toon Filter
  • SmoothToon Filter
  • Tilt Shift
  • CGA Colorspace Filter
  • Posterize
  • Convolution 3x3
  • Emboss Filter
  • Laplacian
  • Chroma Keying
  • Kuwahara Filter
  • Kuwahara Radius3 Filter
  • Vignette
  • Gaussian Blur
  • Box Blur
  • Bilateral Blur
  • Motion Blur
  • Zoom Blur
  • iOS Blur
  • Median Filter
  • Swirl Distortion
  • Bulge Distortion
  • Pinch Distortion
  • Sphere Refraction
  • Glass Sphere Refraction
  • Stretch Distortion
  • Dilation
  • Erosion
  • Opening Filter
  • Closing Filter
  • Local Binary Pattern
  • Color Local Binary Pattern
  • Dissolve Blend
  • Chroma Key Blend
  • Add Blend
  • Divide Blend
  • Multiply Blend
  • Overlay Blend
  • Lighten Blend
  • Darken Blend
  • Color Burn Blend
  • Color Dodge Blend
  • Linear Burn Blend
  • Screen Blend
  • Difference Blend
  • Subtract Blend
  • Exclusion Blend
  • HardLight Blend
  • SoftLight Blend
  • Color Blend
  • Hue Blend
  • Saturation Blend
  • Luminosity Blend
  • Normal Blend
  • Source Over Blend
  • Alpha Blend
  • Non Maximum Suppression
  • Thresholded Non Maximum Suppression
  • Directional Non Maximum Suppression
  • Opacity
  • Weak Pixel Inclusion Filter
  • Color Matrix
  • Directional Sobel Edge Detection
  • Lookup
  • Tone Curve (*.acv files)

Others

  • Texture 3x3
  • Gray Scale

Gradle

Make sure that you run the clean target when using maven.

gradle clean assemble

License

Copyright 2018 CyberAgent, Inc.

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.
Comments
  • App crashes when the range changes quickly.

    App crashes when the range changes quickly.

    When the sample app is running, if you change the range quickly, sometimes the app will crash. I got the following adb messages:

    01-06 13:35:14.462 14995 15045 E AndroidRuntime: FATAL EXCEPTION: GLThread 4239 01-06 13:35:14.462 14995 15045 E AndroidRuntime: java.util.NoSuchElementException 01-06 13:35:14.462 14995 15045 E AndroidRuntime: at java.util.LinkedList.removeFirstImpl(LinkedList.java:689) 01-06 13:35:14.462 14995 15045 E AndroidRuntime: at java.util.LinkedList.removeFirst(LinkedList.java:676) 01-06 13:35:14.462 14995 15045 E AndroidRuntime: at jp.co.cyberagent.android.gpuimage.GPUImageFilter.runPendingOnDrawTasks(GPUImageFilter.java:127) 01-06 13:35:14.462 14995 15045 E AndroidRuntime: at jp.co.cyberagent.android.gpuimage.GPUImageFilter.onDraw(GPUImageFilter.java:102) 01-06 13:35:14.462 14995 15045 E AndroidRuntime: at jp.co.cyberagent.android.gpuimage.GPUImageFilterGroup.onDraw(GPUImageFilterGroup.java:158) 01-06 13:35:14.462 14995 15045 E AndroidRuntime: at jp.co.cyberagent.android.gpuimage.GPUImageRenderer.onDrawFrame(GPUImageRenderer.java:133) 01-06 13:35:14.462 14995 15045 E AndroidRuntime: at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1487) 01-06 13:35:14.462 14995 15045 E AndroidRuntime: at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1241) 01-06 13:35:14.472 744 1067 W ActivityManager: Force finishing activity jp.co.cyberagent.android.gpuimage.sample/.activity.ActivityCamera 01-06 13:35:14.492 666 15052 I libcamera: int android::CameraHardware::aeAfAwbThread(): previewaeafawb is waiting

    Looks like a synchronization issue?

    opened by swcai 16
  • Google Play 64-bit requirement

    Google Play 64-bit requirement

    Hi

    does this library support 64 bit?

    I use this library in my app when I upload the Android App Bundle, I get this message :

    image

    I have tried two versions 2.0.3 and 1.4.1 (since I can't see the libgpuimage-library.so in 2.0.3) .

    After analyzing the Android App Bundle :

    image

    here's my Gradle file :

    android {
            compileSdkVersion 29
            dexOptions {
                preDexLibraries = false
                javaMaxHeapSize "4g"
            }
            defaultConfig {
                applicationId "maa.abc"
                minSdkVersion 18
                targetSdkVersion 29
                versionCode 14
                versionName "1.2.0"
                multiDexEnabled true
                renderscriptTargetApi 28
                renderscriptSupportModeEnabled true
                testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
                ndk.abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64', 'armeabi', 'mips', 'mips64'
            }
            buildTypes {
                release {
                    minifyEnabled true
                    shrinkResources true
                    proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
                }
                debug {
                    minifyEnabled false
                    proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
                }
            }
            compileOptions {
                sourceCompatibility JavaVersion.VERSION_1_8
                targetCompatibility JavaVersion.VERSION_1_8
            }
            packagingOptions {
                exclude 'META-INF/DEPENDENCIES.txt'
                exclude 'META-INF/LICENSE.txt'
                exclude 'META-INF/NOTICE.txt'
                exclude 'META-INF/NOTICE'
                exclude 'META-INF/LICENSE'
                exclude 'META-INF/DEPENDENCIES'
                exclude 'META-INF/notice.txt'
                exclude 'META-INF/license.txt'
                exclude 'META-INF/dependencies.txt'
                exclude 'META-INF/LGPL2.annotations1'
            }
        }
    
        dependencies {
      implementation fileTree(dir: 'libs', include: ['*.jar'])
        implementation project(':appintro')
        /*ANDROID*/
        implementation 'androidx.appcompat:appcompat:1.0.2'
        implementation 'androidx.cardview:cardview:1.0.0'
        implementation 'androidx.exifinterface:exifinterface:1.0.0'
        implementation 'com.android.support:support-annotations:28.0.3'
        implementation 'androidx.legacy:legacy-support-v4:1.0.0'
        implementation 'androidx.multidex:multidex:2.0.1'
        annotationProcessor 'androidx.annotation:annotation:1.1.0'
        implementation 'androidx.recyclerview:recyclerview:1.0.0'
        implementation 'com.google.android.material:material:1.0.0'
        implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    
    
        /*PHOTO FILTERS (CONTAINS NATIVE CODE)*/
        implementation 'cn.ezandroid:EZFilter:2.0.9'
        implementation 'jp.co.cyberagent.android.gpuimage:gpuimage-library:1.4.1'
    
        /*ANIMATION*/
        implementation 'com.daimajia.easing:library:2.0@aar'
        implementation 'com.daimajia.androidanimations:library:2.3@aar'
    
        /*GLIDE*/
        annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0'
        implementation 'com.github.bumptech.glide:glide:4.9.0'
    
    
        /*PICK IMAGE /TAKE PICTURE*/
        implementation 'com.github.jkwiecien:EasyImage:1.3.1'
    
        /*TEST IMPLEMENTATION*/
        androidTestImplementation 'androidx.test:runner:1.2.0'
        androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
        testImplementation 'junit:junit:4.12'
    
    
        /*VIEWS*/
        implementation 'com.github.chrisbanes:PhotoView:2.3.0'
        implementation 'de.hdodenhof:circleimageview:3.0.0'
        implementation 'com.alexvasilkov:gesture-views:2.5.2'
        implementation('com.github.christophesmet:android_maskable_layout:v1.3.1') {
            exclude group: 'com.intellij', module: 'annotations'
        }
        implementation 'com.h6ah4i.android.widget.verticalseekbar:verticalseekbar:1.0.0'
        implementation 'com.github.duanhong169:checkerboarddrawable:1.0.2'
    
    
        /*FIREBASE*/
        implementation "com.google.firebase:firebase-core:17.0.1"
        implementation "com.google.firebase:firebase-storage:18.1.1"
        implementation 'com.google.firebase:firebase-database:18.0.1'
        implementation 'com.firebaseui:firebase-ui-database:5.0.0'
    
        /*HELPER*/
        implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.9'
        implementation 'org.apache.commons:commons-collections4:4.3'
        implementation 'com.github.nanchen2251:CompressHelper:1.0.5'
        implementation 'com.google.code.gson:gson:2.8.5'
        implementation(group: 'uz.shift', name: 'colorpicker', version: '0.5', ext: 'aar')
    
        /*CHANGING FONT*/
        implementation 'io.github.inflationx:viewpump:2.0.2'
        implementation 'io.github.inflationx:calligraphy3:3.1.1'
    }
    
    opened by Mouadabdelghafouraitali 7
  • Use GPUImageFilterGroup causes confusion in the background

    Use GPUImageFilterGroup causes confusion in the background

    When I use GPUImageFilterGroup, the background has a lot of clutter.

    The first time the set group does not have a problem,after the second time, the set group background is confused..

    I use ScaleType.CENTER_INSIDE

    GPUImageFilterGroup group = new GPUImageFilterGroup();
    group.addFilter(new GPUImageSaturationFilter(1.3f));
    group.addFilter(new GPUImageBrightnessFilter(0.2f));
    group.addFilter(new GPUImageContrastFilter(1.3f));
    group.addFilter(new GPUImageWhiteBalanceFilter(5000f,2f));
    surfaceView.setFilter(group);
    

    image

    opened by xiandanin 5
  • Image stretches and crops

    Image stretches and crops

    when i open either the gpuimage-sample,or my own project, smaller images just strech and crop wierdly, how to solve that?

    Trying CENTER_INSIDE scale type doesnt really work....

    1)Original image

    130411155624-lamborghini-dubai-police-4-horizontal-gallery 1

    2)Auto crop and zoomed image in GpuImageSample project

    screenshot_2013-06-28-10-28-09 1

    Thanks,

    Jeet

    opened by jeetdholakia 5
  • useDeprecatedNdk problem

    useDeprecatedNdk problem

    Hi,

    I get build error as:

    Error:Execution failed for task ':library:compileDebugNdk'.

    Error: Flag android.useDeprecatedNdk is no longer supported and will be removed in the next version of Android Studio. Please switch to a supported build system. Consider using CMake or ndk-build integration. For more information, go to: https://d.android.com/r/studio-ui/add-native-code.html#ndkCompile To get started, you can use the sample ndk-build script the Android plugin generated for you at: android-gpuimage-master/library/build/intermediates/ndk/debug/Android.mk Alternatively, you can use the experimental plugin: https://developer.android.com/r/tools/experimental-plugin.html To continue using the deprecated NDK compile for another 60 days, set android.deprecatedNdkCompileLease=1511898978137 in gradle.properties

    opened by oguzgu 4
  • Front Facing Camera Not Full screen

    Front Facing Camera Not Full screen

    jp.co.cyberagent.android.gpuimage.sample.activity.ActivityCamera

    Pls see the screen shot, the front camera is not full screen in some phones? Front cam renders in 1/4 of the screen and last frame of the back camera still in the view.

    screenshot_2016-09-21-15-00-23

    opened by deshan 4
  • Memory Leak Fix & onPictureSavedListener update

    Memory Leak Fix & onPictureSavedListener update

    I also encountered with this memory leak reported here and removed MediaScannerConnection from code and returns image file path instead of uri.

    If file requires to be displayed in gallery, below method can be used as well.

        public static void scanGallery(Activity activity, File modifiedFile) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                    Intent mediaScanIntent = new Intent(
                    Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
                    Uri contentUri = Uri.fromFile(modifiedFile);
                    mediaScanIntent.setData(contentUri);
                    activity.sendBroadcast(mediaScanIntent);
                } else {
                    activity.sendBroadcast(new Intent(
                            Intent.ACTION_MEDIA_MOUNTED,
                            Uri.parse("file://" + Environment.getExternalStorageDirectory())));
                }
        }
    
    opened by yayaa 4
  • Could not find an filter effect for the GPUImageTiltShiftFilter

    Could not find an filter effect for the GPUImageTiltShiftFilter

    I want to find a tilt shift filter effect for android,but I can not see a filter call GPUImageTiltShiftFilter for android which looks like GPUImageTiltShiftFilter for iphone.I try to write it but have the black color.Can you help me? Thanks!

    opened by chunfun 4
  • Question about persisting changes when switching effects

    Question about persisting changes when switching effects

    Hi everyone.

    In your example app the bitmap resets to the original when you switch filters. I'm able to persist changes to the bitmap by first exporting changes to a new bitmap and then setting that new bitmap as the image for the GPUImageView.

    Bitmap newBitmap = mGPUImage.getBitmapWithFilterApplied();          
    mGPUImageView.setImage(newBitmap);
    

    This method takes too much time (almost 1 second to execute) and I assume there must be a more efficient way to do this, maybe by using OpenGL functions. Anybody got an idea how to do this? Any help appreciated.

    opened by primary0 4
  • java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap

    java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap

    0   
    java.lang.RuntimeException: An error occured while executing doInBackground()
    1   
    at android.os.AsyncTask$3.done(AsyncTask.java:299)
    2   
    at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
    3   
    at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
    4   
    at java.util.concurrent.FutureTask.run(FutureTask.java:239)
    5   
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
    6   
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
    7   
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
    8   
    at java.lang.Thread.run(Thread.java:856)
    9   
    Caused by: java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@41e89060
    10  
    at android.graphics.Canvas.throwIfRecycled(Canvas.java:1026)
    11  
    at android.graphics.Canvas.drawBitmap(Canvas.java:1096)
    12  
    at android.graphics.Bitmap.createBitmap(Bitmap.java:617)
    13  
    at android.graphics.Bitmap.createBitmap(Bitmap.java:514)
    14  
    at jp.co.cyberagent.android.gpuimage.GPUImage$LoadImageTask.scaleBitmap(GPUImage.java:592)
    15  
    at jp.co.cyberagent.android.gpuimage.GPUImage$LoadImageTask.loadResizedImage(GPUImage.java:574)
    16  
    at jp.co.cyberagent.android.gpuimage.GPUImage$LoadImageTask.doInBackground(GPUImage.java:540)
    17  
    at jp.co.cyberagent.android.gpuimage.GPUImage$LoadImageTask.doInBackground(GPUImage.java:516)
    18  
    at android.os.AsyncTask$2.call(AsyncTask.java:287)
    19  
    at java.util.concurrent.FutureTask.run(FutureTask.java:234)
    20  
    ... 4 more
    21  
    java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@41e89060
    22  
    at android.graphics.Canvas.throwIfRecycled(Canvas.java:1026)
    23  
    at android.graphics.Canvas.drawBitmap(Canvas.java:1096)
    24  
    at android.graphics.Bitmap.createBitmap(Bitmap.java:617)
    25  
    at android.graphics.Bitmap.createBitmap(Bitmap.java:514)
    26  
    at jp.co.cyberagent.android.gpuimage.GPUImage$LoadImageTask.scaleBitmap(GPUImage.java:592)
    27  
    at jp.co.cyberagent.android.gpuimage.GPUImage$LoadImageTask.loadResizedImage(GPUImage.java:574)
    28  
    at jp.co.cyberagent.android.gpuimage.GPUImage$LoadImageTask.doInBackground(GPUImage.java:540)
    29  
    at jp.co.cyberagent.android.gpuimage.GPUImage$LoadImageTask.doInBackground(GPUImage.java:516)
    30  
    at android.os.AsyncTask$2.call(AsyncTask.java:287)
    31  
    at java.util.concurrent.FutureTask.run(FutureTask.java:234)
    32  
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
    33  
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
    34  
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
    35  
    at java.lang.Thread.run(Thread.java:856)
    

    From the SDK documentation http://developer.android.com/reference/android/graphics/Bitmap.html#createScaledBitmap(android.graphics.Bitmap, int, int, boolean):

    Creates a new bitmap, scaled from an existing bitmap, when possible. If the specified width and height are the same as the current width and height of the source btimap, the source bitmap is returned and now new bitmap is created.
    

    I think this error will be happen when the specified width and height are the same as the current width and height of the source bitmap.

    private Bitmap scaleBitmap(Bitmap bitmap) {
                // resize to desired dimensions
                int width = bitmap.getWidth();
                int height = bitmap.getHeight();
                int[] newSize = getScaleSize(width, height);
                Bitmap workBitmap = Bitmap.createScaledBitmap(bitmap, newSize[0], newSize[1], true);
                bitmap.recycle();
                bitmap = workBitmap;
                System.gc();
    
                if (mScaleType == ScaleType.CENTER_CROP) {
                    // Crop it
                    int diffWidth = newSize[0] - mOutputWidth;
                    int diffHeight = newSize[1] - mOutputHeight;
                    workBitmap = Bitmap.createBitmap(bitmap, diffWidth / 2, diffHeight / 2,
                            newSize[0] - diffWidth, newSize[1] - diffHeight);
                    bitmap.recycle();
                    bitmap = workBitmap;
                }
    
                return bitmap;
            }
    

    Should become this:

    private Bitmap scaleBitmap(Bitmap bitmap) {
                // resize to desired dimensions
                int width = bitmap.getWidth();
                int height = bitmap.getHeight();
                int[] newSize = getScaleSize(width, height);
                Bitmap workBitmap = Bitmap.createScaledBitmap(bitmap, newSize[0],
                        newSize[1], true);
                if (workBitmap != bitmap) {
                    bitmap.recycle();
                    bitmap = workBitmap;
                }
                System.gc();
    
                if (mScaleType == ScaleType.CENTER_CROP) {
                    // Crop it
                    int diffWidth = newSize[0] - mOutputWidth;
                    int diffHeight = newSize[1] - mOutputHeight;
                    workBitmap = Bitmap.createBitmap(bitmap, diffWidth / 2,
                            diffHeight / 2, newSize[0] - diffWidth, newSize[1]
                                    - diffHeight);
                    if (workBitmap != bitmap) {
                        bitmap.recycle();
                        bitmap = workBitmap;
                    }
                }
    
                return bitmap;
            }
    
    opened by rockerhieu 4
  • Build gpuimage library error, help me!

    Build gpuimage library error, help me!

    [INFO] Scanning for projects... [WARNING] [WARNING] Some problems were encountered while building the effective model for jp.co.cyberagent.android.gpuimage:gpuimage-library:apklib:1.0.3 [WARNING] 'build.plugins.plugin.(groupId:artifactId)' must be unique but found duplicate declaration of plugin com.jayway.maven.plugins.android.generation2:android-maven-plugin @ line 56, column 21 [WARNING] [WARNING] Some problems were encountered while building the effective model for jp.co.cyberagent.android.gpuimage:gpuimage-sample:apk:1.0.3 [WARNING] 'build.plugins.plugin.version' for org.apache.maven.plugins:maven-javadoc-plugin is missing. @ line 44, column 15 [WARNING] [WARNING] It is highly recommended to fix these problems because they threaten the stability of your build. [WARNING] [WARNING] For this reason, future Maven versions might no longer support building such malformed projects. [WARNING] [INFO] ------------------------------------------------------------------------ [INFO] Reactor Build Order: [INFO] [INFO] GPUImage for Android [INFO] GPUImage for Android Library [INFO] GPUImage Sample [INFO]
    [INFO] ------------------------------------------------------------------------ [INFO] Building GPUImage for Android 1.0.3 [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- maven-clean-plugin:2.4.1:clean (default-clean) @ gpuimage-parent --- [INFO] [INFO] --- maven-enforcer-plugin:1.0:enforce (enforce-maven) @ gpuimage-parent --- [INFO] [INFO] --- maven-install-plugin:2.3.1:install (default-install) @ gpuimage-parent --- [INFO] Installing C:\Program Files\android-gpuimage-master\pom.xml to C:\Users\yang_shuai.CCWLAB.m2\repository\jp\co\cyberagent\android\gpuimage\gpuimage-parent\1.0.3\gpuimage-parent-1.0.3.pom [INFO]
    [INFO] ------------------------------------------------------------------------ [INFO] Building GPUImage for Android Library 1.0.3 [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- maven-clean-plugin:2.4.1:clean (default-clean) @ gpuimage-library --- [INFO] Deleting C:\Program Files\android-gpuimage-master\library\target [INFO] [INFO] --- maven-enforcer-plugin:1.0:enforce (enforce-maven) @ gpuimage-library --- [INFO] [INFO] --- android-maven-plugin:3.2.0:generate-sources (default-generate-sources) @ gpuimage-library --- [INFO] ANDROID-904-002: Found aidl files: Count = 0 [INFO] ANDROID-904-002: Found aidl files: Count = 0 [INFO] C:\Program Files\adt-bundle-windows-x86\sdk\platform-tools\aapt.exe [package, -m, -J, C:\Program Files\android-gpuimage-master\library\target\generated-sources\r, -M, C:\Program Files\android-gpuimage-master\library\AndroidManifest.xml, -S, C:\Program Files\android-gpuimage-master\library\res, --auto-add-overlay, -I, C:\Program Files\adt-bundle-windows-x86\sdk\platforms\android-17\android.jar] [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ gpuimage-library --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] skip non existing resourceDirectory C:\Program Files\android-gpuimage-master\library\src\main\resources [INFO] skip non existing resourceDirectory C:\Program Files\android-gpuimage-master\library\target\generated-sources\extracted-dependencies\src\main\resources [INFO] [INFO] --- maven-compiler-plugin:2.3.2:compile (default-compile) @ gpuimage-library --- [INFO] Compiling 20 source files to C:\Program Files\android-gpuimage-master\library\target\classes [INFO] [INFO] --- android-maven-plugin:3.2.0:ndk-build (default) @ gpuimage-library --- [INFO] C:\android-ndk-r8d\ndk-build [-C, C:\Program Files\android-gpuimage-master\library, gpuimage-library] make: Entering directory C:/Program Files/android-gpuimage-master/library' [INFO] C:/android-ndk-r8d/build/core/add-application.mk:128: Android NDK: WARNING: APP_PLATFORM android-14 is larger than android:minSdkVersion 8 in ./AndroidManifest.xml make: Nothing to be done forgpuimage-library'. make: Leaving directory `C:/Program Files/android-gpuimage-master/library' [INFO] ------------------------------------------------------------------------ [INFO] Reactor Summary: [INFO] [INFO] GPUImage for Android .............................. SUCCESS [0.796s] [INFO] GPUImage for Android Library ...................... FAILURE [3.561s] [INFO] GPUImage Sample ................................... SKIPPED [INFO] ------------------------------------------------------------------------ [INFO] BUILD FAILURE [INFO] ------------------------------------------------------------------------ [INFO] Total time: 5.357s [INFO] Finished at: Wed Dec 26 14:14:53 CST 2012 [INFO] Final Memory: 11M/21M [INFO] ------------------------------------------------------------------------ [ERROR] Failed to execute goal com.jayway.maven.plugins.android.generation2:android-maven-plugin:3.2.0:ndk-build (default) on project gpuimage-library: ANDROID-040-001: Could not execute: Command = cmd.exe /X /C "C:\android-ndk-r8d\ndk-build -C "C:\Program Files\android-gpuimage-master\library" gpuimage-library", Result = 0 -> [Help 1] [ERROR] [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch. [ERROR] Re-run Maven using the -X switch to enable full debug logging. [ERROR] [ERROR] For more information about the errors and possible solutions, please read the following articles: [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException [ERROR] [ERROR] After correcting the problems, you can resume the build with the command [ERROR] mvn -rf :gpuimage-library

    opened by dotyso 4
  • Missing argument checks in native code

    Missing argument checks in native code

    Bug Reporting

    Hi,

    I found that the implementations of YUVtoRBGA and YUVtoARBG in native code do not check the sizes of the input and output arrays. See here: https://github.com/cats-oss/android-gpuimage/blob/master/library/src/main/cpp/yuv-decoder.c#L28 https://github.com/cats-oss/android-gpuimage/blob/master/library/src/main/cpp/yuv-decoder.c#L87

    When a user provides incorrect width or height arguments, this can lead to an OOB array access, which may terminate the app with a SIGSEGV.

    I'm working on a fix and will open a pull request once finished.

    Steps to Reproduce

    Call GPUImageNativeLibrary.YUVtoARBG(yuv, width, height, output) with buffers that are smaller than width*height.

    Actual Results

    The app crashes with SIGSEGV

    Expected Results

    No crash

    OS details

    • Device: Redroid on Arm64
    • OS: Android 11
    opened by fab1ano 0
  • capture

    capture

    Future Task

    What is the motivation?

    What kind of solution can be considered?

    What do you want to discuss?

    Please add relevant labels


    Bug Reporting

    Steps to Reproduce

    Actual Results (include screenshots)

    Expected Results (include screenshots)

    URL

    OS details

    • Device:
    • OS:

    Please add relevant labels

    opened by happysir 0
  • GPUImageSharpenFilter is different compare to CISharpenLuminance from iOS

    GPUImageSharpenFilter is different compare to CISharpenLuminance from iOS

    Hello I am trying to achieve a filter effect similar to iOS SharpenLuminescence:

    extension SharpenLuminescence {
      func filter(_ image: CIImage) -> CIImage {
        image.applyingFilter(
          "CISharpenLuminance",
          parameters: [
            kCIInputSharpnessKey: sharpness,
            kCIInputRadiusKey: radius,
          ]
        )
      }
    }
    

    Using GPUImageSharpenFilter I am getting different results, any idea why and how to achieve a similar effect to iOS?

    The left side photo is from ios, radius 20 sharpen 2, the right site is an image with GPUImageSharpenFilter applied.

    Screenshot 2022-04-20 at 20 25 39
    opened by 8kt8 0
  • Why does GLTextureView's render thread  is not constructed on handler thread

    Why does GLTextureView's render thread is not constructed on handler thread

    Future Task

    Why does GLTextureView's render thread is not constructed on handler thread

    What is the motivation?

    I'm trying use GLTextureView to render some custom shader. There is some 'shaking' effect when it render continuously. It seem's that the sync signal between GLTextureView and Android's vsync and renderthread do not work properly.

    What kind of solution can be considered?

    Could this be solved by add choreographer to GLTextureView's render thread, and sync every frame by choreographer's callback? Why does GLTextureView use thread directly other than handler thread in the first time ?

    Please add relevant labels GLTextureView RenderThread HandlerThread

    opened by Neilcc 0
  • crash while switching camera on huawei mate30(android 10)

    crash while switching camera on huawei mate30(android 10)

    2022-01-06 16:18:24 32072-32072/? A/DEBUG: backtrace: 2022-01-06 16:18:24 32072-32072/? A/DEBUG: #00 pc 00000000003e7294 /apex/com.android.runtime/lib64/libart.so (art::JNI::GetPrimitiveArrayCritical(_JNIEnv*, _jarray*, unsigned char*)+612) (BuildId: 5507e0405072e431616851bd75037326) 2022-01-06 16:18:24 32072-32072/? A/DEBUG: #01 pc 0000000000000944 /data/app/com.sdfwq.videoeffects-Ykn3zRtlfNRtABX6QOBalA==/lib/arm64/libyuv-decoder.so (Java_jp_co_cyberagent_android_gpuimage_GPUImageNativeLibrary_YUVtoRBGA+88) (BuildId: f7739d3957210f5c0d34829e8ddf12f08dfbdbd8) 2022-01-06 16:18:24 32072-32072/? A/DEBUG: #02 pc 000000000014d350 /apex/com.android.runtime/lib64/libart.so (art_quick_generic_jni_trampoline+144) (BuildId: 5507e0405072e431616851bd75037326) 2022-01-06 16:18:24 32072-32072/? A/DEBUG: #03 pc 00000000001445b8 /apex/com.android.runtime/lib64/libart.so (art_quick_invoke_static_stub+568) (BuildId: 5507e0405072e431616851bd75037326) 2022-01-06 16:18:24 32072-32072/? A/DEBUG: #04 pc 00000000001531c4 /apex/com.android.runtime/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+284) (BuildId: 5507e0405072e431616851bd75037326) 2022-01-06 16:18:24 32072-32072/? A/DEBUG: #05 pc 00000000002eed0c /apex/com.android.runtime/lib64/libart.so (art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, art::ShadowFrame*, unsigned short, art::JValue*)+384) (BuildId: 5507e0405072e431616851bd75037326) 2022-01-06 16:18:24 32072-32072/? A/DEBUG: #06 pc 00000000002e9fdc /apex/com.android.runtime/lib64/libart.so (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+912) (BuildId: 5507e0405072e431616851bd75037326) 2022-01-06 16:18:24 32072-32072/? A/DEBUG: #07 pc 00000000005bdc94 /apex/com.android.runtime/lib64/libart.so (MterpInvokeStatic+368) (BuildId: 5507e0405072e431616851bd75037326) 2022-01-06 16:18:24 32072-32072/? A/DEBUG: #08 pc 000000000013e994 /apex/com.android.runtime/lib64/libart.so (mterp_op_invoke_static+20) (BuildId: 5507e0405072e431616851bd75037326) 2022-01-06 16:18:24 32072-32072/? A/DEBUG: #09 pc 000000000055ef2c anonymous:78f6438000 (㒘.Ⱍ.Ⱍ.Ⱍ.Ⱍ.䀔$Ⱍ.run+32) 2022-01-06 16:18:24 32072-32072/? A/DEBUG: #10 pc 00000000005bcbec /apex/com.android.runtime/lib64/libart.so (MterpInvokeInterface+1752) (BuildId: 5507e0405072e431616851bd75037326) 2022-01-06 16:18:24 32072-32072/? A/DEBUG: #11 pc 000000000013ea14 /apex/com.android.runtime/lib64/libart.so (mterp_op_invoke_interface+20) (BuildId: 5507e0405072e431616851bd75037326) 2022-01-06 16:18:24 32072-32072/? A/DEBUG: #12 pc 000000000055f31a anonymous:78f6438000 (㒘.Ⱍ.Ⱍ.Ⱍ.Ⱍ.䀔.ҵ+26) 2022-01-06 16:18:24 32072-32072/? A/DEBUG: #13 pc 00000000002bf948 /apex/com.android.runtime/lib64/libart.so (_ZN3art11interpreterL7ExecuteEPNS_6ThreadERKNS_20CodeItemDataAccessorERNS_11ShadowFrameENS_6JValueEbb.llvm.4040658722762997890+240) (BuildId: 5507e0405072e431616851bd75037326) 2022-01-06 16:18:24 32072-32072/? A/DEBUG: #14 pc 00000000005a62c8 /apex/com.android.runtime/lib64/libart.so (artQuickToInterpreterBridge+1012) (BuildId: 5507e0405072e431616851bd75037326) 2022-01-06 16:18:24 32072-32072/? A/DEBUG: #15 pc 000000000014d468 /apex/com.android.runtime/lib64/libart.so (art_quick_to_interpreter_bridge+88) (BuildId: 5507e0405072e431616851bd75037326) 2022-01-06 16:18:24 32072-32072/? A/DEBUG: #16 pc 000000000200d0e0 /memfd:/jit-cache (deleted) (㒘.Ⱍ.Ⱍ.Ⱍ.Ⱍ.䀔.onDrawFrame+80) 2022-01-06 16:18:24 32072-32072/? A/DEBUG: #17 pc 0000000000144334 /apex/com.android.runtime/lib64/libart.so (art_quick_invoke_stub+548) (BuildId: 5507e0405072e431616851bd75037326) 2022-01-06 16:18:24 32072-32072/? A/DEBUG: #18 pc 00000000001531a4 /apex/com.android.runtime/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+252) (BuildId: 5507e0405072e431616851bd75037326) 2022-01-06 16:18:24 32072-32072/? A/DEBUG: #19 pc 00000000002eed0c /apex/com.android.runtime/lib64/libart.so (art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, art::ShadowFrame*, unsigned short, art::JValue*)+384) (BuildId: 5507e0405072e431616851bd75037326) 2022-01-06 16:18:24 32072-32072/? A/DEBUG: #20 pc 00000000002e9fdc /apex/com.android.runtime/lib64/libart.so (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+912) (BuildId: 5507e0405072e431616851bd75037326) 2022-01-06 16:18:24 32072-32072/? A/DEBUG: #21 pc 00000000005bc888 /apex/com.android.runtime/lib64/libart.so (MterpInvokeInterface+884) (BuildId: 5507e0405072e431616851bd75037326) 2022-01-06 16:18:24 32072-32072/? A/DEBUG: #22 pc 000000000013ea14 /apex/com.android.runtime/lib64/libart.so (mterp_op_invoke_interface+20) (BuildId: 5507e0405072e431616851bd75037326) 2022-01-06 16:18:24 32072-32072/? A/DEBUG: #23 pc 00000000002fc55a /system/framework/framework.jar (android.opengl.GLSurfaceView$GLThread.guardedRun+1086) 2022-01-06 16:18:24 32072-32072/? A/DEBUG: #24 pc 00000000005bd788 /apex/com.android.runtime/lib64/libart.so (MterpInvokeDirect+1168) (BuildId: 5507e0405072e431616851bd75037326) 2022-01-06 16:18:24 32072-32072/? A/DEBUG: #25 pc 000000000013e914 /apex/com.android.runtime/lib64/libart.so (mterp_op_invoke_direct+20) (BuildId: 5507e0405072e431616851bd75037326) 2022-01-06 16:18:24 32072-32072/? A/DEBUG: #26 pc 00000000002fcb54 /system/framework/framework.jar (android.opengl.GLSurfaceView$GLThread.run+48) 2022-01-06 16:18:24 32072-32072/? A/DEBUG: #27 pc 00000000002bf948 /apex/com.android.runtime/lib64/libart.so (_ZN3art11interpreterL7ExecuteEPNS_6ThreadERKNS_20CodeItemDataAccessorERNS_11ShadowFrameENS_6JValueEbb.llvm.4040658722762997890+240) (BuildId: 5507e0405072e431616851bd75037326) 2022-01-06 16:18:24 32072-32072/? A/DEBUG: #28 pc 00000000005a62c8 /apex/com.android.runtime/lib64/libart.so (artQuickToInterpreterBridge+1012) (BuildId: 5507e0405072e431616851bd75037326) 2022-01-06 16:18:24 32072-32072/? A/DEBUG: #29 pc 000000000014d468 /apex/com.android.runtime/lib64/libart.so (art_quick_to_interpreter_bridge+88) (BuildId: 5507e0405072e431616851bd75037326) 2022-01-06 16:18:24 32072-32072/? A/DEBUG: #30 pc 0000000000144334 /apex/com.android.runtime/lib64/libart.so (art_quick_invoke_stub+548) (BuildId: 5507e0405072e431616851bd75037326) 2022-01-06 16:18:24 32072-32072/? A/DEBUG: #31 pc 00000000001531a4 /apex/com.android.runtime/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+252) (BuildId: 5507e0405072e431616851bd75037326) 2022-01-06 16:18:24 32072-32072/? A/DEBUG: #32 pc 00000000004c6d18 /apex/com.android.runtime/lib64/libart.so (art::(anonymous namespace)::InvokeWithArgArray(art::ScopedObjectAccessAlreadyRunnable const&, art::ArtMethod*, art::(anonymous namespace)::ArgArray*, art::JValue*, char const*)+104) (BuildId: 5507e0405072e431616851bd75037326) 2022-01-06 16:18:24 32072-32072/? A/DEBUG: #33 pc 00000000004c7dac /apex/com.android.runtime/lib64/libart.so (art::InvokeVirtualOrInterfaceWithJValues(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jmethodID*, jvalue const*)+416) (BuildId: 5507e0405072e431616851bd75037326) 2022-01-06 16:18:24 32072-32072/? A/DEBUG: #34 pc 0000000000507d7c /apex/com.android.runtime/lib64/libart.so (art::Thread::CreateCallback(void*)+1176) (BuildId: 5507e0405072e431616851bd75037326) 2022-01-06 16:18:24 32072-32072/? A/DEBUG: #35 pc 00000000000ce1b0 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+36) (BuildId: 95e03d8a9f101c0f1d3d9458688aa085) 2022-01-06 16:18:24 32072-32072/? A/DEBUG: #36 pc 0000000000070ba8 /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: 95e03d8a9f101c0f1d3d9458688aa085)

    opened by ivorita 0
Owner
CATS Open Source Softwares
OSS from CATS ( CyberAgent Advanced Technology Studio ).
CATS Open Source Softwares
🔥 Android OpenGL Camera 2.0 实现 30 种滤镜和抖音特效

OpenGLCamera2 Android OpenGL Camera 2.0 项目使用 OpenGL ES 3.0 实现 30 种相机滤镜和特效,支持相机预览和拍照,左右滑动切换滤镜。 对 OpenGL ES 3.0 不熟悉的同学可以移步 Android OpenGLES 3.0 开发系统性学习教

字节流动 794 Dec 23, 2022
OpenGLES - an embedded version of the OpenGL cross-platform API which is used to render 2D/3D texture

OpenGLES is an embedded version of the OpenGL cross-platform API which is used to render 2D/3D texture. This sample code contains the implementation of shape rendering using OpenGLES.

MindInventory 5 Sep 20, 2022
An image board client based on Gelbooru for android, made from Jetpack Compose 🚀 .

Mejiboard An image board client based on Gelbooru for android, made from Jetpack Compose ?? . Features Material Design UI Easy one-handed operation Li

Agung Watanabe 59 Dec 30, 2022
An Android library for scanning documents based on CameraX API and a tiny version of OpenCV

Document Scanner with tiny OpenCV example1.mp4 Document Scanner is an Android library (kotlin based) for scanning documents based on CameraX API and a

null 8 May 12, 2022
Pixel Boom is a Java-based Android software, featuring image super-resolution and colorization

Pixel Boom is a Java-based Android software, featuring image super-resolution and colorization.

Zaitian 1 Jul 3, 2022
Phimp.me Android Phimp.me is an Android image editor app

Phimp.me Android Phimp.me is an Android image editor app that aims to replace proprietary photographing and image apps on smart phones. It offers feat

FOSSASIA 2.6k Jan 6, 2023
Opencv Android SDK application for Deep Neural Networks to run on Android.

This application allows you to deploy deep nets in Android environment using OpenCV Android SDK. With OpenCV, images are taken from the camera on your phone, and then these images are passed through the neural network and visualized on the front side. In this application, we will search for faces in the images taken and draw the found faces on the screen.

Ahmet Furkan DEMIR 10 Nov 1, 2022
Android library project for cropping images

I guess people are just cropping out all the sadness An Android library project that provides a simple image cropping Activity, based on code from AOS

Jamie McDonald 4.5k Jan 7, 2023
Custom view for circular images in Android while maintaining the best draw performance

CircularImageView Custom view for circular images in Android while maintaining the best draw performance Usage To make a circular ImageView, add this

Pkmmte Xeleon 1.2k Dec 28, 2022
An android image compression library.

Compressor Compressor is a lightweight and powerful android image compression library. Compressor will allow you to compress large photos into smaller

Zetra 6.7k Dec 31, 2022
Custom shaped android imageview components

Shape Image View Provides a set of custom shaped android imageview components, and a framework to define more shapes. Implements both shader and bitma

Siyamed SINIR 2.6k Jan 3, 2023
Android widget for cropping and rotating an image.

Cropper The Cropper is an image cropping tool. It provides a way to set an image in XML and programmatically, and displays a resizable crop window on

Edmodo 2.9k Nov 14, 2022
A simple image cropping library for Android.

SimpleCropView The SimpleCropView is an image cropping library for Android. It simplifies your code for cropping image and provides an easily customiz

Issei Aoki 2.5k Dec 28, 2022
Customizable Android full screen image viewer for Fresco library supporting "pinch to zoom" and "swipe to dismiss" gestures. Made by Stfalcon

This project is no longer supported. If you're able to switch from Fresco to any other library that works with the Android's ImageView, please migrate

Stfalcon LLC 1.8k Dec 19, 2022
Dali is an image blur library for Android. It contains several modules for static blurring, live blurring and animations.

Dali Dali is an image blur library for Android. It is easy to use, fast and extensible. Dali contains several modules for either static blurring, live

Patrick Favre-Bulle 1k Dec 1, 2022
An image resizing library for Android

Resizer Inspired by zetbaitsu's Compressor, Resizer is a lightweight and easy-to-use Android library for image scaling. It allows you to resize an ima

Kakit Ho 426 Dec 22, 2022
Photo picker library for android. Let's you pick photos directly from files, or navigate to camera or gallery.

ChiliPhotoPicker Made with ❤️ by Chili Labs. Library made without DataBinding, RxJava and image loading libraries, to give you opportunity to use it w

Chili Labs 394 Nov 29, 2022
Simple android image popup Library

Android Image Popup Show image as a popup on a click event or any event. Simply set the image as drawable and thats it!!!. And also you can set width,

Chathura Lakmal 64 Nov 15, 2022
Image loading library for Android

Image Loader Image loader library for Android. Deprecated. See Glide. Features Image transformations Automatic memory and storage caching Ability to l

Yuriy Budiyev 19 May 28, 2022