lyft / scissors Goto Github PK
View Code? Open in Web Editor NEW✂ Android image cropping library
Home Page: https://eng.lyft.com/scissors-an-image-cropping-library-for-android-a56369154a19
License: Apache License 2.0
✂ Android image cropping library
Home Page: https://eng.lyft.com/scissors-an-image-cropping-library-for-android-a56369154a19
License: Apache License 2.0
Hello everyone!
I was wondering why the pickUsing
relies on a android.app.Fragment
instead of the support fragment?
static void pickUsing(Fragment fragment, int requestCode) {
fragment.startActivityForResult(createChooserIntent(), requestCode);
}
I have my hands tied, as I'm using the v4 support fragment, and using the Activity counterpart is going to be really messy. Is there any plans to bring in the support functionality? Or at least is there a suggestion anyone has that I could make use of?
We have a flow requiring multiple images to be selected and cropped. The issue is the CropView's transform sticks around even after loading a new image. Is there a way to reset the transform applied to the CropView before we load the next image?
when calling cropView.extensions() .pickUsing(this, RequestCodes.PICK_IMAGE_FROM_GALLERY);
from with in a fragment returns the result to the parent activity and not back to the fragments onActivityResult
Is there a work around or is this something that can be added. Thanks for the library, loving it so far.
Is it possible to have a rotate feature and a callback for once the image is cropped and saved?
I know this is primarily a cropping library but something like a rotate/mirror feature could add a lot of value. Thoughts?
It would be nice if you could add some guidelines over the image or anything that would offer the familiar look of an image-cropping screen so that the user will instantly understand that this is where cropping happens, not just to read the activity title to know they now can crop
Does that make sense?
Can the Crop view be used to re position an image in a container. the image is bigger than the CropView and i need to chose which area is visible trough the view port. to do this i would need to get the x and y position of the image in relation tho the cropView. I am using this library for cropping image in another section of my app and would like to reuse it for this function as it handles the dragging and scaling for me but after playing around with it i could not get ant information on the positioning of the image. is this supported or do i need to look else where.
As far as I know there is no way to provide a "loading finished" callback to the framework. Assuming this is not a deliberate design decision, can we consider adding a method to the BitmapLoader interface that accepts a callback?
i.e. something to the effect of:
public interface BitmapLoader {
void load(@Nullable Object model, @NonNull ImageView view);
void load(@Nullable Object model, @NonNull ImageView view, ScissorCallback callback);
}
public interface ScissorCallback {
void onComplete();
}
PicassoBitmapLoader / GlideBitmapLoader's implementations can then forward events generated from their respective libraries to ScissorCallback's onComplete(). This is obviously not a complete solution as we're losing a lot of information from the library callbacks but it's a start and super simple to implement.
W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0xe0162fc0, error=EGL_SUCCESS
Getting the above error anytime i try loading the image into the cropView.
any help on that please?
Here is the related code:
private void loadImageFromCamera() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
Uri imageUri = Uri.fromFile(createExternalCacheFile("avatar_camera.png"));
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(intent, PICK_IMAGE_FROM_CAMERA);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE_FROM_GALLERY && resultCode == RESULT_OK) {
Uri imageUri = data.getData();
mCropView.extensions().load(imageUri);
}
if (requestCode == PICK_IMAGE_FROM_CAMERA && requestCode == RESULT_OK) {
Bitmap bitmap = null;
try {
bitmap = BitmapFactory.decodeStream(new FileInputStream(createExternalCacheFile("avatar_camera.png")));
mCropView.setImageBitmap(bitmap);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
CropView doesn't show the bitmap.
Hi?
Are there examples showing how to use this library with glide? Also, i want the cropped image to fit into a square of specific dimensions e.g 200px by 200px, how do i achieve that?
A few months ago Glide 4 has been released and there are some incompatibilities with Glide 3.
In Glide 4, there's an object that needs to be used to pass options when loading an image, as you can see in this link.
Glide options documentation
In particular, I'm using the CropView library that ends calling Scissor's load method of the GlideBitmapLoader class which has a code not supported in Glide v4.
Thanks,
Pablo
Thanks for you share the Demo。
if i use
<com.lyft.android.scissors.CropView
android:id="@+id/clipfilter_img"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:cropviewViewportOverlayColor="#a0000000"
/>
at layout XML ,the picture display like fit end on bottom cropline(picture bottom coincidence with app:cropviewViewportRatio line),not the bottom your CropView。
and i use cropview.setViewportRatio(1f) aslo has this questiong.
i find that if the picture not load done then use cropview.setViewportRatio(1) will has this question。
so i ues the
Glide.with(this).load(imgPath).listener(new RequestListener<String, GlideDrawable>() {
@OverRide
public boolean onException(Exception e, String model, Target target, boolean isFirstResource) {
return false;
}
@Override
public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
handler.postDelayed(new Runnable() {
@Override
public void run() {
imageView.setViewportRatio(1f);
}
}, 0);
return false;
}
}).into(imageView);
it can solve thisquestion。
but i find another question ,the android:scaleType="" not work。the pic always fill the corpview like i use the fitXY,even a square picture aslo stretch to fill parent。
Now i use
@OverRide
protected void onResume() {
super.onResume();
handler.postDelayed(new Runnable() {
@OverRide
public void run() {
imageView.setViewportRatio(1f);
}
}, 300);
}
,but if the pic is too big or my phone not have a stronger CPU,cropView load pic 0.3S not done aslo has the fist question 。but the time aslo can't set too long which cause i can saw the setViewportRatio anim 。
Thank you。
Is it possible to have a rotate feature?
I know this is primarily a cropping library but something like a rotate/mirror feature could add a lot of value. Thoughts?
thx
Hi, is there any way I could get the cropped offset (left and top)?
Hi! Thanks for open-sourcing this amazing library!
I noticed that if I have a thin viewport ratio, the underlying bitmp is not initially centered:
I can get the centered image by doing position.set (availableWidth / 2, availableHeight / 2)
here - https://github.com/lyft/scissors/blob/master/scissors/src/main/java/com/lyft/android/scissors/TouchManager.java#L88
Is this the appropriate workaround?
Hi, How can i set Custom size on view port
After crop, if i send picture via intent like in sample with Picasso, most of the times does nothing because file is corrupted or other causes. I made an AsyncTask with weak reference to load bitmap. I set image to crop, first time resulted bitmap is null. Second time bitmap is decoded successful. Is decoding when he wants. I do something wrong or is some bug? I followed the sample at first time and it isn't work at all.
Thank you for your effort. I have one question below.
How to show grid view around cropped view?
Currently, the cropped image can be significantly degraded from the original since the cropping is based on the view's dimensions. If the image is significantly larger than the view, the cropped image will be the size of the view, which isn't ideal, especially on budget devices.
Regardless of view size, I think the cropping should be based on the original image size, since the representation on screen is simply proportional to the actual file.
I want to customize the crop ratio dynamically from code, but no support currently..
I tried it on Galaxy S6 running 5.1.1
And if I try to load an image, the image is rotated in 90 degrees even before cropping.
The debug version of my app works fine. I created a release build for my app, and on selecting a picture to be cropped the app crashes stating the following.
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=10001, result=-1, data=Intent { dat=content://media/external/images/media/9279 }} to activity {com.prism.prismapp/com.prism.prismapp.CropImageActivity_}: java.lang.IllegalStateException: You must provide a BitmapLoader.
at android.app.ActivityThread.deliverResults(ActivityThread.java:3367)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3410)
at android.app.ActivityThread.access$1300(ActivityThread.java:141)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1260)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5113)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:609)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.IllegalStateException: You must provide a BitmapLoader.
at com.lyft.android.scissors.CropViewExtensions.resolveBitmapLoader(Unknown Source)
at com.lyft.android.scissors.CropViewExtensions$LoadRequest.load(Unknown Source)
at com.lyft.android.scissors.CropView$Extensions.load(Unknown Source)
at com.prism.prismapp.g.onActivityResult(Unknown Source)
at android.app.Activity.dispatchActivityResult(Activity.java:5440)
at android.app.ActivityThread.deliverResults(ActivityThread.java:3363)
Can we have an updated read me with the proguard setup?
My project has a Fresco Drawee for the imageview.
Can I use scissors with this?
I'd like to suggest to remove the use of extensions completely and focusing more on the core functionality. Here are some reasons:
Although all of the above can be fixed, I think it's simply unnecessary as the loading libraries already do all that.
Currently we use custom touch handling for zooming and snapping, we should use ScaleGestureDetector
which has out of the box double tap to drag zooming.
Hi all,my project is using Fresco to loading picture. How can i use CropView with Fresco?
I have code such as:
cropView.setImageURI(imageFileUri);
cropView.setViewportRatio(viewportRatioValue);
The only time the TouchManager's setViewport()
code is called is when the we set the viewport. However at this state, the bitmap width/height is 0 (because the Bitmap isn't loaded yet), so we get an imageAspect of NaN, making our viewport non-existent.
Hi @davidbeloosesky , @eveliotc
I am trying to load an image into the cropview but it does not show up. I pass a string extra to my crop image activity.
I then try to load it into the cropview using the following
@AfterViews
void setupUI() {
if (getIntent().getExtras() != null) {
if (getIntent().getExtras().getString(KEY_IMAGE_FILE_PATH) != null) {
cropView.extensions()
.load(Uri.fromFile(new File(getIntent().getStringExtra(KEY_IMAGE_FILE_PATH))));
}
}
}
The value of the string on debugging is
/storage/emulated/0/Pictures/PrismApp/Current/96adeca7-79a3-4cf9-bc1c-8c736bb26ee2.jpg
Why does the image not show up? Am I using the api wrong or is it a bug?
I have even tried removing the Uri.fromFile bit and directly loading a File.
I am not using the
cropView.extensions().load(galleryPictureUri);
Instead, I am using my own intent and request code to launch my CropImageActivity before returning to my current activity.
Such as:circle,4_3 , 3_4 , 16_9.
Question: I was wondering if you need to add any ProGuard rules to use this library.
FYI: I did find https://github.com/lyft/scissors/blob/master/scissors/proguard-rules.txt - but it contains rules for dependencies.
I'm planning to use following rules, is it sufficient?
-dontwarn com.lyft.android.scissors.**
-keep class com.lyft.android.scissors.** { *; }
-keep interface com.lyft.android.scissors.** { *; }
I tested my app on a Sony Ericsson Xperia S. It is using scissors to select images to crop before adding them.
I have used the selection as shown in the sample app.
cropView.extensions().pickUsing (this,REQ_CODE)
This works perfectly well on other devices that I have tested it on - Xiaomi, Samsung s3, Galaxy S4.
However on the Sony Ericsson Xperia S, when I select an image to crop, many times the cropView does not load the image instead the selection prompt pops up again. Is this related to the other load issue?
First of all, this is a question, but sorry, I don't know how to add the label to it.
Hi, from what I've seen, this library is useful to select an image from the fallery and then crop it. Is there a way to open the device's camera, take a picture, and then crop it? If so, can you tell me how?
Thanks!
I'm following your method for cropping.So I would like to remove the scale feature from this method.May I know how I can remove the scaling ?
Trying to crop into file using scissors 1.1.1 and i get the following error when compiling
Error:(49, 22) Cannot access 'CropViewExtensions': it is public/package/ in 'com.lyft.android.scissors'
The code in question is basically the same as the example provided.
mCropView.extensions()
.crop()
.quality(87)
.format(PNG)
.into(file)
Hi, I have an issue, when I move image to maximum right and then crop him, there's a white place. Can you help me please?
No resource identifier found for attribute 'cropviewViewportOverlayPadding' in package .Why use android studio to add dependency can not find this attribute.
can't import scissors 2 using gradle with com.lyft:scissors:2.0.0-SNAPSHOT
I've been seeing some crashes come in with the following error message:
Permission Denial: reading com.android.providers.media.MediaProvider uri content://media/external/images/media/1037 from pid=23237, uid=10079 requires android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission()
This happens after I call cropView.extensions().pickUsing(...)
, but I can't seem to reproduce it on any of my devices.
Thanks in advance!
I want cropped coordinates on original image. Is it possible with this library?
My guess is that your java-code-styles
repo is private, but regardless this is a broken link:
https://github.com/lyft/java-code-styles
I would love to start contributing and wanted to respect existing convention, but the code style isn't publicly available.
The current CropViewConfig
mechanism really cleans up attribute parsing, but also greatly limits the view since it can only be configured via xml. Want to programmatically create a view with non-default options? No, thank you.
I think we need standard getters/setters on the CropView object so that we can not only programmatically configure the view, but also alter the view at runtime (like allowing the user to choose from standard aspect ratios.
Front page code directs to set app:cropviewViewportHeightRatio="1" when that parameter no longer exists. I think the correct entry is app:cropviewViewportRatio="1" to function correctly. The crop aspect appears to be correct, is there any issues with setting this?
The following code:
cropView
.extensions()
.using(GlideBitmapLoader.createUsing(cropView))
.load(uri)
won't work if cropView
is not yet laid out – even with #16 in – because GlideBitmapLoader.createUsing
directly extracts cropView.getHeight()
and cropView.getWidth()
: https://github.com/lyft/scissors/blob/master/scissors/src/main/java/com/lyft/android/scissors/GlideBitmapLoader.java#L57-L61. At this point, cropView's dimension is 0:0.
I worked around this by adding a 100ms delay, but that's obviously hacky.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.