RepoPilotOpen in app →

Yalantis/uCrop

Image Cropping Library for Android

Mixed

Slowing — last commit 9mo ago

weakest axis
Use as dependencyConcerns

no license — legally unclear; no tests detected…

Fork & modifyConcerns

no license — can't legally use code; no tests detected…

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isConcerns

no license — can't legally use code; last commit was 9mo ago…

  • Last commit 9mo ago
  • 31+ active contributors
  • Distributed ownership (top contributor 31% of recent commits)
Show all 7 evidence items →
  • Slowing — last commit 9mo ago
  • No license — legally unclear to depend on
  • No CI workflows detected
  • No test directory detected
What would change the summary?
  • Use as dependency ConcernsMixed if: publish a permissive license (MIT, Apache-2.0, etc.)
  • Fork & modify ConcernsMixed if: add a LICENSE file
  • Deploy as-is ConcernsMixed if: add a LICENSE file

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Great to learn from" badge

Paste into your README — live-updates from the latest cached analysis.

RepoPilot: Great to learn from
[![RepoPilot: Great to learn from](https://repopilot.app/api/badge/yalantis/ucrop?axis=learn)](https://repopilot.app/r/yalantis/ucrop)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/yalantis/ucrop on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: Yalantis/uCrop

Generated by RepoPilot · 2026-05-09 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/Yalantis/uCrop shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

WAIT — Slowing — last commit 9mo ago

  • Last commit 9mo ago
  • 31+ active contributors
  • Distributed ownership (top contributor 31% of recent commits)
  • ⚠ Slowing — last commit 9mo ago
  • ⚠ No license — legally unclear to depend on
  • ⚠ No CI workflows detected
  • ⚠ No test directory detected

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live Yalantis/uCrop repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/Yalantis/uCrop.

What it runs against: a local clone of Yalantis/uCrop — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in Yalantis/uCrop | Confirms the artifact applies here, not a fork | | 2 | Default branch develop exists | Catches branch renames | | 3 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 4 | Last commit ≤ 304 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>Yalantis/uCrop</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of Yalantis/uCrop. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/Yalantis/uCrop.git
#   cd uCrop
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of Yalantis/uCrop and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "Yalantis/uCrop(\\.git)?\\b" \\
  && ok "origin remote is Yalantis/uCrop" \\
  || miss "origin remote is not Yalantis/uCrop (artifact may be from a fork)"

# 3. Default branch
git rev-parse --verify develop >/dev/null 2>&1 \\
  && ok "default branch develop exists" \\
  || miss "default branch develop no longer exists"

# 4. Critical files exist
test -f "ucrop/src/main/java/com/yalantis/ucrop/UCrop.java" \\
  && ok "ucrop/src/main/java/com/yalantis/ucrop/UCrop.java" \\
  || miss "missing critical file: ucrop/src/main/java/com/yalantis/ucrop/UCrop.java"
test -f "ucrop/src/main/java/com/yalantis/ucrop/UCropActivity.java" \\
  && ok "ucrop/src/main/java/com/yalantis/ucrop/UCropActivity.java" \\
  || miss "missing critical file: ucrop/src/main/java/com/yalantis/ucrop/UCropActivity.java"
test -f "ucrop/src/main/java/com/yalantis/ucrop/view/GestureCropImageView.java" \\
  && ok "ucrop/src/main/java/com/yalantis/ucrop/view/GestureCropImageView.java" \\
  || miss "missing critical file: ucrop/src/main/java/com/yalantis/ucrop/view/GestureCropImageView.java"
test -f "ucrop/src/main/java/com/yalantis/ucrop/task/BitmapCropTask.java" \\
  && ok "ucrop/src/main/java/com/yalantis/ucrop/task/BitmapCropTask.java" \\
  || miss "missing critical file: ucrop/src/main/java/com/yalantis/ucrop/task/BitmapCropTask.java"
test -f "ucrop/src/main/jni/uCrop.cpp" \\
  && ok "ucrop/src/main/jni/uCrop.cpp" \\
  || miss "missing critical file: ucrop/src/main/jni/uCrop.cpp"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 304 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~274d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/Yalantis/uCrop"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

uCrop is an Android image cropping library that provides a UI-driven, interactive crop experience with support for custom aspect ratios, maximum output dimensions, and compression options. It wraps image manipulation in UCropActivity (an Android Activity component) and optionally uses native C++ code for lossless image quality preservation during crop operations. The project is a library module (ucrop/) with a companion sample/ app. Core logic lives in sample/src/main/java/com/yalantis/ucrop/ with UCropActivity orchestrating UI, CropImageView handling gesture/canvas rendering, and optional native bindings in C++. Configuration flows through the UCrop builder class using the builder pattern.

👥Who it's for

Android app developers building photo editing or profile picture upload features who need a polished, customizable cropping interface without writing their own gesture detection, canvas rendering, and image transformation logic.

🌱Maturity & risk

Production-ready. The library is published on JitPack and Google Play (sample app has real users), uses modern AndroidX dependencies (activity 1.10.1, appcompat 1.7.1, core 1.16.0), and supports multiple implementation flavors (lightweight pure-Java vs. native-accelerated). However, commit recency and active maintenance status are not visible in provided metadata.

Low-to-moderate risk. The codebase is primarily Java (230KB) with small native layer (3.7KB C++), minimizing platform-specific fragility. Main risks: single-organization ownership (Yalantis), no visible CI/CD config in file list, and dependency on AndroidX ecosystem (which is actively maintained by Google but requires API level 14+). Breaking changes unlikely given stable 2.x versioning.

Active areas of work

No commit or PR data visible in provided metadata. The README and gradle config suggest ongoing maintenance (modern Gradle 8.11.1, recent AndroidX versions as of this snapshot), but specific active work items are not evident from the file listing alone.

🚀Get running

git clone https://github.com/Yalantis/uCrop.git
cd uCrop
./gradlew assembleDebug  # Build the library
./gradlew sample:assembleDebug  # Build sample app
./gradlew sample:installDebug  # Install on connected device/emulator

Daily commands: No traditional dev server. To test: ./gradlew sample:installDebug && adb shell am start -n com.yalantis.ucrop.sample/.SampleActivity (assumes Android device/emulator connected). Library itself is built via ./gradlew assembleDebug.

🗺️Map of the codebase

  • ucrop/src/main/java/com/yalantis/ucrop/UCrop.java — Main entry point and API facade for the cropping library; defines how applications integrate uCrop
  • ucrop/src/main/java/com/yalantis/ucrop/UCropActivity.java — Core activity that manages the cropping UI and handles user interactions; every crop operation flows through here
  • ucrop/src/main/java/com/yalantis/ucrop/view/GestureCropImageView.java — Handles all gesture recognition and image manipulation logic; critical for smooth user interaction and animation
  • ucrop/src/main/java/com/yalantis/ucrop/task/BitmapCropTask.java — Performs the actual image cropping operation using JNI; bridges Java and native C++ code for performance
  • ucrop/src/main/jni/uCrop.cpp — Native C++ implementation for high-performance bitmap cropping and transformation operations
  • ucrop/src/main/java/com/yalantis/ucrop/util/BitmapLoadUtils.java — Handles efficient image loading, scaling, and memory management; prevents OOM errors on large images
  • ucrop/build.gradle — Defines library dependencies, build configuration, and NDK setup for native compilation

🛠️How to make changes

Add a New Aspect Ratio Option

  1. Define aspect ratio in sample activity or your implementation (sample/src/main/java/com/yalantis/ucrop/sample/SampleActivity.java)
  2. Create an AspectRatio model instance with your dimensions (ucrop/src/main/java/com/yalantis/ucrop/model/AspectRatio.java)
  3. Pass aspect ratios to UCrop builder via withAspectRatio() or withAspectRatios() (ucrop/src/main/java/com/yalantis/ucrop/UCrop.java)
  4. Optional: customize UI in include_settings.xml for aspect ratio buttons (sample/src/main/res/layout/include_settings.xml)

Customize Output Crop Parameters

  1. Create or modify CropParameters with output dimensions and quality (ucrop/src/main/java/com/yalantis/ucrop/model/CropParameters.java)
  2. Configure via UCrop builder using withOutputCropOptions() (ucrop/src/main/java/com/yalantis/ucrop/UCrop.java)
  3. Output size and format are applied during BitmapCropTask execution (ucrop/src/main/java/com/yalantis/ucrop/task/BitmapCropTask.java)

Handle Crop Result and Save Cropped Image

  1. Override onActivityResult() in your activity to receive the cropped URI (sample/src/main/java/com/yalantis/ucrop/sample/SampleActivity.java)
  2. Check UCrop.RESULT_ERROR or handle successful crop with getOutput() (ucrop/src/main/java/com/yalantis/ucrop/UCrop.java)
  3. Load and display the cropped bitmap using the returned URI (sample/src/main/java/com/yalantis/ucrop/sample/ResultActivity.java)
  4. FileUtils handles writing the cropped image to disk (ucrop/src/main/java/com/yalantis/ucrop/util/FileUtils.java)

Configure Advanced Image Loading Settings

  1. Use BitmapLoadUtils to set image sampling and memory constraints (ucrop/src/main/java/com/yalantis/ucrop/util/BitmapLoadUtils.java)
  2. Enable EXIF rotation handling via ImageState.setExifInfo() (ucrop/src/main/java/com/yalantis/ucrop/model/ImageState.java)
  3. BitmapLoadTask applies these settings during async image load (ucrop/src/main/java/com/yalantis/ucrop/task/BitmapLoadTask.java)

🪤Traps & gotchas

  1. Native flavor (ucrop:2.2.11-native) adds ~1.5 MB to APK—clarify with stakeholders if needed. 2. UCropActivity must be declared in AndroidManifest.xml with android:screenOrientation="portrait" and correct theme; omitting this causes silent crashes. 3. ExifInterface (1.4.1) handles image rotation metadata—if source image has EXIF orientation tag, it's automatically applied; test with rotated photos. 4. No explicit minSdkVersion visible in snippet; AndroidX dependencies imply API 14+, but verify in actual library build.gradle. 5. Result handling requires checking both RESULT_OK and UCrop.RESULT_ERROR; missing error check can crash with null pointer on UCrop.getError().

🏗️Architecture

💡Concepts to learn

  • ExifInterface metadata and image rotation — uCrop uses ExifInterface (androidx.exifinterface:exifinterface:1.4.1) to detect and apply stored EXIF orientation tags; misunderstanding this can cause crops on rotated photos to be applied in unexpected directions
  • ActivityResultLauncher and result contracts — uCrop returns results via ActivityResultLauncher (modern replacement for onActivityResult); the callback must handle both RESULT_OK and UCrop.RESULT_ERROR codes
  • Canvas custom rendering and GestureDetector — CropImageView uses Android Canvas for real-time preview rendering and GestureDetector for pan/zoom/rotate gestures; understanding touch event flow is key to modifying UI behavior
  • Content URI and FileProvider — uCrop accepts source and destination URIs (not just file paths); integration with FileProvider is required for Android 7.0+ file access permissions
  • JNI (Java Native Interface) and native image processing — The native flavor uses C++ via JNI for high-fidelity image scaling/cropping; understanding JNI boundaries helps debug native crashes or integrate custom filters
  • Builder pattern and fluent API — uCrop configuration (aspect ratio, max size, compression) flows through UCrop.of(...).with*().start(); misunderstanding builder chaining can lead to silent config drops
  • JPEG vs. PNG compression quality and lossiness — uCrop allows setting compression quality (0-100) and format (JPEG, PNG); PNG ignores quality (lossless), JPEG respects it; choosing the wrong format wastes storage or degrades quality unexpectedly
  • zetbaitsu/Compressor — Companion library for post-crop image compression/optimization; often used after uCrop returns the result URI
  • square/picasso — Image loading & caching for Android; often paired with uCrop to fetch source image and display cropped result
  • wasabeef/Android-ImageEffects — Provides additional image filters (blur, grayscale) that can be chained after cropping
  • ArthurHub/Android-Image-Cropper — Direct alternative image cropping library with similar feature set (aspect ratio, compression, customization)
  • android/architecture-samples — Reference for modern Android architecture patterns (MVVM, LiveData, Coroutines) relevant for integrating uCrop into larger apps

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add instrumented Android unit tests for UCropActivity lifecycle and image processing

The repo lacks visible test files for core functionality. UCropActivity.java handles critical image manipulation logic that should have automated test coverage. This would catch regressions in crop transformations, EXIF handling, and lifecycle edge cases across Android versions.

  • [ ] Create ucrop/src/androidTest/java/com/yalantis/ucrop/ directory structure
  • [ ] Add UCropActivityTest.java with tests for: image loading, crop region validation, rotation/scaling transformations
  • [ ] Add tests for ExifInterface integration in ucrop/src/main/java/com/yalantis/ucrop/ to verify EXIF data preservation
  • [ ] Configure androidTest in ucrop/build.gradle with androidx.test dependencies
  • [ ] Update README with test execution instructions

Add GitHub Actions CI workflow for automated testing and APK builds on PR

The repo has .github/ISSUE_TEMPLATE.md but no visible CI workflow files (.github/workflows/). With gradle and jitpack.yml present, setting up automated builds would catch compilation errors, test failures, and compatibility issues across multiple Android SDK versions before merge.

  • [ ] Create .github/workflows/android-build.yml with: checkout, setup JDK, gradlew build, gradlew test jobs
  • [ ] Configure matrix strategy for minSdkVersion and compileSdkVersion variations from build.gradle
  • [ ] Add artifact upload step for sample APK and test reports
  • [ ] Create .github/workflows/lint.yml for Android Lint checks on ucrop/ module
  • [ ] Add workflow badges to README.md

Create UCropFragment integration tests and document Fragment API with working examples

UCropFragment.java exists but sample/src/main/java only shows Activity-based usage (SampleActivity.java, ResultActivity.java). Fragment integration is underdocumented and untested. Adding Fragment examples and tests would help developers use the headless cropping component and reveal API stability issues.

  • [ ] Add FragmentSampleActivity.java in sample/src/main/java/com/yalantis/ucrop/sample/ demonstrating UCropFragment lifecycle
  • [ ] Create sample/src/main/res/layout/activity_fragment_sample.xml with FragmentContainerView
  • [ ] Add instrumented test: ucrop/src/androidTest/java/com/yalantis/ucrop/UCropFragmentTest.java covering Fragment creation, callback handling, and state restoration
  • [ ] Update README with dedicated 'Using UCropFragment' section with code snippets
  • [ ] Document UCropFragmentCallback.java interface expectations

🌿Good first issues

  • Add unit tests for UCrop.Options builder: sample/src/main/java/com/yalantis/ucrop/sample/ lacks JUnit tests for aspect ratio validation, compression quality bounds (0-100), and format enum handling.
  • Document native build setup: README lacks instructions for building the native flavor locally (NDK setup, CMake config); add a 'Building with Native Support' section and Makefile rules.
  • Create integration test for ExifInterface rotation: add test that loads a landscape EXIF-rotated JPEG, crops it, and verifies output orientation matches expected result—currently no test file visible for EXIF metadata handling.

Top contributors

Click to expand

📝Recent commits

Click to expand
  • f788b53 — Update mavenpush.gradle (lynnik)
  • 4ff728a — Update mavenpush.gradle (lynnik)
  • d36b677 — Revert "Update mavenpush.gradle" (lynnik)
  • 8b86748 — Update mavenpush.gradle (lynnik)
  • 8a12773 — Merge remote-tracking branch 'origin/develop' into develop (lynnik)
  • b107db1 — Update mavenpush.gradle (lynnik)
  • d408d80 — Update mavenpush.gradle (lynnik)
  • 0c6bdd4 — Update README (lynnik)
  • c3ed37c — Merge pull request #955 from Yalantis/release/2.2.11 (vladlynnik)
  • 8c20e0e — Resources optimization (lynnik)

🔒Security observations

The uCrop image cropping library has a moderate security posture. The main concerns are around dependency management (OkHttp needs monitoring), secure image loading practices, and file/EXIF handling. The codebase lacks visible security misconfigurations in the provided snippet, but several critical areas (FileUtils, ImageHeaderParser, BitmapLoadTask) require code-level review for injection risks, path traversal vulnerabilities, and proper input validation. The library handles user-provided image files which inherently carries security implications. Recommendations focus on implementing TLS pinning, strict file validation, EXIF stripping,

  • High · Outdated OkHttp Dependency — build.gradle (okhttp_version = "5.1.0"). OkHttp version 5.1.0 is used, which may contain known vulnerabilities. The library should be regularly updated to the latest stable version to patch security issues, especially for HTTP client operations that handle image loading from remote sources. Fix: Update OkHttp to the latest stable version (currently 4.12.x for production stability or latest 5.x with security patches). Review OkHttp release notes for any CVEs and apply patches.
  • Medium · Potential Insecure Image Loading — ucrop/src/main/java/com/yalantis/ucrop/UCropHttpClientStore.java, ucrop/src/main/java/com/yalantis/ucrop/util/BitmapLoadUtils.java. The codebase includes UCropHttpClientStore and BitmapLoadUtils for loading images, potentially from remote sources. Without explicit TLS/SSL pinning or certificate validation configuration visible, remote image loading could be vulnerable to MITM attacks. Fix: Implement certificate pinning for remote image loading. Validate HTTPS connections and reject insecure HTTP endpoints. Add network security configuration in AndroidManifest or network_security_config.xml.
  • Medium · File Provider Configuration Not Fully Visible — sample/src/main/res/xml/file_provider_paths.xml. While file_provider_paths.xml exists, the actual content is not visible in the provided structure. Improper FileProvider configuration could expose app's internal files to other applications. Fix: Review FileProvider configuration to ensure it only exposes necessary directories with strict path restrictions. Use specific paths rather than broad directory access. Implement proper content URI validation.
  • Medium · Potential Path Traversal in FileUtils — ucrop/src/main/java/com/yalantis/ucrop/util/FileUtils.java. The FileUtils utility class is present but not fully inspectable. File operations on user-selected images could be vulnerable to path traversal attacks if file paths are not properly validated. Fix: Implement strict file path validation. Use File.getCanonicalPath() to resolve symbolic links. Whitelist allowed directories for image processing. Reject suspicious path patterns (../, etc).
  • Medium · EXIF Data Handling — ucrop/src/main/java/com/yalantis/ucrop/model/ExifInfo.java. The library handles EXIF data (ExifInfo.java) which may contain sensitive metadata (GPS coordinates, device info, timestamps). Improper handling could leak user privacy information. Fix: Implement EXIF stripping by default unless explicitly required. Provide user control over EXIF data retention. Document privacy implications in API documentation.
  • Low · Missing Proguard Configuration Details — sample/proguard-rules.pro, ucrop/proguard-rules.pro. While proguard-rules.pro files exist, their content is not provided for review. Inadequate obfuscation could make the app vulnerable to reverse engineering. Fix: Review and enhance ProGuard rules to obfuscate sensitive classes. Use -keep rules judiciously to avoid over-protection that impacts security. Keep rules updated with library upgrades.
  • Low · Gradle Plugin Version — build.gradle (classpath 'com.android.tools.build:gradle:8.11.1'). Android Gradle plugin version 8.11.1 is relatively recent and should be monitored for security updates. Fix: Subscribe to Android Gradle plugin security updates and apply patches promptly. Regularly check for new versions.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Mixed signals · Yalantis/uCrop — RepoPilot