An android image compression library.

Overview

Compressor

Android Arsenal Build Status codecov

Compressor is a lightweight and powerful android image compression library. Compressor will allow you to compress large photos into smaller sized photos with very less or negligible loss in quality of the image.

Gradle

dependencies {
    implementation 'id.zelory:compressor:3.0.1'
}

Let's compress the image size!

Compress Image File

val compressedImageFile = Compressor.compress(context, actualImageFile)

Compress Image File to specific destination

val compressedImageFile = Compressor.compress(context, actualImageFile) {
    default()
    destination(myFile)
}

I want custom Compressor!

Using default constraint and custom partial of it

val compressedImageFile = Compressor.compress(context, actualImageFile) {
    default(width = 640, format = Bitmap.CompressFormat.WEBP)
}

Full custom constraint

val compressedImageFile = Compressor.compress(context, actualImageFile) {
    resolution(1280, 720)
    quality(80)
    format(Bitmap.CompressFormat.WEBP)
    size(2_097_152) // 2 MB
}

Using your own custom constraint

class MyLowerCaseNameConstraint: Constraint {
    override fun isSatisfied(imageFile: File): Boolean {
        return imageFile.name.all { it.isLowerCase() }
    }

    override fun satisfy(imageFile: File): File {
        val destination = File(imageFile.parent, imageFile.name.toLowerCase())
        imageFile.renameTo(destination)
        return destination
    }
}

val compressedImageFile = Compressor.compress(context, actualImageFile) {
    constraint(MyLowerCaseNameConstraint()) // your own constraint
    quality(80) // combine with compressor constraint
    format(Bitmap.CompressFormat.WEBP)
}

You can create your own extension too

fun Compression.lowerCaseName() {
    constraint(MyLowerCaseNameConstraint())
}

val compressedImageFile = Compressor.compress(context, actualImageFile) {
    lowerCaseName() // your own extension
    quality(80) // combine with compressor constraint
    format(Bitmap.CompressFormat.WEBP)
}

Compressor now is using Kotlin coroutines!

Calling Compressor should be done from coroutines scope

// e.g calling from activity lifecycle scope
lifecycleScope.launch {
    val compressedImageFile = Compressor.compress(context, actualImageFile)
}

// calling from global scope
GlobalScope.launch {
    val compressedImageFile = Compressor.compress(context, actualImageFile)
}

Run Compressor in main thread

val compressedImageFile = Compressor.compress(context, actualImageFile, Dispatchers.Main)

Old version

Please read this readme

License

