Search Unity

Creative [RELEASED] Image Cropper - multiplatform image cropping solution with oval mask support

Discussion in 'Tools In Progress' started by yasirkula, Apr 15, 2018.

  1. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    I'm guessing you need to add
    markTextureNonReadable = false,
    to Settings parameter.
     
  2. gaglabs

    gaglabs

    Joined:
    Oct 17, 2019
    Posts:
    185
    Thats what i did.
    Texture2D _texture = NativeGallery.LoadImageAtPath(_path, -1, false, false);
     
  3. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    I mean the ImageCropper.Settings object.
     
  4. gaglabs

    gaglabs

    Joined:
    Oct 17, 2019
    Posts:
    185
    Ahhh i see, where it says
    result.Apply( false, MarkTextureNonReadable );


    make it
    result.Apply( false, false );
     
  5. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    Code (CSharp):
    1. settings: new ImageCropper.Settings()
    2. {
    3.     ovalSelection = ovalSelection,
    4.     autoZoomEnabled = autoZoom,
    5.     imageBackground = Color.clear,
    6.     selectionMinSize = new Vector2(512,512),
    7.     selectionMaxSize = new Vector2(512,512),
    8.     markTextureNonReadable = false,
    9. },
     
  6. gaglabs

    gaglabs

    Joined:
    Oct 17, 2019
    Posts:
    185
    I just changed it in the ImageCropper.cs where is says result.apply. that worked great. thanks Yas
     
    yasirkula likes this.
  7. swifter14

    swifter14

    Joined:
    Mar 2, 2017
    Posts:
    165
    I like the way you can choose the size and resize the final result. Is there a way to scale it to 2 different sizes, 2 textures? In my app I need to get 2 textures, one is half the size, and the second is very low (30x30). Or is there a way to use your scaling function by a given texture? So far I do it manually, getting the cropped image, and then use TextureScale.Bilinear, but the quality is very bad when scaling to 30x30, it gets blurry. I think your scaling function is better
     
  8. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    I don't actually have a resize algorithm. I just create a RenderTexture of specified size and the camera renders to that texture. I think the easiest solution here would be to modify ImageCropper.Crop function so that after the "
    Texture2D result = CropSelection();
    " line, it also calls "
    Texture2D resultSmall = CropSelection(30,30);
    " and then passes that texture to the callback function, as well. You'll need to change the delegate as follows:
    public delegate void CropResult(bool result, Texture originalImage, Texture2D croppedImage, Texture2D croppedImageSmall);
     
    swifter14 likes this.
  9. Raghavendra

    Raghavendra

    Joined:
    Mar 14, 2014
    Posts:
    52
    Hi @yasirkula, Thanks for all your plugins. Is there any way I can capture and save part of the camera that is rendering? The rendering area of the camera keeps on changing depending on the level, so there is no way for me to give any fixed values while saving. So, is there any way I can do it? Consider it as me cropping the image without giving the user a manual option to do it. Thanks
     
  10. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    Hi! Googling "unity partial screenshot" should yield useful results in this case.
     
  11. taira20

    taira20

    Joined:
    Aug 7, 2018
    Posts:
    2
    How can i use this code. i want save the crop image from in some folder.
     
  12. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    See markTextureNonReadable here and apply the code you've quoted to the Texture returned by image cropper.
     
  13. taira20

    taira20

    Joined:
    Aug 7, 2018
    Posts:
    2
    can i ask where can i find the texture returned in image cropper script. thanks
     
  14. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    It is returned by ImageCropper.Instance.Show's
    CropResult onCrop
    callback function. You can check out ImageCropperDemo.cs example script to see it in action.
     
  15. EmilCoehl

    EmilCoehl

    Joined:
    Jan 29, 2021
    Posts:
    9
    Hi @yasirkula ! Thanks for the asset!
    I use it in custom window and selection rect conflicting with fadeoverlay. This happens when I zoom in image and then dragging selection rect to larger part.
    How can I fix that ?
    upload_2021-4-27_19-21-2.png
     
  16. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    Probably some RectTransform values in your custom UI doesn't match the values in ImageCropper prefab which this plugin expects. You need to compare your RectTransform values with ImageCropper's values (anchors, pivots, offsets). Or you can disable auto-zoom feature.
     
  17. EmilCoehl

    EmilCoehl

    Joined:
    Jan 29, 2021
    Posts:
    9
    I changed FadeOverlayGraphic's base class from Grahpics to Maskablegraphics and the problem was solved.
    Thanks
     
    yasirkula likes this.
  18. siva7170

    siva7170

    Joined:
    Sep 2, 2021
    Posts:
    1
    hi, i m struggling with oval shape cropping. When i tried in unity editor, the oval shape is come with transparent background. But in the real device and android emulator, the cropped image come with black transparent.

    I used below cropped settings,

    Code (CSharp):
    1.          settings: new ImageCropper.Settings()
    2.          {
    3.              ovalSelection = true,
    4.              autoZoomEnabled = true,
    5.              imageBackground = Color.clear,
    6.              selectionMinAspectRatio = 1f,
    7.              selectionMaxAspectRatio = 1f,
    8.              markTextureNonReadable = false
    9.          },
    Is there anything do with image cropper? Please assist me
     

    Attached Files:

  19. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    Are you using URP/HDRP? I can't see anything wrong with your code.
     
  20. seyit25

    seyit25

    Joined:
    Sep 28, 2018
    Posts:
    13
    Hi Yasir,

    I want the size of the rectangle on boot to be the same as the size of the image. In other words, if the user does not resize, I want the image to be used exactly. How can I do it?
     
  21. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    dazaizone and seyit25 like this.
  22. seyit25

    seyit25

    Joined:
    Sep 28, 2018
    Posts:
    13
    Thank you, you are a good man.
     
    yasirkula likes this.
  23. seyit25

    seyit25

    Joined:
    Sep 28, 2018
    Posts:
    13
    Hello Yasir, I was going to ask something;
    I want the size of the frame we resize to always be square, the user just enlarges or shrinks this square, not rectangular. How can I do it?
     
  24. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    Hi, you can set both selectionMinAspectRatio and selectionMaxAspectRatio to 1 (these are variables of Settings settings parameter).
     
    dazaizone and seyit25 like this.
  25. seyit25

    seyit25

    Joined:
    Sep 28, 2018
    Posts:
    13
    Thanks, it is working, perfect.
     
    yasirkula likes this.
  26. RestlessSwords

    RestlessSwords

    Joined:
    May 9, 2021
    Posts:
    26
    I downloaded your Unity asset, and inside its plugin the demo runs fine.

    But out in my main project, in my main scripts folder, i cannot access the ImageCropper.Instance
    - what do need to do to access it in a script outside your plugins directory ?

     
  27. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    Can you try Edit-Preferences-External Tools-Regenerate project files? If you're using Assembly Definition Files, you need to add reference to ImageCropper's own Assembly Definition File, as well.
     
  28. RestlessSwords

    RestlessSwords

    Joined:
    May 9, 2021
    Posts:
    26
    Yes, thanks, that was exactly what was needed, it complies fine now.
     
    yasirkula likes this.
  29. Arunaru

    Arunaru

    Joined:
    Mar 31, 2021
    Posts:
    3
    I have issue with HDRP scene, when crop the image its appearing dark compare to original image
    Do you have any solution for this ? please help me out
    upload_2022-7-6_16-55-10.png
     
    Last edited: Jul 6, 2022
  30. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    @Arunaru After some testing, I've figured it out. Post processing darkens the cropped image because it's captured via an internal camera (that is affected by post processing by default). To fix this, you should open ImageCropper prefab and set the CropRenderCamera object's Camera.Environment.VolumeMask property to Nothing.
     
  31. Arunaru

    Arunaru

    Joined:
    Mar 31, 2021
    Posts:
    3
    @yasirkula Awesome its worked perfect, Thank you so much :)
     
    yasirkula likes this.
  32. MohsenJamaliL

    MohsenJamaliL

    Joined:
    Nov 13, 2017
    Posts:
    12
    Hi
    Is it possible to customize the cropping phase such as translating the words in another language
     
  33. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    @MohsenJamaliL Hi, this can be achieved only by modifying the ImageCropper prefab.
     
  34. MohsenJamaliL

    MohsenJamaliL

    Joined:
    Nov 13, 2017
    Posts:
    12
    Thanks. Appreciated!
     
    yasirkula likes this.
  35. unity_12191726

    unity_12191726

    Joined:
    Sep 16, 2022
    Posts:
    1
    Hello, I'm not sure if I'm doing it right because it's my first time asking.
    After I cut the image, I want to save it on my Android phone.
    Can I possibly know how?
     
  36. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
  37. k0995249667sv

    k0995249667sv

    Joined:
    Oct 3, 2022
    Posts:
    3
    Hello. Thanks for the greate assets! I have a truble on Android, when call ImageCropper.Instance.Show(). It works greate in unity playmode, but in .apk build nothing happens. Do you know, why can this be?
     
  38. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    @k0995249667sv Hi! Can you check Android Logcat logs for error messages? And please put a Debug.Log before and after ImageCropper.Instance.Show and see if both of them are logged to logcat.
     
  39. k0995249667sv

    k0995249667sv

    Joined:
    Oct 3, 2022
    Posts:
    3
    Much thanks for answering. I'll check this up as soon as possible)
     
  40. k0995249667sv

    k0995249667sv

    Joined:
    Oct 3, 2022
    Posts:
    3
    I think I got it. It started to work, when I add delay like 1-2 seconds between loading image from gallery (by NativeGalery) and ImageCropper.Instance.Show. I can`t now debug it via LogCat, cause working on remote pc.
    If you know, what callback I need to wait, for full loading image with NativeGalery

    Code (CSharp):
    1. using UnityEngine;
    2. using TMPro;
    3. using System.Collections.Generic;
    4. using System.Collections;
    5.  
    6. public class UploadImage : MonoBehaviour
    7. {
    8.     [SerializeField] private SpriteRenderer _spriteRenderer;
    9.     [SerializeField] private TMP_Text _errorText;
    10.  
    11.     private Sprite _sprite;
    12.     private Texture2D _texture;
    13.  
    14.     public void LoadImage()
    15.     {
    16.         NativeGallery.Permission permission = NativeGallery.GetImageFromGallery((path) =>
    17.        {
    18.            Debug.Log("Image path: " + path);
    19.            if (path != null)
    20.            {
    21.                Texture2D texture = NativeGallery.LoadImageAtPath(path);
    22.                if (texture == null)
    23.                {
    24.                    Debug.Log("Can`t load from " + path);
    25.                    StartCoroutine(ErrorMessage());
    26.                    return;
    27.                }
    28.                _texture = texture;
    29.                StartCoroutine(Delay());
    30.            }
    31.        });
    32.  
    33.         Debug.Log("Result: " + permission);
    34.     }
    35.  
    36.     private void CropImage()
    37.     {
    38.         if (_texture == null)
    39.             LoadImage();
    40.  
    41.  
    42.         Debug.LogWarning("START CROPPING");
    43.         ImageCropper.Instance.Show(_texture, (bool result, Texture originalImage, Texture2D croppedImage) =>
    44.         {
    45.             if (result)
    46.             {
    47.                 _sprite = Sprite.Create(croppedImage, new Rect(0, 0, croppedImage.width, croppedImage.height), new Vector2(0.5f, 0.5f));
    48.                 _spriteRenderer.sprite = _sprite;
    49.                 _spriteRenderer.color = Color.white;
    50.                 Debug.LogWarning("NICE CROP");
    51.             }
    52.             else
    53.             {
    54.                 _sprite = null;
    55.                 StartCoroutine(ErrorMessage());
    56.                 Debug.LogWarning("CROP ERROR");
    57.             }
    58.  
    59.             Destroy(_texture);
    60.             Debug.LogWarning("CROP FINISH");
    61.         },
    62.             settings: new ImageCropper.Settings()
    63.             {
    64.                 ovalSelection = true,
    65.                 autoZoomEnabled = true,
    66.                 imageBackground = Color.clear,
    67.             },
    68.             croppedImageResizePolicy: (ref int width, ref int height) =>
    69.             {
    70.                 width = 100;
    71.                 height = 100;
    72.             });
    73.  
    74.     }
    75.  
    76.     public void SetSprite()
    77.     {
    78.         LoadImage();
    79.     }
    80.  
    81.     private IEnumerator ErrorMessage()
    82.     {
    83.         yield return new WaitForEndOfFrame();
    84.         _errorText.gameObject.SetActive(true);
    85.  
    86.         yield return new WaitForSeconds(3);
    87.         _errorText.gameObject.SetActive(false);
    88.     }
    89.  
    90.     private IEnumerator Delay()
    91.     {
    92.         yield return new WaitForSeconds(1);
    93.         CropImage();
    94.     }
    95. }
     
  41. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    You might've called CropImage in a wrong location before. I'd recommend replacing "StartCoroutine(Delay());" with CropImage().
     
  42. Farshadfarzan368

    Farshadfarzan368

    Joined:
    Sep 10, 2022
    Posts:
    73
    I want the output to be square. When cutting the shadow is a circle.

    How to enter circle shadow while I want the output image to be square

    my setting is
    settings: new ImageCropper.Settings()
    {
    ovalSelection = false,
    autoZoomEnabled = true,
    imageBackground = Color.clear,
    selectionMinAspectRatio = 1f,
    selectionMaxAspectRatio = 1f,
    markTextureNonReadable = false,

    },
    no circle shadow;
    or
    settings: new ImageCropper.Settings()
    {
    ovalSelection = true,
    autoZoomEnabled = true,
    imageBackground = Color.clear,
    selectionMinAspectRatio = 1f,
    selectionMaxAspectRatio = 1f,
    markTextureNonReadable = false,

    },

    no output square;
     
  43. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    @Farshadfarzan368 Hi, you'll need to modify the source code and set OvalSelection to false inside CropSelection function. In theory, it should work.
     
    Farshadfarzan368 likes this.
  44. Farshadfarzan368

    Farshadfarzan368

    Joined:
    Sep 10, 2022
    Posts:
    73
    Hello, why does the quality decrease? The size is the same.
    use encodetojpg(100);
    Quality decreases during import
     

    Attached Files:

    Last edited: Feb 24, 2023
  45. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    Can you show me the section of the ImageCropper code that causes this issue? EncodeToJPG is Unity's own function so I'm a little confused.
     
  46. Farshadfarzan368

    Farshadfarzan368

    Joined:
    Sep 10, 2022
    Posts:
    73
    Open photo in gallery and send to open photo
    fix size for all photo and open image for crop
    public void OpenPhoto(Texture2D texture2D)
    {
    float cy = Canvas.GetComponent<RectTransform>().sizeDelta.y;
    float cx = Canvas.GetComponent<RectTransform>().sizeDelta.x;
    child.GetComponent<RectTransform>().sizeDelta = new Vector2(texture2D.width, texture2D.height);
    child.GetComponent<RawImage>().texture = texture2D;
    if (child.GetComponent<RectTransform>().sizeDelta.x > cx || child.GetComponent<RectTransform>().sizeDelta.y > cy)
    {
    float x = child.GetComponent<RectTransform>().sizeDelta.x;
    float y = child.GetComponent<RectTransform>().sizeDelta.y;
    if (x > y)
    {
    float nesbat = x / y;
    for (int i = 0; i >= 0; i++)
    {
    x -= 1 * nesbat;
    y -= 1;
    if (x < cx && y < cy)
    break;
    }
    child.GetComponent<RectTransform>().sizeDelta = new Vector2(x, y);
    }
    else if (y > x)
    {
    float nesbat = y / x;
    for (int i = 0; i >= 0; i++)
    {
    x -= 1;
    y -= 1 * nesbat;
    if (x < cx && y < cy)
    break;
    }
    child.GetComponent<RectTransform>().sizeDelta = new Vector2(x, y);
    }
    }
    parent.gameObject.SetActive(true);
    Crop();
    }

    to jpg byte

    byte[] photobyte = croppedImage.EncodeToJPG(100))


    I think it is reduced to adjust the size of the photo and then it is zoomed and this reduces the quality. How to display the photo in its own size without reducing the quality?
     
    Last edited: Feb 24, 2023
  47. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    You should save the image as PNG instead of JPG if you don't want it to lose quality.
     
  48. Farshadfarzan368

    Farshadfarzan368

    Joined:
    Sep 10, 2022
    Posts:
    73
    Thank you, there is no change, it has nothing to do with the output, there is a drop in quality when entering.
     
  49. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    Unfortunately I'm unsure what's causing this issue for you :(
     
    Farshadfarzan368 likes this.
  50. Farshadfarzan368

    Farshadfarzan368

    Joined:
    Sep 10, 2022
    Posts:
    73
    Thank you, it works perfectly. The difference is very small, you can be indifferent
     
    yasirkula likes this.