androidimageandroid-studiokotlin

Image cropper Android Studio Kotlin


I'm newbie and I need help I can't resolve problem i don't know what to do. Very confusing it and need help (if you explain about it i'm very very thank you).

I watching Kotlin Project - Kotlin Android Instagram Clone using Firebase - Kotlin Instagram Clone

He using ArthurHub/Android-Image-Cropper (but it is old version right ?), I find some new version is CanHub/Android-Image-Cropper.

I don't have this code like him

CropImage.activity() .setAspectRatio(1,1) .start(this@AccountSettingsActivity)

what to do?

I can't use this code and i don't know how to resolve this problem, be utterly mystified.

Help me please Thank you very much. Best regards.

(you can blame me, but not harsh i'm Newbie and I don't know)

I need help I can't resolve problem i don't know what to do. Very confusing it and need help


Solution

  • Since you said you're new I'll help you understand what the project page's example usage is showing you. I can only do this in general, I don't have time to go actually creating an example project to test it myself.

    If you run into any issues, you'll have to puzzle it out - that's a big part of coding! It's rare that you'll get a nice simple solution that drops neatly into whatever you're doing, and learning how to make it work for you is an important skill to develop.

    If you're ever stuck, always look at the project page (in this case the Github page) for a user guide, and they have a sample project in the repository too, so you can see how it works inside a full app. Don't be afraid to look at it, even if you don't understand it all - the more you do this the more you'll understand


    Anyway, here are their examples:

    Calling crop directly

    class MainActivity {
      private val cropImage = registerForActivityResult(CropImageContract()) { result ->
        if (result.isSuccessful) {
          // Use the returned uri.
          val uriContent = result.uriContent
          val uriFilePath = result.getUriFilePath(context) // optional usage
        } else {
          // An error occurred.
          val exception = result.error
        }
      }
    

    I'm going to break the code up here - this first bit is showing you're doing this inside an Activity. You're creating a cropImage object, which is an Activity launcher provided by registerForActivityResult - you're going to call launch on that later to start your cropping Activity.

    The lambda in the curly braces is the function that's going to run when you get a result back - this is where you actually do something with the cropped image. In this case they're getting URIs to the image - I don't know what you need, but you can google "get bitmap from URI" or whatever if you need something else.

    This whole getResultFromActivity thing is part of the AndroidX Activity and Fragment libraries - if you want to do it this way, you'll need those (and it's a good idea to use them on every project anyway, AndroidX stuff gives you backwards compatibility and saves you work).

    Once you've set that up, you can call launch on cropImage to open your cropping Activity. It looks like they're giving you three examples, with different options (you could combine the options, but you only call launch once):

    private fun startCrop() {
        // Start picker to get image for cropping and then use the image in cropping activity.
        cropImage.launch(
          options {
            setGuidelines(Guidelines.ON)
          }
        )
    

    They're putting these in a startCrop() function you can call from, say, a button click listener. This one's setting some guideline options on the launched Activity - and like the comment says, it opens an image picker so the user can select an image.

        // Start picker to get image for cropping from only gallery and then use the image in cropping activity.
        cropImage.launch(
          options {
            setImagePickerContractOptions(
              PickImageContractOptions(includeGallery = true, includeCamera = false)
            )
          }
        )
    

    This one (again, like the comment says - this stuff is there to help you) is setting some options on the picker instead, specifically limiting the choice to gallery images.

        // Start cropping activity for pre-acquired image saved on the device and customize settings.
        cropImage.launch(
          options(uri = imageUri) {
            setGuidelines(Guidelines.ON)
            setOutputCompressFormat(CompressFormat.PNG)
          }
        )
    

    This one does a few things: passes the URI of an image to crop (instead of opening a picker for the user to choose), adds guidelines, and sets the output format for the resulting cropped image.

    Remember, these are all examples of the different ways you might use this. You can combine options, depending on how you want to configure things - you're setting options before you launch the cropping Activity.


    Using CropView

    This one looks like it uses a custom View you can add to a layout, which lets you crop an image:

    // Add CropImageView into your activity
    
    <!-- Image Cropper fill the remaining available height -->
    <com.canhub.cropper.CropImageView
      android:id="@+id/cropImageView"
      android:layout_width="match_parent"
      android:layout_height="0dp"
      android:layout_weight="1"
      />
    

    So you add this to your Activity's layout (might work on Fragments too, maybe with some tweaking - I'm not testing it remember!). The sizing isn't important - you can work out how to make a view as big as you want it to be. It's just a normal View in a layout.

    //Set image to crop
    cropImageView.setImageUriAsync(uri)
    // Or prefer using uri for performance and better user experience.
    cropImageView.setImageBitmap(bitmap)
    

    In the Activity, with a reference to the CropImageView in your layout, you call this set image function with the URI of an image you want to use. Or, if you have it, you can set a Bitmap directly. Once it's set on the CropImageView, the user can adjust it

    // Subscribe to async event using cropImageView.setOnCropImageCompleteListener(listener)
    cropImageView.getCroppedImageAsync()
    // Or.
    val cropped: Bitmap = cropImageView.getCroppedImage()
    

    Now this one's a bit trickier - to me, it's not completely obvious how you're supposed to use that first one. So let's actually look at the code in CropImageView, where we can see how it works and read the documentation.

    Surprise! There is no getCroppedImageAsync() function, just a croppedImageAsync one (without the get) that looks like it does the same thing. That's fine. If you're using an IDE like Android Studio, it'll probably suggest the right function as you type, and you can read the documentation right there:

    * Cropped image based on the current crop window to the given uri.
    * The result will be invoked to listener set by [setOnCropImageCompleteListener].
    

    Ok, that looks like what the example is hinting at. You call setOnCropImageCompleteListener with a function to do something with the resulting image, like this:

    cropImageView.setOnCropImageCompleteListener { view, result ->
        // do something with cropped result
    }
    

    and then you call croppedImageAsync (with whatever option parameters you want, check the docs) to start the crop-and-store process. When it's done, that callback function you just set will be called with the result.


    And then there's the custom Activity example but that's enough for me - if you really want that, if you can follow what we've gone over so far you should be able to work out the rest.

    Since you're already making an app following a tutorial, and it's using a different library (with a different way of doing things) you'll have to work out how to fit this library into your own project. Take a step back and look at what you're doing in the tutorial, what you're trying to achieve (like launching a cropping Activity), and work out how you'd achieve the same task in this library.

    A lot of software development is about trying to fit different pieces together like this, and it rarely goes smoothly. Not knowing what you're doing is normal! But then you have to sit down and work it out. Hopefully that gives you an idea of an approach you can take to learning - and there is a lot to learn at first!