Giter Site home page Giter Site logo

croppy's Introduction

Croppy

Basic Usage

//Start croppy (source uri is the original image.)
val cropRequest = CropRequest.Auto(sourceUri = uri, requestCode = 101)
Croppy.start(this, cropRequest)
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
      super.onActivityResult(requestCode, resultCode, data)
      if (requestCode == 101) {
           imageview.setImageURI(data.data)
     }
}

Custom Usage

Create cropped image result in external storage

val externalCropRequest = CropRequest.Auto(sourceUri = uri, requestCode = RC_CROP_IMAGE)

Create cropped image result in cache storage

val cacheCropRequest = CropRequest.Auto(
     sourceUri = uri,
     requestCode = RC_CROP_IMAGE,
     storageType = StorageType.CACHE
)

If you want to create destination file manually

val destinationUri = ...
val manuelCropRequest = CropRequest.Manual(
    sourceUri = uri,
    destinationUri = destinationUri,
    requestCode = RC_CROP_IMAGE
)

If you want to exclude some specific aspect ratio from bottom aspect ratio list view.

val excludeAspectRatiosCropRequest = CropRequest.Manual(
    sourceUri = uri,     
    destinationUri = destinationUri,
    requestCode = RC_CROP_IMAGE,
    excludedAspectRatios = arrayListOf(AspectRatio.ASPECT_FREE)
)

If you want to give specific theme as accent color.

val themeCropRequest = CropRequest.Manual(
    sourceUri = uri,
    destinationUri = destinationUri,
    requestCode = RC_CROP_IMAGE,
    croppyTheme = CroppyTheme(R.color.blue)
)
//Start croppy with your custom request.
Croppy.start(this, cropRequest)

Demo

Features

Double tap focus ๐Ÿ‘†๐Ÿ‘†

It zooms-in to the touch points on double tap. Restores default state when user double taps on max scale state.

Pinch Zoom ๐Ÿ‘Œ

Zoom in and out with two finger.

Free Mode ๐ŸคŸ

You can crop your image in free mode. In any size.

Aspect Ratio Mode ๐Ÿ“ฑ

Enhanced aspect ratio mode will help you while cropping. Aspect ratio will be fixed while you play with cropper. So for your social media apps, it will help you to crop in fixed size (instagram, facebook, twitter, 16:9, 1:2, 3:2 and more..)

Size Displayer ๐Ÿ”Ÿ

While you scale your image, size displayer indicates the bitmap size reactively. It will provide a smoother experience to the user.

Auto Centered ๐Ÿ˜

What ever you do while cropping, we center the bitmap with animation. Smoother experience for user.

Animations ๐ŸŒŸ

We use animation everywhere in this cropper. User zoomed-out too much? We zoom back in with animation. User scrolled image out of borders? We scroll it back with animation.

Setup

allprojects {
     repositories {
	...
	maven { url 'https://jitpack.io' }
     }
}
dependencies {
      implementation 'com.github.lyrebirdstudio:Croppy:0.2'
}

License

Copyright 2019 Lyrebird Studio.

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.

croppy's People

Contributors

gungoren avatar iammert avatar mohammadsianaki avatar nuhkoca avatar oguzcelik avatar seanghay avatar zcelaloglu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

croppy's Issues

Layout Direction

hi
unfortunately it has a bug
the direction in rtl or in persian language has problem , please check it

Run error

