Skip to content
CAI
Software that uses CAICheck a score

LuckSiege/PictureSelector

43.3

Weak · 25 September 2026

48k

lines of production code

Java

primary language

5

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

This is an Android library suite for media selection, editing, and playback. It provides modular components for image and video selection, camera capture, and video playback, while also offering image compression and multi-image cropping capabilities. The system supports pluggable image loading engines and is structured into distinct, publishable modules.

How it got here

2017 — AndroidX migration and modularization

8 changes.

The project underwent a significant structural overhaul, migrating to AndroidX and splitting the codebase into distinct, publishable modules. This period also introduced modern media capabilities, including video playback and camera integration, while removing legacy components to support a pluggable image loading architecture.

2021–2023 — modularization and media integration

6 changes.

This period focused on modularizing the codebase by introducing distinct components for image compression, camera functionality, and media playback. The project expanded its capabilities by integrating the Luban compression library, a CameraX-based camera module, and the ijkplayer-java media player. These additions were accompanied by structural refactoring of the selector module and minor updates to the demo application.

Features

Added Apache 2.0 license and updated project documentation

The repository now includes a LICENSE file containing the Apache License, Version 2.0, establishing the legal terms for using the software. Additionally, the README.md and README\_CN.md files have been created/updated to provide comprehensive documentation for the PictureSelector 3.0 Android library, including installation instructions, permission requirements, and usage examples for image and video selection.

(repo-wide) · high confidence

Introduced a new camera module in the \camerax\ directory, providing a complete camera implementation. This includes \PictureCameraActivity\ for the main camera interface, \SimpleCameraX\ as the public API for starting the camera, and \CustomCameraConfig\ for global configuration. The module also adds support for image loading via \CameraImageEngine\, handles permissions through \PermissionChecker\, manages capture states with \CaptureButton\ and \CaptureLayout\ widgets, and includes utility classes for file handling (\FileUtils\, \CameraUtils\), bitmap processing (\BitmapUtils\), and date formatting (\DateUtils\).

camerax · high confidence

Adds custom image loading engine and multi-image cropping support

The library now supports a pluggable image loading mechanism via the new UCropImageEngine interface and UCropDevelopConfig, allowing developers to integrate their own image loading libraries (such as Glide or Fresco) instead of being locked into a specific implementation. Additionally, a new UCropMultipleActivity and UCropFragment-based architecture enables cropping multiple images in a single session, with each image managed as a separate fragment within a gallery-style interface.

ucrop/src/main/java · high confidence

Adds demo app with custom UI and multiple image loading engine implementations

The app/src directory now contains a complete demo application for the PictureSelector library. This includes custom UI components such as a bottom navigation bar, title bars, loading dialogs, and preview fragments that demonstrate how to extend the library's default views. Additionally, the demo provides concrete implementations for three image loading engines—Glide, Picasso, and Coil—allowing developers to see how to integrate different image loading libraries with the selector. The App class configures the Coil image loader and camera X settings, while the InjectFragmentActivity shows how to launch the selector as a fragment or activity.

app/src · high confidence

Adds video playback, camera, and media display components

The library now includes new components for video playback and camera functionality. ExoPlayerEngine and IjkPlayerEngine are added to support video playback with state listeners. A new CustomCameraView is introduced, leveraging AndroidX CameraX to provide a customizable camera interface with support for photo, video, and flash modes. Additionally, OnlyQueryDataActivity and RoundedCornersTransform are added to demonstrate data querying and image transformation capabilities, while new view holders (AudioViewHolder, ImageViewHolder, VideoViewHolder) enable styled display of media items in a grid.

. · high confidence

Initial release of the ijkplayer-java Android media player library

The ijkplayer-java module is added to the codebase, introducing the core Java components for the IJKMediaPlayer. This includes the \IMediaPlayer\ interface and its \MediaPlayerProxy\ implementation, which handle media playback and state management. The update also introduces the \IjkMediaCodecInfo\ class, which provides a ranking system for selecting the most appropriate hardware or software video decoder on the device. Additionally, the change adds supporting classes for media metadata (\IjkMediaMeta\), timed text (\IjkTimedText\), and Android-specific wrappers for media formats (\AndroidMediaFormat\) and track information (\AndroidTrackInfo\).

ijkplayer-java · high confidence

Introduce modularized PictureSelector components

The selector module now includes a new set of core UI and logic classes, including fragments for the main selector, preview, and system album access, along with their corresponding RecyclerView adapters and view holders. This restructuring separates the selection, preview, and system integration logic into distinct, reusable components within the selector package.

