# Lossless JPG Editing for Wikimedia Commons Android: Precise Crop, Rotation, and Privacy-Aware Blurring
**Name:** Jagadeeshwar Reddy Kota
**Email:** kota.jagadesh123@gmail.com
**GitHub:** https://github.com/kota-jagadeesh
**LinkedIn:** https://linkedin.com/in/jagadeeshwar-reddy-kota
**Country:** India
**Preferred Time Zone:** Indian Standard Time (IST, UTC +5:30)
**University:** Amrita Vishwa Vidyapeetham
**Course:** Bachelor of Technology in Artificial Intelligence & Data Science
**Availability for Google Summer of Code:** Full-time (42+ hours per week)
## Synopsis
### App
Wikimedia Commons is an Android application developed by the Wikimedia Foundation that enables users to browse, upload, and contribute media directly to the Wikimedia Commons repository using their mobile devices. Users can easily select images from their device gallery or capture photos using the camera and upload them to the platform. The app aims to simplify the media contribution workflow and make it easier for contributors to share freely licensed images with the Wikimedia ecosystem.
### Project
This project aims to implement advanced** lossless JPEG image editing** capabilities in the Wikimedia Commons Android App to enable contributors to safely edit images before uploading them, while preserving their original quality, metadata, and file structure. While the application already supports basic editing features such as cropping and rotation, these operations need to be improved to ensure that transformations remain fully lossless and do not alter the image data, metadata, or color information.
Through my prior investigation of Issue [[ https://github.com/commons-app/apps-android-commons/issues/6659 | #6659 ]], I conducted detailed testing on the current rotation pipeline, including multi-step rotation experiments and metadata comparisons using tools such as exiftool. This analysis revealed that the brightness shift observed after rotating images is caused by **Android’s ExifInterface.saveAttributes()** method, which rewrites the EXIF metadata block and removes the original ICC Color Profile. Because the color profile is lost, image viewers render the rotated image with a different gamma/brightness profile. Based on this investigation, the project will focus on implementing a rotation pipeline that bypasses this metadata rewriting behavior using **jpegtran** to preserve the original headers and maintain exact color fidelity.
A key design principle of this project is that all transformations should operate directly on the JPEG macroblock structure, ensuring that edits are performed without unnecessary loss of information and without increasing the file size. This approach guarantees that contributors can safely edit images inside the app without degrading their quality or altering their metadata.
To achieve this, the project will deliver the following core improvements:
* **Deliverable 1: 100% Lossless Crop & Rotate (Fixing Issue [[ https://github.com/commons-app/apps-android-commons/issues/6659 | #6659 ]])**
The existing crop and rotation features will be improved to guarantee fully lossless transformations. The rotation pipeline will be redesigned to preserve the complete JPEG metadata, including the ICC color profile, preventing brightness and gamma shifts. This involve bypassing Android’s ExifInterface metadata rewriting and using a lower-level JPEG transformation approach (**using jpegtran**) that keeps the original metadata headers intact.
* **Deliverable 2: Automated Privacy Detection (Issue [[ https://github.com/commons-app/apps-android-commons/issues/1192
| #1192 ]])**
To assist contributors in protecting privacy before uploading images, the project will integrate on-device computer vision using **OpenCV's** Deep Neural Network (DNN) module. OpenCV is a widely used open-source computer vision library that supports modern deep learning, based object detection while operating entirely offline.
Using OpenCV’s DNN module, the application will run lightweight pre-trained detection models to identify sensitive regions such as human faces and vehicle license plates. These models analyze the image and return bounding box coordinates for detected objects with high accuracy. Because the detection pipeline runs fully on-device, no images are transmitted to external services, ensuring strict privacy preservation and compliance with Wikimedia’s privacy requirements.
The detected bounding boxes will be presented within the editing interface and passed to the lossless image editing module. These coordinates will then be used to determine the corresponding JPEG macroblocks that must be modified during the lossless blurring stage.
* **Deliverable 3: Lossless Macroblock Blurring (Issue [[ https://github.com/commons-app/apps-android-commons/issues/190 | #190 ]])**
The project will implement lossless privacy-aware blurring by modifying only the specific JPEG 8×8 DCT macroblocks corresponding to detected sensitive regions (faces or license plates). Instead of recompressing the entire image, which would degrade quality and potentially increase file size, this approach manipulates only the relevant macroblocks while leaving the rest of the JPEG structure untouched. As a result, the final image retains its exact original quality, metadata, and file size while ensuring that sensitive regions are irreversibly blurred.
By integrating these capabilities directly into the Commons Android App, contributors will be able to perform essential edits, such as cropping, rotating, and privacy blurring, directly within the application before uploading media. This reduces reliance on third-party editing tools, prevents accidental image degradation, and lowers the barrier for mobile contributions to Wikimedia Commons.
**Issue Links**
- https://github.com/commons-app/apps-android-commons/issues/1192
- https://github.com/commons-app/apps-android-commons/issues/190
- https://github.com/commons-app/apps-android-commons/issues/6659
- Phabricator Task link: {T415446}
**Possible Mentor(s)**
- Mentor: @RitikaPahwa4444 (Ritika Pahwa)
- Mentor: @Nicolas_Raoul (Nicolas Raoul)
**Have you contacted the mentors already?**
Yes
## Implementation Plan
This project will introduce a robust **lossless image editing pipeline** for the Wikimedia Commons Android App by improving the current editing workflow and integrating reliable mechanisms for **metadata preservation**, **privacy detection**, and **macroblock-level image manipulation**. The implementation will be structured into four main technical components.
### 1. Lossless Crop and Rotation Pipeline (Fixing [Issue #6659](https://github.com/commons-app/apps-android-commons/issues/6659))
The first component focuses on ensuring that existing editing operations such as **rotation** and **cropping** remain **fully lossless** while preserving all metadata, including the **ICC color profile**.
As identified during the investigation of **Issue #6659**, the current rotation pipeline relies on Android’s `ExifInterface.saveAttributes()` method, which rewrites the EXIF metadata block and removes the original ICC color profile.
To resolve this issue, the project will implement a lossless JPEG transformation pipeline using **jpegtran**, a widely used tool for performing lossless operations directly on JPEG files. Unlike standard image editing methods that decode and recompress the image, **jpegtran** operates directly on the JPEG compression structure, allowing transformations such as rotation and cropping to occur:
- without recompression
- without metadata loss
- without increasing the file size
**Updated pipeline steps:**
1. The selected image is passed to the editing module before upload.
2. Instead of using Android’s metadata rewriting methods, the transformation is performed using **jpegtran**.
3. **jpegtran** executes the requested transformation (crop or rotate) directly on the JPEG compression structure.
4. The original metadata headers - including **EXIF** information and **ICC color profiles** - remain intact.
This approach ensures that the edited image retains **exactly the same visual quality**, **metadata integrity**, and **file size** as the original image.
### 2. Automated Privacy Detection using OpenCV (Fixing [Issue #1192](https://github.com/commons-app/apps-android-commons/issues/1192))
To assist contributors in protecting privacy before uploading images, the project will integrate **on-device computer vision** using **OpenCV** to automatically detect sensitive regions such as **human faces** and **vehicle license plates**.
**OpenCV** will be integrated to perform image analysis locally on the device. Since all processing occurs on-device, **no image data is transmitted externally**, ensuring strict privacy protection.
**Detection pipeline steps:**
- The selected image is decoded into a **Bitmap** representation for computer vision analysis and then converted to an **OpenCV Mat** object for processing.
- **Face detection** is implemented using the **OpenCV DNN** (Deep Neural Network) module, enabling the application to run pretrained lightweight deep learning models optimized for object detection.
- A pretrained face detection model (such as an **SSD** or **MobileNet**-based detector) is loaded through the OpenCV DNN framework and used to analyze the image and identify human faces with associated confidence scores.
- For **vehicle license plate detection**, a lightweight object detection model is used within the same OpenCV DNN pipeline to identify rectangular plate regions.
- The detection model returns **bounding box coordinates** corresponding to the detected sensitive regions.
These detected bounding box coordinates are then passed to the image editing module, where the lossless macroblock-based blurring system applies privacy-aware blur **only to the relevant JPEG regions** while leaving the rest of the image unchanged.
### 3. Lossless Macroblock-Based Privacy Blurring (Fixing [Issue #190](https://github.com/commons-app/apps-android-commons/issues/190))
After detecting sensitive regions, the project will implement **lossless privacy-aware blurring** by modifying only the relevant JPEG compression blocks rather than recompressing the entire image.
JPEG images are internally represented using **8×8 Discrete Cosine Transform (DCT) blocks**. Instead of decoding the entire image and recompressing it after applying blur, the project will operate directly on these compression blocks.
**Process steps:**
1. The bounding box coordinates obtained from the OpenCV detection module are mapped to the corresponding **JPEG block grid**.
2. The JPEG blocks intersecting the sensitive region are identified.
3. Using **jpegtran**, only the selected macroblocks are manipulated to introduce **irreversible blur** in those regions.
4. The remaining image blocks remain unchanged.
Because this process operates directly on the JPEG compression structure, the resulting image maintains:
- identical visual quality outside the blurred region
- original metadata and headers
- no increase in file size
- no additional compression artifacts
### 4. Integration with the Commons Upload Workflow
The final step integrates the new editing pipeline into the existing image editing workflow of the Commons Android App.
**Updated editing flow:**
1. User selects or captures an image.
2. The user optionally opens the **Edit Image** interface.
3. **Privacy detection** is executed using OpenCV.
4. Detected sensitive regions are highlighted for user confirmation or adjustment.
5. The user can apply **cropping**, **rotation**, or **privacy blur**.
6. The requested transformations are executed using the **lossless jpegtran pipeline**.
7. The processed image is passed to the existing **upload module**.
This integration ensures that contributors can safely perform essential image edits **directly within the application** before uploading their media to Wikimedia Commons.
Through this architecture, the project will provide a reliable **lossless image editing system** that preserves metadata integrity, protects user privacy, and ensures that transformations occur without unnecessary recompression or increase in file size.
## Timeline
**Note** : During **May 20 - June 5**, my university end-semester examinations will take place. While this overlaps slightly with the early coding period, I will remain active in the project and the community. As I am already familiar with the Commons Android App and the contributor workflow, I plan to begin preliminary implementation during the community bonding period while also participating in discussions and reviewing existing pull requests where possible. Although development progress may be slightly slower during examination days, I will continue contributing consistently and will ensure that any limited progress during this period is compensated once the exams conclude.
| Timeframe | Start Date | End Date | Tasks and Subtasks |
|----------------------------------------|-----------------|-----------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **Community Bonding Period** | May 1, 2026 | May 24, 2026 | Get familiar with mentors and the Wikimedia developer community. Study the Commons Android App architecture, image editing pipeline, and relevant modules. Review documentation related to JPEG compression, metadata handling, and **jpegtran**. Set up the development environment and finalize the implementation plan with mentors. |
| **Week 1** | May 25, 2026 | May 31, 2026 | **Set up lossless JPEG transformation environment** |
| Subtask | May 25, 2026 | May 27, 2026 | Integrate **jpegtran** into the Android project and verify execution within the app environment. |
| Subtask | May 28, 2026 | May 31, 2026 | Study the current image editing workflow and identify integration points for the new lossless transformation pipeline. |
| **Week 2** | June 1, 2026 | June 7, 2026 | **Implement base lossless rotation pipeline** |
| Subtask | June 1, 2026 | June 4, 2026 | Implement JPEG rotation using **jpegtran** and validate rotation correctness. |
| Subtask | June 5, 2026 | June 7, 2026 | Verify metadata preservation and confirm **ICC profile** retention using tools such as **exiftool**. |
| **Week 3** | June 8, 2026 | June 14, 2026 | **Fix metadata loss issue** [Fixes Issue #6659](https://github.com/commons-app/apps-android-commons/issues/6659) |
| Subtask | June 8, 2026 | June 11, 2026 | Redesign the rotation pipeline to bypass Android `ExifInterface.saveAttributes()` metadata rewriting. |
| Subtask | June 12, 2026 | June 14, 2026 | Verify preservation of **ICC color profiles** and confirm brightness/gamma consistency after rotation. |
| **Week 4** | June 15, 2026 | June 21, 2026 | **Implement lossless cropping functionality** |
| Subtask | June 15, 2026 | June 18, 2026 | Implement cropping using **jpegtran** lossless transformations. |
| Subtask | June 19, 2026 | June 21, 2026 | Validate cropped images to ensure metadata integrity and no quality loss. |
| **Week 5** | June 22, 2026 | June 28, 2026 | **Integrate lossless editing pipeline into the app UI** |
| Subtask | June 22, 2026 | June 25, 2026 | Connect the **jpegtran** transformation pipeline with the existing image editing interface. |
| Subtask | June 26, 2026 | June 28, 2026 | Test rotation and cropping features within the complete upload workflow. |
| **Week 6** | June 29, 2026 | July 5, 2026 | **Integrate OpenCV environment for privacy detection** |
| Subtask | June 29, 2026 | July 2, 2026 | Integrate **OpenCV** into the Android project and configure the image processing pipeline. |
| Subtask | July 3, 2026 | July 5, 2026 | Convert Android **Bitmap** images to **OpenCV Mat** format and prepare preprocessing steps. |
| **Week 7 (Midterm milestone)** | July 6, 2026 | July 12, 2026 | **Implement face detection using OpenCV DNN** |
| Subtask | July 6, 2026 | July 9, 2026 | Integrate pretrained **DNN face detection model** within OpenCV. |
| Subtask | July 10, 2026 | July 12, 2026 | Generate bounding box coordinates for detected faces and verify detection accuracy. |
| **Week 8** | July 13, 2026 | July 19, 2026 | **Implement license plate detection** |
| Subtask | July 13, 2026 | July 16, 2026 | Integrate object detection model for license plate detection using **OpenCV DNN**. |
| Subtask | July 17, 2026 | July 19, 2026 | Refine bounding box filtering and improve detection reliability. |
| **Week 9** | July 20, 2026 | July 26, 2026 | **Develop macroblock-based blur algorithm** |
| Subtask | July 20, 2026 | July 23, 2026 | Map detection bounding boxes to the **JPEG 8×8 macroblock grid**. |
| Subtask | July 24, 2026 | July 26, 2026 | Implement algorithm to modify only the relevant JPEG macroblocks. |
| **Week 10** | July 27, 2026 | August 2, 2026 | **Integrate privacy-aware blur into the editing workflow** |
| Subtask | July 27, 2026 | July 30, 2026 | Apply macroblock-based blur to detected sensitive regions. |
| Subtask | July 31, 2026 | August 2, 2026 | Add manual adjustment option for users to refine blur regions if automatic detection fails. |
| **Week 11** | August 3, 2026 | August 9, 2026 | **Testing and performance optimization** |
| Subtask | August 3, 2026 | August 6, 2026 | Optimize **OpenCV** detection performance and editing pipeline. |
| Subtask | August 7, 2026 | August 9, 2026 | Add unit tests and integration tests for editing features. |
| **Week 12** | August 10, 2026 | August 16, 2026 | **Final integration and project completion** |
| Subtask | August 10, 2026 | August 13, 2026 | Perform final bug fixes, UI improvements, and code cleanup. |
| Subtask | August 14, 2026 | August 16, 2026 | Prepare final documentation, developer guidelines, and final project report. |
**This timeline is flexible and will be refined in consultation with mentors based on project progress and feedback.**
## Benefits to the Community
This project will enhance the image editing capabilities of the Commons Android App by enabling truly **lossless transformations**, ensuring that images retain their original quality, metadata, and file size.
While the app already supports basic editing features such as cropping and rotation, these operations are not fully lossless. As a result, images may undergo recompression, leading to **quality degradation, loss of metadata (such as EXIF and ICC profiles), and potential changes in file size**. Additionally, the lack of built-in privacy-aware blurring forces contributors to rely on third-party tools, which further increases the risk of information loss.
By implementing a lossless editing pipeline using jpegtran and introducing privacy-aware blurring, this project will allow contributors to safely edit images directly within the app without compromising their integrity.
Overall, this project will:
* Preserve image quality and metadata during editing
* Eliminate unnecessary recompression and file size changes
* Introduce built-in privacy protection features
* Reduce dependency on external tools
* Improve the overall mobile contribution workflow
These improvements will lower barriers to contribution and help increase both the quality and reliability of media uploaded to Wikimedia Commons.
## About Me
I am Jagadeeshwar Reddy Kota, currently pursuing a Bachelor of Technology in Artificial Intelligence and Data Science at Amrita Vishwa Vidyapeetham, Amritapuri.
I am deeply interested in Android development and open-source contributions. Over time, I have gained hands-on experience working with Android application architecture, debugging real-world issues, and improving user experience through practical contributions. I enjoy working on problems that involve both system-level understanding and user-facing improvements.
My interest in open source grew as I started contributing to real projects and collaborating with developers across the community. I particularly enjoy understanding existing codebases, identifying issues, and working towards clean and maintainable solutions.
Apart from development, I am also interested in problem solving and continuously improving my technical skills through practice and real-world applications.
## Previous Contributions
To date, I have submitted **48 pull requests**, of which **35 have been merged** and **10 are currently under review**.
### Merged Pull Requests (35)
| S.No | PR | Title | Status |
|------|----------|-------------------------------------------------------------------------------------------|---------|
| 01 | [#6367](https://github.com/commons-app/apps-android-commons/pull/6367) | Fix email verification input | Merged |
| 02 | [#6405](https://github.com/commons-app/apps-android-commons/pull/6405) | Make “File Usages” items clickable with correct URLs | Merged |
| 03 | [#6417](https://github.com/commons-app/apps-android-commons/pull/6417) | Added wiki prefix to titles in GlobalFileUsage | Merged |
| 04 | [#6420](https://github.com/commons-app/apps-android-commons/pull/6420) | Fix: Add listener call in ImageAdapter to update UI & upload | Merged |
| 05 | [#6425](https://github.com/commons-app/apps-android-commons/pull/6425) | Fix: location Permission prompt on Upload via mobile screen | Merged |
| 06 | [#6363](https://github.com/commons-app/apps-android-commons/pull/6363) | Update bug report to use type:bug | Merged |
| 07 | [#6429](https://github.com/commons-app/apps-android-commons/pull/6429) | Fix: App crashes theme change multi upload | Merged |
| 08 | [#6479](https://github.com/commons-app/apps-android-commons/pull/6479) | Fix: Explore map crashes when tapped recenter button | Merged |
| 09 | [#6520](https://github.com/commons-app/apps-android-commons/pull/6520) | Fix: bottom nav visibility media details | Merged |
| 10 | [#6529](https://github.com/commons-app/apps-android-commons/pull/6529) | Test: Add campaigns api tests | Merged |
| 11 | [#6557](https://github.com/commons-app/apps-android-commons/pull/6557) | Enhance custom selector upload limit | Merged |
| 12 | [#6565](https://github.com/commons-app/apps-android-commons/pull/6565) | Fix: Preserve UploadActivity state across screen resize | Merged |
| 13 | [#6569](https://github.com/commons-app/apps-android-commons/pull/6569) | Update feature request to use type:feature | Merged |
| 14 | [#6578](https://github.com/commons-app/apps-android-commons/pull/6578) | Feature: increase maximum zoom level on upload preview screen | Merged |
| 15 | [#6604](https://github.com/commons-app/apps-android-commons/pull/6604) | Fix: missing accessibility for back button in singlewebviewactivity | Merged |
| 16 | [#6625](https://github.com/commons-app/apps-android-commons/pull/6625) | Humanize github actions and prevent duplicate comments | Merged |
| 17 | [#6637](https://github.com/commons-app/apps-android-commons/pull/6637) | Feat: Link to actual profile when using custom author name | Merged |
| 18 | [#6642](https://github.com/commons-app/apps-android-commons/pull/6642) | Fix: Incorrect rotation logic and re-edit bug | Merged |
| 19 | [#6632](https://github.com/commons-app/apps-android-commons/pull/6632) | Fix: Refine auto assignment logic | Merged |
| 20 | [#6653](https://github.com/commons-app/apps-android-commons/pull/6653) | Fix: Hide edit image button for unsupported non-JPEG files | Merged |
| 21 | [#6635](https://github.com/commons-app/apps-android-commons/pull/6635) | Fix: Refine assignment logic with issue context | Merged |
| 22 | [#6655](https://github.com/commons-app/apps-android-commons/pull/6655) | Fix: Prevent ActivityLauncher crash by moving registration onCreate | Merged |
| 23 | [#6644](https://github.com/commons-app/apps-android-commons/pull/6644) | Fix: Add assignment confirmation comment and fix new contributor welcome logic | Merged |
| 24 | [#6661](https://github.com/commons-app/apps-android-commons/pull/6661) | UninitialisedPropertyAccessException ImageFragment onDestroy | Merged |
| 25 | [#6694](https://github.com/commons-app/apps-android-commons/pull/6694) | Fix: Improve UX for Edit image button on the non-JPEG files | Merged |
| 26 | [#6698](https://github.com/commons-app/apps-android-commons/pull/6698) | Docs: fix the broken link | Merged |
| 27 | [#0066](https://github.com/commons-app/apps-android-commons/pull/0066) | Add link to commons mobile talk page for the app feedback | Merged |
| 28 | [#0065](https://github.com/commons-app/apps-android-commons/pull/0065) | Document the additional features of the app in the docs section | Merged |
| 29 | [#0063](https://github.com/commons-app/apps-android-commons/pull/0063) | Add the commons policy and guidelines links to help new contributors | Merged |
| 30 | [#0003](https://github.com/commons-app/apps-android-commons/pull/0003) | Docs: Update maintenance Readme | Merged |
| 31 | [#0060](https://github.com/commons-app/apps-android-commons/pull/0060) | Fix: the broken link of images | Merged |
| 32 | [#0002](https://github.com/commons-app/apps-android-commons/pull/0002) | Add issue migration script | Merged |
| 33 | [#0054](https://github.com/commons-app/apps-android-commons/pull/0054) | Better documentation for the leaderboard | Merged |
| 34 | [#0057](https://github.com/commons-app/apps-android-commons/pull/0057) | Update link to unassigned bugs in documentation | Merged |
| 35 | [#0059](https://github.com/commons-app/apps-android-commons/pull/0059) | Migrated from label:enhancement to type:feature | Merged |
### Pull Requests Under Review (10)
| S.No | PR | Title | Status |
|------|----------|-------------------------------------------------------------------------------------------|---------|
| 01 | [#6709](https://github.com/commons-app/apps-android-commons/pull/6709) | Fix: image sorting in custom selector to use historical order | Open |
| 02 | [#6532](https://github.com/commons-app/apps-android-commons/pull/6532) | Fix: Prevent crash when pausing/resuming uploads after screen rotation | Open |
| 03 | [#6579](https://github.com/commons-app/apps-android-commons/pull/6579) | Fix: Prevent crash in offline search caused by null map boundaries | Open |
| 04 | [#6602](https://github.com/commons-app/apps-android-commons/pull/6602) | Refactor: Centralize location service unavailability handling | Open |
| 05 | [#6605](https://github.com/commons-app/apps-android-commons/pull/6605) | Fix: stateless in searchActivity and media detail pager fragment during screen rotation | Open |
| 06 | [#6613](https://github.com/commons-app/apps-android-commons/pull/6613) | Fix: prevent UI settings on logout | Open |
| 07 | [#6623](https://github.com/commons-app/apps-android-commons/pull/6623) | Add unit tests for findUniqueFileName | Open |
| 08 | [#6580](https://github.com/commons-app/apps-android-commons/pull/6580) | Feature: Animated multi FAB upload in Pending Uploads | Open |
| 09 | [#6698](https://github.com/commons-app/apps-android-commons/pull/6698) | Enforce upload limit in first step of upload Flow | Open |
| 10 | [#6649](https://github.com/commons-app/apps-android-commons/pull/6649) | Automate issue assignment and implement inactivity management | Draft |