java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException
at java.base/java.lang.Class.getDeclaredConstructors0(Native Method)
at java.base/java.lang.Class.privateGetDeclaredConstructors(Class.java:3137)
at java.base/java.lang.Class.getConstructor0(Class.java:3342)
at java.base/java.lang.Class.newInstance(Class.java:556)
at org.jetbrains.kotlin.cli.jvm.plugins.ServiceLoaderLite.loadImplementations(ServiceLoaderLite.kt:51)
at org.jetbrains.kotlin.cli.jvm.plugins.ServiceLoaderLite.loadImplementations(ServiceLoaderLite.kt:44)
at org.jetbrains.kotlin.kapt3.ClasspathBasedKapt3Extension$loadProcessors$efficientProcessorLoader$1.doLoadProcessors(Kapt3Extension.kt:84)
at org.jetbrains.kotlin.kapt3.base.ProcessorLoader.loadProcessors(ProcessorLoader.kt:45)
at org.jetbrains.kotlin.kapt3.base.ProcessorLoader.loadProcessors$default(ProcessorLoader.kt:28)
at org.jetbrains.kotlin.kapt3.ClasspathBasedKapt3Extension.loadProcessors(Kapt3Extension.kt:89)
at org.jetbrains.kotlin.kapt3.AbstractKapt3Extension.analysisCompleted(Kapt3Extension.kt:172)
at org.jetbrains.kotlin.kapt3.ClasspathBasedKapt3Extension.analysisCompleted(Kapt3Extension.kt:99)
at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM$analyzeFilesWithJavaIntegration$2.invoke(TopDownAnalyzerFacadeForJVM.kt:96)
at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(TopDownAnalyzerFacadeForJVM.kt:106)
at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration$default(TopDownAnalyzerFacadeForJVM.kt:81)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler$analyze$1.invoke(KotlinToJVMBytecodeCompiler.kt:555)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler$analyze$1.invoke(KotlinToJVMBytecodeCompiler.kt:82)
at org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport.analyzeAndReport(AnalyzerWithCompilerReport.kt:107)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.analyze(KotlinToJVMBytecodeCompiler.kt:546)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules$cli(KotlinToJVMBytecodeCompiler.kt:177)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:164)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:54)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:84)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:42)
at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:104)
at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:1558)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:359)
at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:200)
at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:197)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.rmi/sun.rmi.transport.Transport.serviceCall(Transport.java:196)
at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:562)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:796)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:677)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:676)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: java.lang.ClassNotFoundException: javax.xml.bind.JAXBException
at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:476)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:589)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
... 43 more

Oriented Images Should Rotate Before Loading

After taking a photo from my LG G7 and starting Croppy from the file Uri, CroppyActivity started with the image rotated.

You may consider checking ExifInterface orientation before loading bitmap.

Sample code in Java :

Bitmap rotateBitmap(@NonNull String src, Bitmap bitmap) {
            int orientation;

            try {
                orientation = getExifOrientation(src);
            } catch (IOException e) {
                e.printStackTrace();
                return bitmap;
            }

            Matrix matrix = new Matrix();

            switch (orientation) {
                case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
                    matrix.setScale(-1, 1);
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    matrix.setRotate(180);
                    break;
                case ExifInterface.ORIENTATION_FLIP_VERTICAL:
                    matrix.setRotate(180);
                    matrix.postScale(-1, 1);
                    break;
                case ExifInterface.ORIENTATION_TRANSPOSE:
                    matrix.setRotate(90);
                    matrix.postScale(-1, 1);
                    break;
                case ExifInterface.ORIENTATION_ROTATE_90:
                    matrix.setRotate(90);
                    break;
                case ExifInterface.ORIENTATION_TRANSVERSE:
                    matrix.setRotate(-90);
                    matrix.postScale(-1, 1);
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    matrix.setRotate(-90);
                    break;
                default:
                    return bitmap;
            }

            try {
                Bitmap oriented = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
                bitmap.recycle();
                return oriented;
            } catch (OutOfMemoryError e) {
                e.printStackTrace();
                return null;
            }
        }

private int getExifOrientation(@NonNull String src) throws IOException {
            DebugLog.write();
            ExifInterface exifInterface = new ExifInterface(src);
            return exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
        }

issue with height

this line its the problem


     viewModel
            .getResizedBitmapLiveData()
            .observe(viewLifecycleOwner, Observer { binding.cropView.setBitmap(it.bitmap) })