selector · high confidence

Introduced Luban image compression library

Added the Luban image compression library to the project, including the main \Luban\ class, \Engine\ for handling compression logic, \Checker\ for image validation, and supporting classes for input streams and memory pooling. The \LubanUtils\ class provides utilities for resolving file paths from URIs, and the \io\ package introduces an \ArrayPool\ for efficient memory management during compression. This adds a new capability for users to compress images with customizable parameters.

compress · high confidence

Behavioural changes

1 commit (0 fixes) modifying app/demo

A change to existing behaviour in app/demo — 1 commit, 1 file.

app/demo · low confidence · unverified

Added debug APK metadata for the Luck Picture Selector app

A new debug build artifact is now generated, with metadata stored in debug/output-metadata.json. This file records the application ID (com.luck.pictureselector), the debug variant name, and the specific APK output (app-debug.apk) for version 2.6.1, enabling better tracking of debug build outputs.

app/signature, debug · high confidence

Removed legacy picture library components

The \picture\_library\ module's legacy UI and data classes have been removed, including activities (AlbumDirectoryActivity, ImageGridActivity, PreviewActivity, VideoPlayActivity), adapters, fragments, and entity classes (LocalMedia, LocalMediaFolder). This cleanup eliminates the old image and video selection and preview interfaces, indicating a shift away from the previous implementation of these features.

_picture\library · high confidence

Updated ProGuard rules for PictureSelector and Glide

The app's ProGuard configuration has been updated to include obfuscation and optimization settings, along with specific keep-rules for the PictureSelector library (com.luck.picture.lib) and Glide (com.bumptech.glide). This ensures that these third-party components are not stripped or obfuscated during the release build process.

app · medium confidence

Upgraded Gradle wrapper to version 7.5

The project's Gradle wrapper has been upgraded from version 2.14.1 to 7.5. This change updates the underlying build system, which may affect build performance and compatibility with newer Android development tools.

gradle · high confidence

Dependencies

Project structure and build configuration overhaul

The project has been restructured into distinct, publishable modules (camerax, compress, selector, ijkplayer-java, ucrop) with a centralized config.gradle for version management. The app module now depends on these new modules and integrates multiple image loading libraries (Glide, Picasso, Coil) alongside navigation and UI dependencies. Build tools have been upgraded to Gradle 7.4.2 and Java 8 compatibility, and the project has migrated to AndroidX, removing older support libraries and legacy dependencies.

(dependencies) · medium confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

Score

  • CAI 45 → 43 (-2.2)
  • Rubric changed (rubric-2026.08.19 → rubric-2026.09.15) — scores are not directly comparable.

Lenses

  • Code Health 73 → 83 (+10.4)
  • Architecture 96 → 95 (-1.8)
  • Maturity 46 → 45 (-0.9)
  • Readiness 24 → 18 (-6.3)
  • Security 92 → 87 (-5.0)

Resolved (117)

  • Change coupling: PictureImageGridAdapter.java ↔ PicturePreviewAdapter.java (selector/src/main/java/com/luck/picture/lib/adapter/PictureImageGridAdapter.java)
  • Coverage not included — suite not readable by the collector
  • Dependency hygiene not measured — dependency manifest found but not parsed for hygiene
  • Duplicated block (10 lines × 2) (app/src/main/java/com/luck/pictureselector/ImageLoaderUtils.java)
  • Duplicated block (10 lines × 2) (app/src/main/java/com/luck/pictureselector/MainActivity.java)
  • Duplicated block (10 lines × 2) (app/src/main/java/com/luck/pictureselector/PicassoEngine.java)
  • Duplicated block (10 lines × 2) (camerax/src/main/java/com/luck/lib/camerax/utils/FileUtils.java)
  • Duplicated block (10 lines × 2) (selector/src/main/java/com/luck/picture/lib/PictureSelectorPreviewFragment.java)
  • Duplicated block (10 lines × 2) (selector/src/main/java/com/luck/picture/lib/PictureSelectorSystemFragment.java)
  • Duplicated block (10 lines × 2) (selector/src/main/java/com/luck/picture/lib/basic/PictureCommonFragment.java)
  • Duplicated block (10 lines × 2) (selector/src/main/java/com/luck/picture/lib/basic/PictureCommonFragment.java)
  • Duplicated block (10 lines × 2) (selector/src/main/java/com/luck/picture/lib/basic/PictureSelectionQueryModel.java)
  • Duplicated block (10 lines × 2) (selector/src/main/java/com/luck/picture/lib/utils/MediaUtils.java)
  • Duplicated block (10 lines × 2) (selector/src/main/java/com/luck/picture/lib/utils/MediaUtils.java)
  • Duplicated block (10 lines × 2) (ucrop/src/main/java/com/yalantis/ucrop/UCropActivity.java)
  • Duplicated block (10 lines × 2) (ucrop/src/main/java/com/yalantis/ucrop/UCropActivity.java)
  • Duplicated block (10 lines × 2) (ucrop/src/main/java/com/yalantis/ucrop/UCropActivity.java)
  • Duplicated block (10 lines × 2) (ucrop/src/main/java/com/yalantis/ucrop/UCropActivity.java)
  • Duplicated block (10 lines × 2) (ucrop/src/main/java/com/yalantis/ucrop/util/ImageHeaderParser.java)
  • Duplicated block (10 lines × 3) (app/src/main/java/com/luck/pictureselector/MainActivity.java)
  • …and 97 more

