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.0'
}

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
This is an Image slider with swipes, Here we used Volley to Image load URL's from JSON! Here we make it very easy way to load images from Internet and We customized the description font style(OpenSans).

ImageSliderWithSwipes This is an Image slider with swipes, Here we used Volley to load URL's from JSON! Here we make it very easy way to load images f

Prabhakar Thota 44 May 31, 2021
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
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
Image Cropping Library for Android, optimised for Camera / Gallery.

Image Cropping Library for Android, optimised for Camera / Gallery.

CanHub 812 Dec 30, 2022
An image loading library for android.

Bilder Download Add following to your project's build.gradle allprojects { repositories { ... maven { url 'https://jitpack.io' } } }

Kshitij Sharma 4 Jan 1, 2022
An Android transformation library providing a variety of image transformations for Coil, Glide, Picasso, and Fresco.

An Android transformation library providing a variety of image transformations for Coil, Glide, Picasso, and Fresco.

Daichi Furiya 257 Jan 2, 2023
🎨 Modern image loading library for Android. Simple by design, powerful under the hood.

Simple Image Loader Modern image loading library for Android. Simple by design, powerful under the hood. Kotlin: Simple Image Loader is Kotlin-native

Igor Solkin 8 Nov 21, 2022
Image Cropping Library for Android

Image Cropping Library for Android

Lyrebird Studio 1.1k Dec 30, 2022
A small customizable library useful to handle an gallery image pick action built-in your app. :sunrise_over_mountains::stars:

Louvre A small customizable image picker. Useful to handle an gallery image pick action built-in your app. *Images from Google Image Search Installati

André Mion 640 Nov 19, 2022
Library to save image locally and shows options to open and share !

Image Save and Share Library to save image locally and shows options to open and share ! Download Demo APK from HERE Kindly use the following links to

Prabhakar Thota 27 Apr 18, 2022
RoundedImageView-Library 0.9 0.0 Java To set single or multiple corners on Image Views.

RoundedImageView-Library Rounded ImageView Android Library, to set single or multiple corners on imageview. Screenshot Usage Step 1. Add the JitPack r

Dushyant Mainwal 15 Sep 2, 2020
A library for image manipulation with power of renderScript which is faster than other ordinary solutions.

Pixl is a library for image manipulation with power of renderScript which is faster than other ordinary solutions, currently it includes three basic scripts, brightness, contrast, saturation.

Jibran Iqbal 20 Jan 23, 2022
Image cropping library written with Jetpack Compose with other Composables such as ImageWithConstraints scales Bitmap

Image cropping library written with Jetpack Compose with other Composables such as ImageWithConstraints scales Bitmap it displays and returns position and bounds of Bitmap and ImageWithThumbnail to display thumbnail of the image on selected corner.

Smart Tool Factory 9 Jul 27, 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
some android image filters

android-image-filter some android image filters in some filter, I use NDK to implement to make it more efficient Setup Install Android NDK and properl

RagnarokStack 643 Dec 27, 2022