java.lang.IllegalArgumentException: width and height must be > 0
at android.graphics.Bitmap.createBitmap(Bitmap.java:1113)
at android.graphics.Bitmap.createBitmap(Bitmap.java:1080)
at android.graphics.Bitmap.createBitmap(Bitmap.java:1030)
at android.graphics.Bitmap.createBitmap(Bitmap.java:991)
at com.lyrebirdstudio.croppylib.cropview.CropView.createMaskBitmap(CropView.kt:525)
at com.lyrebirdstudio.croppylib.cropview.CropView.initialize(CropView.kt:510)
at com.lyrebirdstudio.croppylib.cropview.CropView.setBitmap(CropView.kt:404)
at com.lyrebirdstudio.croppylib.ui.ImageCropFragment$onActivityCreated$2.onChanged(ImageCropFragment.kt:119)
at com.lyrebirdstudio.croppylib.ui.ImageCropFragment$onActivityCreated$2.onChanged(ImageCropFragment.kt:17)
at androidx.lifecycle.LiveData.considerNotify(LiveData.java:131)
at androidx.lifecycle.LiveData.dispatchingValue(LiveData.java:149)
at androidx.lifecycle.LiveData.setValue(LiveData.java:307)
at androidx.lifecycle.MutableLiveData.setValue(MutableLiveData.java:50)
at com.lyrebirdstudio.croppylib.ui.ImageCropViewModel$setCropRequest$1.accept(ImageCropViewModel.kt:38)
at com.lyrebirdstudio.croppylib.ui.ImageCropViewModel$setCropRequest$1.accept(ImageCropViewModel.kt:18)
at io.reactivex.internal.observers.ConsumerSingleObserver.onSuccess(ConsumerSingleObserver.java:62)
at io.reactivex.internal.operators.single.SingleObserveOn$ObserveOnSingleObserver.run(SingleObserveOn.java:81)
at io.reactivex.android.schedulers.HandlerScheduler$ScheduledRunnable.run(HandlerScheduler.java:124)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:491)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)

Crash if no databinding enabled in project

Crash when starting Croppy if the project doesn't have databinding added in gradle.

Croppy.start(this, CropRequest.Auto(bitmapUri, code))
FATAL EXCEPTION: main
    java.lang.NoClassDefFoundError: Failed resolution of: Landroidx/databinding/DataBinderMapperImpl;
        at androidx.databinding.DataBindingUtil.<clinit>(DataBindingUtil.java:32)
        at androidx.databinding.DataBindingUtil.setContentView(DataBindingUtil.java:284)
        at com.lyrebirdstudio.croppylib.main.CroppyActivity.onCreate(CroppyActivity.kt:23)
        at android.app.Activity.performCreate(Activity.java:7963)
        at android.app.Activity.performCreate(Activity.java:7952)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1307)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3629)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3806)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2267)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:237)
        at android.app.ActivityThread.main(ActivityThread.java:8167)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100)

missing document/info about import

You are writing very useful information, but forgetting very basic infos:
import statements:

import com.lyrebirdstudio.croppylib.Croppy
import com.lyrebirdstudio.croppylib.main.CropRequest

To all Android Devs:
while giving some code/info, please state where to write also...
always give required imports also.

Problem: "A resource Failed to Call Close"

Hi I am trying the most basic version of your app
The Croppy editing app will load. however once i Click the "Tick" button on the Croppy App. it just closes with a "W/System: A resource failed to call close. "
I couldnt get any result back probably because of that.
Any idea why this could happen?

`
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)

    when(requestCode){
        1->{
            if (resultCode== Activity.RESULT_OK&&data!=null)
            {
                imageURI_1= data.data!!
                val cropRequest=CropRequest.Auto(data.data!!,101)
                Log.d(TAG,"Start Croppy Activity")
                Croppy.start(mActivity,cropRequest)
            }
        }
        
        101->{
            Log.d(TAG,"Get Crop Result Back")
            imagebutton_1.setImageURI(data!!.data)
        }
    }
}

`

Croppy Direction

hi
unfortunately it has a bug
the direction in rtl or in persian language has problem , please check it

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.