A drop-in photo & video editor for Android apps. Add one dependency, call one method, and your app gains a polished editor — crop, filters, live adjustments, rotate, flip, and frame-accurate video trim — with the edited file handed back to you as a URI.
PixEdit.openGallery(activity = this) // SDK picker → editor
PixEdit.openEditor(activity = this, mediaUri = uri) // skip the pickerThis repository is the demo app and documentation. The SDK itself is distributed as a prebuilt library — see Install.
minSdk |
24 (Android 7.0) |
compileSdk |
36 |
| Build host | JDK 17, AGP 8.4+, Gradle 8.4+ |
| Language | Kotlin — classic XML views, no Compose required |
| Required of your app | Hilt (@HiltAndroidApp) — see Install |
// settings.gradle
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven { url "https://raxit0948.github.io/pixedit-maven" }
}
}// app/build.gradle
dependencies {
implementation "com.pixedit:pixedit-sdk:1.1.0"
// Required: the SDK's internals live in Hilt's SingletonComponent.
implementation "com.google.dagger:hilt-android:2.54"
kapt "com.google.dagger:hilt-android-compiler:2.54"
}And annotate your Application class — this is the only setup step:
@HiltAndroidApp
class MyApp : Application() {
override fun onCreate() {
super.onCreate()
PixEdit.init(this) // no-op in 1.x; see INTEGRATION.md
}
}PixEditActivity and the SDK's media permissions come from its own manifest; the
merger pulls them in. You don't declare either.
Requirements: minSdk 24 · compileSdk 36 · JDK 17 · AGP 8.4+
The SDK's own picker — one consistent gallery UX, Recent / Favorites / Videos / Screenshots tabs, routing images to Crop and videos to Trim:
PixEdit.openGallery(activity = this)Your own URI — from the system photo picker, a deep link, a download:
PixEdit.openEditor(activity = this, mediaUri = uri)Launch through the Intent variants to receive the output URI:
private val launchEditor = registerForActivityResult(
ActivityResultContracts.StartActivityForResult(),
) { result ->
val output: PixEditResult? = result.data?.parcelable(PixEdit.RESULT_EXTRA)
output?.outputUri?.let { uri -> /* upload, display, share */ }
}
launchEditor.launch(PixEdit.galleryIntent(this))By default the edit lands in the user's gallery (Pictures/PixEdit,
Movies/PixEdit) and outputUri is a MediaStore URI. That's right for a photo the
user wants to keep.
For an intermediate — an avatar you're about to upload, a clip you're about to post — you usually don't want it in their camera roll at all:
launchEditor.launch(
PixEdit.galleryIntent(this, PixEditConfig(saveToGallery = false)),
)
// In the callback: a private FileProvider URI, nothing added to the gallery.
val file = PixEdit.outputFile(this, outputUri) // a real File, if you need a path
PixEdit.clearOutputCache(this) // once you've consumed it| Crop | 7 aspect ratios (FREE, 1:1, 4:5, 16:9, 9:16, 3:4, 4:3), drag & pinch resize, rotate left/right, horizontal flip |
| Filter | 7 zero-allocation ColorMatrix presets — None, Natural, Warm, Cool, Mono, Vintage, Fade — with live preview |
| Adjust | 10 tools: Brightness, Contrast, Saturation, Exposure, Warmth, Fade, Highlights, Shadows, Sharpness, Vignette. ~60 fps while dragging |
| Trim | Frame-accurate ExoPlayer preview, filmstrip timeline, draggable in/out handles |
| Smart video export | Keyframe-aligned cuts stream-copy (near-instant, no re-encode); off-keyframe cuts fall back to a Media3 Transformer hardware re-encode |
| Format preserving | PNG → PNG with alpha, WebP → WebP (lossless on API 30+), HEIC/AVIF/GIF/BMP → JPEG. EXIF orientation applied to pixels, not just the tag |
| Bounded memory | Sources above 24 MP are sampled down before decode, so peak allocation is capped regardless of input size |
| Output your way | Publish to the gallery, or keep the result in your app's private cache and get a File back — see Gallery, or private file? |
| Platform correctness | Scoped storage on API 29+, granular media permissions on 33+, partial photo access on 34+ |
| Hard to crash | Invalid URIs, missing extras, OOM on huge bitmaps and failed media loads all yield RESULT_CANCELED instead of taking your process down |
| Call | What it does |
|---|---|
PixEdit.init(context) |
Optional setup. A no-op in 1.x — see INTEGRATION.md |
PixEdit.openGallery(activity, config) |
SDK picker → editor, fire-and-forget |
PixEdit.openEditor(activity, mediaUri, config) |
Straight to the editor with your URI |
PixEdit.galleryIntent(context, config) |
Same as openGallery, as an Intent for registerForActivityResult |
PixEdit.editorIntent(context, mediaUri, config) |
Same as openEditor, as an Intent |
PixEdit.outputFile(context, uri) |
The backing File for private-cache output, else null |
PixEdit.clearOutputCache(context) |
Delete cached outputs; returns how many |
Everything else is PixEditConfig (5 fields) and PixEditResult (outputUri,
cancelled).
git clone https://github.com/Raxit0948/pixedit-android-sdk.git
cd pixedit-android-sdk && ./gradlew :app:installDebugThe whole integration is one file: PixEditDemoActivity.kt.
INTEGRATION.md is the full guide — configuration, both output modes, supported formats, permissions, theming, host-app patterns, and troubleshooting.
The SDK is proprietary and distributed in binary form; the demo source is free to copy. See LICENSE.
Free for the 1.x series — including commercial apps, with no fee, registration, or licence key. Future major versions may ship under different terms, but that never applies retroactively: any version you have already integrated stays under the terms it was released under.
Raxit Bhalala