New (209)

  • 1106.doInBackground (cognitive 46) (selector/src/main/java/com/luck/picture/lib/utils/DownloadFileUtils.java)
  • 1106.doInBackground (cyclomatic 22) (selector/src/main/java/com/luck/picture/lib/utils/DownloadFileUtils.java)
  • 11262.doInBackground (cognitive 97) (selector/src/main/java/com/luck/picture/lib/loader/LocalMediaPageLoader.java)
  • 11262.doInBackground (cyclomatic 28) (selector/src/main/java/com/luck/picture/lib/loader/LocalMediaPageLoader.java)
  • 3361.doInBackground (cognitive 39) (selector/src/main/java/com/luck/picture/lib/loader/LocalMediaLoader.java)
  • 7596.doInBackground (cognitive 23) (selector/src/main/java/com/luck/picture/lib/loader/LocalMediaPageLoader.java)
  • Change coupling: PictureSelectorFragment.java ↔ BaseRecyclerMediaHolder.java (selector/src/main/java/com/luck/picture/lib/PictureSelectorFragment.java)
  • ClassTooLong: CustomCameraView (camerax/src/main/java/com/luck/lib/camerax/CustomCameraView.java)
  • ClassTooLong: IjkMediaPlayer (ijkplayer-java/src/main/java/tv/danmaku/ijk/media/player/IjkMediaPlayer.java)
  • ClassTooLong: LocalMediaPageLoader (selector/src/main/java/com/luck/picture/lib/loader/LocalMediaPageLoader.java)
  • ClassTooLong: MainActivity (app/src/main/java/com/luck/pictureselector/MainActivity.java)
  • ClassTooLong: PhotoViewAttacher (selector/src/main/java/com/luck/picture/lib/photoview/PhotoViewAttacher.java)
  • ClassTooLong: PictureCommonFragment (selector/src/main/java/com/luck/picture/lib/basic/PictureCommonFragment.java)
  • ClassTooLong: PictureSelectionModel (selector/src/main/java/com/luck/picture/lib/basic/PictureSelectionModel.java)
  • ClassTooLong: PictureSelectorFragment (selector/src/main/java/com/luck/picture/lib/PictureSelectorFragment.java)
  • ClassTooLong: PictureSelectorPreviewFragment (selector/src/main/java/com/luck/picture/lib/PictureSelectorPreviewFragment.java)
  • ClassTooLong: PictureThreadUtils (selector/src/main/java/com/luck/picture/lib/thread/PictureThreadUtils.java)
  • ClassTooLong: UCropActivity (ucrop/src/main/java/com/yalantis/ucrop/UCropActivity.java)
  • Dependency hygiene PARTLY measured — Maven/Gradle declarations read, no dependency graph resolved
  • Documentation: no usage examples (README.md)
  • …and 189 more

Architecture

  • Containers 0 added · 0 removed · contexts 6 added · 1 removed · edges 5 added · 0 removed

Added bounded contexts (6)

  • app
  • camerax
  • compress
  • ijkplayer-java
  • selector
  • ucrop

Removed bounded contexts (1)

  • .

Added dependency edges (5)

  • app → camerax
  • app → compress
  • app → ijkplayer-java
  • app → selector
  • app → ucrop

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

LuckSiege/PictureSelector was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 25 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit a880156bbd4df2ebe254858b9f5acec0a7ca54c3 — the exact code this score is about.
  • Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-f917f263222d.