Copyright (c) 2016 Zetra.

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
  • Migration from JCenter

    Migration from JCenter

    In may this library won't be available from JCenter: https://jfrog.com/blog/into-the-sunset-bintray-jcenter-gocenter-and-chartcenter/

    Please migrate this library to some other repository

    opened by jakoss 9
  • Upgrade to RxJava2.0.1

    Upgrade to RxJava2.0.1

    my project use RxJava2.0.1, and i use this lib to handler image,. Then when i run my project like this: Error:Execution failed for task ':app:transformResourcesWithMergeJavaResForDebug'.

    com.android.build.api.transform.TransformException: com.android.builder.packaging.DuplicateFileException: Duplicate files copied in APK META-INF/rxjava.properties File1: /Users/envative/.gradle/caches/modules-2/files-2.1/io.reactivex/rxjava/1.1.6/2586312cd2b8a511e4c6236736f5a039fc0f2273/rxjava-1.1.6.jar File2: /Users/envative/.gradle/caches/modules-2/files-2.1/io.reactivex.rxjava2/rxjava/2.0.1/57f850a6b317e5582f1dbaff10a9e7d7e1fcdcfb/rxjava-2.0.1.jar

    opened by Xiasm 5
  • Create friendly api to Compressor

    Create friendly api to Compressor

    Create friendly "API" to compressor:

    ImageCompressor.with(context)  
     .launchOn(Dispatchers.IO) // set a CoroutineContext (Optional, default = Dispatchers.IO)
     .observeOn(lifecycleScope) // set a CoroutineScope
     .applyCompressionWith { // options 
        resolution(1280, 720) 
        format(Bitmap.CompressFormat.WEBP) 
        ... 
     }.compress(inputImg) { outputImage -> 
        // get output image here 
     }
    

    With that implementation is possible to use any DI framework to provide an ImageCompressor instance, enabling more reusability and decoupling of android Context.

    See implementation here ImageCompressor.kt

    opened by jeziellago 4
  •  error: incompatible types: io.reactivex.Scheduler cannot be converted to rx.Scheduler

    error: incompatible types: io.reactivex.Scheduler cannot be converted to rx.Scheduler

    i m Getting error in this line: Compressor.getDefault(this).compressToFileAsObservable(actualImage) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread())

    i m using android studio 2.3.1 and my project using this lib. compile 'io.reactivex.rxjava2:rxandroid:2.0.1' .

    opened by ruby-sharma6851 4
  • Compresor doesn't change file name ending after compression to different format

    Compresor doesn't change file name ending after compression to different format

    I am using 2.1.0 version.

    Let's say I want to compress JPEG image and save it as a PNG after compression.

    The problem is that newly created PNG file name persists the same with .jpg ending after such compression.

    To avoid this, I have to do something like this:

    .compressToFileAsFlowable(file, file.getName().replace(".jpg", ".png"))

    which is not good in my opinion and such thing should be handled by library.

    opened by GediminasZukas 3
  • error

    error

    java.lang.RuntimeException: An error occured while executing doInBackground() at android.os.AsyncTask$3.done(AsyncTask.java:300) at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355) at java.util.concurrent.FutureTask.setException(FutureTask.java:222) at java.util.concurrent.FutureTask.run(FutureTask.java:242) at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) at java.lang.Thread.run(Thread.java:818) Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int android.graphics.Bitmap.getWidth()' on a null object reference at id.zelory.compressor.ImageUtil.getScaledBitmap(ImageUtil.java:96) at id.zelory.compressor.ImageUtil.compressImage(ImageUtil.java:128) at id.zelory.compressor.Compressor.compressToFile(Compressor.java:43) at com.rxjr.rxcd.beta.utils.CompressUtil.doInBackground(CompressUtil.java:48) at com.rxjr.rxcd.beta.utils.CompressUtil.doInBackground(CompressUtil.java:21) at android.os.AsyncTask$2.call(AsyncTask.java:288) at java.util.concurrent.FutureTask.run(FutureTask.java:237)

    opened by xiyanglove 3
  • why you use uri rather than File.getAbsolutePath() ??

    why you use uri rather than File.getAbsolutePath() ??

    public File compressToFile(File file) { return ImageUtil.compressImage(context, Uri.fromFile(file), maxWidth, maxHeight, compressFormat, bitmapConfig, quality, destinationDirectoryPath, fileNamePrefix, fileName); }

    opened by 08carmelo 2
  • java.lang.IllegalArgumentException: width and height must be > 0

    java.lang.IllegalArgumentException: width and height must be > 0

    java.lang.IllegalArgumentException: width and height must be > 0 at android.graphics.Bitmap.createBitmap(Bitmap.java:967) at android.graphics.Bitmap.createBitmap(Bitmap.java:946) at android.graphics.Bitmap.createBitmap(Bitmap.java:913) at id.zelory.compressor.ImageUtil.getScaledBitmap(ImageUtil.java:116) at id.zelory.compressor.ImageUtil.compressImage(ImageUtil.java:161) at id.zelory.compressor.Compressor.compressToFile(Compressor.java:48)

    receiving in

    DEVICE config

    Android 6.01 Family samsung Model on7xeltedd (SM-G610F) Architecture armv8l Orientation portrait screen_resolution 1920x1080

    opened by umesh0492 2
  • Upgrade to RxJava 2.0.1

    Upgrade to RxJava 2.0.1

    I am using RxJava 2.0.1 in my project and when i import Compressor it wont compile complaining i have multiple versions of RxJava.

    Error:Execution failed for task ':app:transformResourcesWithMergeJavaResForDebug'.
    > com.android.build.api.transform.TransformException: com.android.builder.packaging.DuplicateFileException: Duplicate files copied in APK META-INF/rxjava.properties
      	File1: /Users/envative/.gradle/caches/modules-2/files-2.1/io.reactivex/rxjava/1.1.6/2586312cd2b8a511e4c6236736f5a039fc0f2273/rxjava-1.1.6.jar
      	File2: /Users/envative/.gradle/caches/modules-2/files-2.1/io.reactivex.rxjava2/rxjava/2.0.1/57f850a6b317e5582f1dbaff10a9e7d7e1fcdcfb/rxjava-2.0.1.jar
    
    opened by ka05 2
  • compressor artifact on maven central has unspecified dependency

    compressor artifact on maven central has unspecified dependency

    FAILURE: Build failed with an exception.
    
    * What went wrong:
    Could not determine the dependencies of task ':compileReleaseJavaWithJavac'.
    > Could not resolve all task dependencies for configuration ':releaseCompileClasspath'.
       > Could not find :unspecified:.
         Required by:
             project : > id.zelory:compressor:3.0.0
    

    We get this after pulling the artifact from Maven Central... In the pom file, you have a dependency called "unspecified", can you do an update which fixes this?

    This is what the pom file looks like:

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>id.zelory</groupId>
        <artifactId>compressor</artifactId>
        <version>3.0.0</version>
        <packaging>aar</packaging>
        <name>compressor</name>
        <description>An android image compressor library</description>
        <url>https://github.com/zetbaitsu/Compressor</url>
        <licenses>
            <license>
                <name>The Apache Software License, Version 2.0</name>
                <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
            </license>
        </licenses>
        <developers>
            <developer>
                <id>zetbaitsu</id>
                <name>Zetra</name>
                <email>[email protected]</email>
            </developer>
        </developers>
        <scm>
            <connection>scm:git:github.com/zetbaitsu/Compressor.git</connection>
            <developerConnection>scm:git:ssh://github.com/zetbaitsu/Compressor.git</developerConnection>
            <url>https://github.com/zetbaitsu/Compressor/tree/main</url>
        </scm>
        <dependencies>
            <dependency>
                <groupId/>
                <artifactId>unspecified</artifactId>
                <version/>
            </dependency>
            <dependency>
                <groupId>org.jetbrains.kotlin</groupId>
                <artifactId>kotlin-stdlib-jdk7</artifactId>
                <version>1.3.61</version>
            </dependency>
            <dependency>
                <groupId>org.jetbrains.kotlinx</groupId>
                <artifactId>kotlinx-coroutines-core</artifactId>
                <version>1.3.3</version>
            </dependency>
        </dependencies>
    </project>
    

    (We used another 3.0.0 version that didn't have any dependencies from Jcenter earlier)

    opened by daverix 1
  • Compressed image is of 0 bytes

    Compressed image is of 0 bytes

    I'm using this code to compress image, works fine till android 9 but on android 10 file size is of 0 bytes

    try { new Compressor(this) //.setMaxWidth(640) // .setMaxHeight(480) // .setQuality(75) .setCompressFormat(Bitmap.CompressFormat.JPEG) .setDestinationDirectoryPath(new File(this.getExternalCacheDir(),"images").getAbsolutePath()) .compressToFile(new File(getPath(uri))); } catch (IOException e) { e.printStackTrace(); }

    opened by pratyush019 1
  • Custom compress not giving the expected  image size.

    Custom compress not giving the expected image size.

    I have used it according to the documentation but when am compressing image to a specific size like 2mb it will not compress image exact to 2mb. It will give result like 1.1mb or something like that.

    opened by azizconsoliads 1
  • Caused by java.io.FileNotFoundException: on Xiaomi Redmi Note 9

    Caused by java.io.FileNotFoundException: on Xiaomi Redmi Note 9

    Caused by java.io.FileNotFoundException: /storage/emulated/0/Android/data/com.app.aexdriver.dev/files/Pictures/Camera/IMG_20220922_083206_502.jpg: open failed: ENOENT (No such file or directory)

    opened by irfanirawansukirman 0
  • Delete cache on exception

    Delete cache on exception

    Looking at source code of Compressor.compress and it's implementation down the line.

    Seems like cache stays behind, if Exception occurs. Probably some sort of try-catch is needed, that deletes cached file in finally block.

    opened by WildOrangutan 0
  •  Ability to delete cached image.

    Ability to delete cached image.

    Hi @zetbaitsu! Thank you for library. My question is how can we safely remove the cached file from the compressor folder? For example, I get images from outside, create a new file with name compressedImage , and set destination(imageFile) as the property, my newly created file is successfully replaced with the compressed one. But now we have 2 identical files in different folders. Would like to be able to properly delete a file coming along the path - "${context.cacheDir.path}${separator}compressor$separator".

    opened by Normalnick12 1
Releases(v3.0.1)
Owner
Zetra
anti dandruff 🏄‍♀️
Zetra
An image loading and caching library for Android focused on smooth scrolling

Glide | View Glide's documentation | 简体中文文档 | Report an issue with Glide Glide is a fast and efficient open source media management and image loading

Bump Technologies 33.2k Jan 7, 2023
A powerful image downloading and caching library for Android

Picasso A powerful image downloading and caching library for Android For more information please see the website Download Download the latest AAR from

Square 18.4k Jan 6, 2023
An Android transformation library providing a variety of image transformations for Glide.

Glide Transformations An Android transformation library providing a variety of image transformations for Glide. Please feel free to use this. Are you

Daichi Furiya 9.7k Dec 30, 2022
An Android transformation library providing a variety of image transformations for Picasso

Picasso Transformations An Android transformation library providing a variety of image transformations for Picasso. Please feel free to use this. Are

Daichi Furiya 1.7k Jan 5, 2023
Library to handle asynchronous image loading on Android.

WebImageLoader WebImageLoader is a library designed to take to hassle out of handling images on the web. It has the following features: Images are dow

Alexander Blom 102 Dec 22, 2022
🍂 Jetpack Compose image loading library which can fetch and display network images using Glide, Coil, and Fresco.

?? Jetpack Compose image loading library which can fetch and display network images using Glide, Coil, and Fresco.

Jaewoong Eum 1.4k Jan 2, 2023
Compose Image library for Kotlin Multiplatform.

Compose ImageLoader Compose Image library for Kotlin Multiplatform. Setup Add the dependency in your common module's commonMain sourceSet kotlin {

Seiko 45 Dec 29, 2022
Android Asynchronous Networking and Image Loading

Android Asynchronous Networking and Image Loading Download Maven Git Features Kotlin coroutine/suspend support Asynchronously download: Images into Im

Koushik Dutta 6.3k Dec 27, 2022
Image loading for Android backed by Kotlin Coroutines.

An image loading library for Android backed by Kotlin Coroutines. Coil is: Fast: Coil performs a number of optimizations including memory and disk cac

Coil 8.8k Jan 8, 2023
Image Picker for Android 🤖

Image Picker for Android ??

Esa Firman 1k Dec 31, 2022
ZoomableComposeImage - A zoomable image for jetpack compose

ZoomableComposeImage - A zoomable image for jetpack compose

RERERE 10 Dec 11, 2022
ComposeImageBlurhash is a Jetpack Compose component with the necessary implementation to display a blurred image

compose-image-blurhash ComposeImageBlurhash is a Jetpack Compose component with the necessary implementation to display a blurred image while the real

Orlando Novas Rodriguez 24 Nov 18, 2022
Easy to use, lightweight custom image view with rounded corners.

RoundedImageView Easy to use, lightweight custom image view with rounded corners. Explore the docs » View Demo · Report Bug · Request Feature About Th

Melik Mehmet Özyildirim 6 Dec 23, 2021
load-the-image Apply to compose-jb(desktop), Used to load network and local pictures.

load-the-image load-the-image Apply to compose-jb(desktop), Used to load network and local pictures. ?? Under construction It may change incompatibly

lt_taozi 13 Dec 29, 2022
Powerful and flexible library for loading, caching and displaying images on Android.

Universal Image Loader The great ancestor of modern image-loading libraries :) UIL aims to provide a powerful, flexible and highly customizable instru

Sergey Tarasevich 16.8k Jan 8, 2023
An Android library for managing images and the memory they use.

Fresco Fresco is a powerful system for displaying images in Android applications. Fresco takes care of image loading and display, so you don't have to

Facebook 16.9k Jan 8, 2023
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 Jan 2, 2023
Glide Bitmap Pool is a memory management library for reusing the bitmap memory

Glide Bitmap Pool About Glide Bitmap Pool Glide Bitmap Pool is a memory management library for reusing the bitmap memory. As it reuses bitmap memory ,

AMIT SHEKHAR 573 Dec 31, 2022
Andorid library that loads images asynchronously into cache using a thread pool

AndroidImageLoader AndroidImageLoader is a fork of the Image Loader component in libs-for-android. The AndroidImageLoader is an Android library that h

David Wu 63 Feb 19, 2019