commit 3408e8a25e3388446b3abd86573bbf0afb6140f0
parent 98e4272df49c3d08bf48a717559d5c6bf52113e6
Author: maydayv7 <maydayv7@gmail.com>
Date: Thu, 4 Dec 2025 01:47:45 +0530
Update README and stylesheet page
Diffstat:
8 files changed, 94 insertions(+), 96 deletions(-)
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
@@ -14,25 +14,25 @@ jobs:
runs-on: ubuntu-latest
steps:
- # 1. Checkout Code (with LFS for your ONNX models)
+ # 1. Checkout Code (with LFS)
- name: Checkout code
uses: actions/checkout@v4
with:
- lfs: true
+ lfs: true
# 2. Setup Java (Required for Android Build)
- name: Setup Java
uses: actions/setup-java@v4
with:
- distribution: 'temurin'
- java-version: '17'
+ distribution: "temurin"
+ java-version: "17"
# 3. Setup Flutter
- name: Setup Flutter
uses: subosito/flutter-action@v2
with:
- channel: 'stable'
- flutter-version: '3.38.x'
+ channel: "stable"
+ flutter-version: "3.38.x"
# 4. Create .env file from Secrets
- name: Create .env file
@@ -42,25 +42,23 @@ jobs:
- name: Decode Keystore
run: |
echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 --decode > android/app/upload-keystore.jks
-
+
echo "storePassword=${{ secrets.KEYSTORE_PASSWORD }}" >> android/key.properties
echo "keyPassword=${{ secrets.KEY_PASSWORD }}" >> android/key.properties
echo "keyAlias=${{ secrets.KEY_ALIAS }}" >> android/key.properties
echo "storeFile=upload-keystore.jks" >> android/key.properties
- # 6. Setup Python 3.11 (Matches your local version)
+ # 6. Setup Python 3.8
- name: Setup Python
uses: actions/setup-python@v5
with:
- python-version: '3.11'
+ python-version: "3.8"
# 7. Install Dependencies
- name: Install dependencies
run: flutter pub get
# 8. Build APK
- # split-per-abi is optional, but --release is mandatory.
- # Removing split-per-abi creates one "fat" APK compatible with all devices.
- name: Build Release APK
run: flutter build apk --release
@@ -71,4 +69,4 @@ jobs:
with:
files: build/app/outputs/flutter-apk/app-release.apk
generate_release_notes: false
- body: "Inter IIT Adobe P.S. by IITG."
+ body: "adobe"
diff --git a/README.md b/README.md
@@ -4,32 +4,32 @@ A Flutter project with AI-based image analysis
## Prerequisites
-- Flutter SDK
-- Python 3.8
-- Kotlin + Gradle
-- JDK
-- Android SDK
+- `git` & `git-lfs`
+- Flutter SDK **>=3.7**
+- Python **3.8**
+- Gradle **8.9.1**
+- Java/JDK **17** & Kotlin
+- Android SDK & NDK
+ - Platform Level **>=34**
+ - Build Tools **>=34.0.0**
+ - NDK Version **27.0.12077973**
+ - CMake **3.22.1**
+
+Ensure that all these programs with the correct versions are installed on your system before using this repository
## Setup
-### 1. Setup Python
+### 1. Clone Repository
-#### A) Install Python 3.8
-
-**macOS:**
+Clone using `git lfs clone` to ensure all models are correctly pulled
-```bash
-brew install python@3.8
-```
+### 2. Setup Python
-**Linux:**
+The Android app compiles Python code using [Chaquopy](https://chaquo.com/chaquopy/), which requires the following setup, mandatorily using Python Version 3.8:
-```bash
-sudo apt-get install python3.8 python3.8-venv
-```
+#### A) Install Python 3.8
-**Windows:**
-Download from [python.org](https://www.python.org/downloads/)
+Download from [python.org](https://www.python.org/downloads/release/python-3810/)
#### B) Set up Virtual Environment
@@ -37,13 +37,16 @@ Download from [python.org](https://www.python.org/downloads/)
python -m venv python_env
```
-### 3. AI Models
-
-Download the models from [here](https://mega.nz/folder/WghwgRYA#byC4igRSImx0LRd9KW40hw) and place them under `assets`
-
-### 4. Build the APK
+### 3. Build the APK
```bash
flutter clean
-flutter build apk --release
+flutter pub get
+flutter build apk
```
+
+If you have `adb` properly installed, you can use `flutter run`
+
+## Backend
+
+Read [flask/README.md](flask/README.md) to run the server
diff --git a/android/.gitignore b/android/.gitignore
@@ -7,8 +7,8 @@ gradle-wrapper.jar
GeneratedPluginRegistrant.java
.cxx/
-# Remember to never publicly share your keystore.
+# Remember to never publicly share your keystore
# See https://flutter.dev/to/reference-keystore
-# key.properties
+key.properties
**/*.keystore
**/*.jks
diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts
@@ -71,7 +71,7 @@ android {
buildTypes {
release {
- // Signing with the relsease keys, so `flutter run --release` works.
+ // Signing with the release keys, so `flutter run --release` works.
signingConfig = signingConfigs.getByName("release")
// Optional: Enable shrinking for smaller APKs (recommended for release)
diff --git a/android/key.properties b/android/key.properties
@@ -1,4 +0,0 @@
-storePassword=interiit
-keyPassword=interiit
-keyAlias=upload
-storeFile=upload-keystore.jks
diff --git a/flask/README.md b/flask/README.md
@@ -1,57 +1,32 @@
-# AI Image Generator Backend
+# Backend
-This project sets up a local Flask server that uses the Stable Diffusion v1.5 model to generate images from text prompts.
-Prerequisites
-Before you begin, ensure you have the following installed:
-Python 3.10 or 3.11 (Recommended for compatibility)
+This project provides a unified AI backend for image generation, inpainting, background removal, and captioning. It supports two modes of operation:
-### Prerequisites
+## 1. Local Server (`index.py`)
-- NVIDIA GPU (Recommended)
- You need a GPU with at least 4GB VRAM
- Ensure you have the latest NVIDIA drivers installed
- Check CUDA availability: Open terminal and run `nvidia-smi`
+Runs purely on your local machine
-## Installation & Setup
+> [!IMPORTANT]
+> Requires Cuda-enabled NVIDIA GPU
-### A. Install Standard Packages
+To run backend locally, run the following commands:
-```
-pip install flask flask-cors diffusers transformers accelerate safetensors
-```
-
-### B. Install PyTorch & xFormers (GPU Acceleration)
-
-This step differs slightly depending on your OS and GPU
-
-#### Windows (NVIDIA GPU)
-
-To ensure you get the version compatible with your GPU, run:
-
-```
-pip install torch torchvision xformers --index-url https://download.pytorch.org/whl/cu118
-```
-
-If you have a very new GPU, you can try `cu121` instead of `cu118`
-
-#### Mac (M1/M2/M3 Silicon)
-
-Macs use "MPS" (Metal Performance Shaders) instead of CUDA
-
-```
-pip install torch torchvision torchaudio
+```shell
+pip install -r requirements.txt
+python ./index.py
```
-### C. Models
+## 2. Cloud Server (`modal_app.py`)
-Download the requisite models from [here](https://github.com/adobeinter/Adobe-Models/tree/main)
+Deploys to [Modal.com](https://modal.com) for serverless GPU inference
-## Running the Server
+To deploy, run the following commands:
```shell
-python index.py
+pip install modal
+modal setup
+modal deploy modal_app.py
```
-# Server Deployment
-
-To deploy to [Modal](https://modal.com/) server, simply modify `modal_app.py` according to your requirements and run `modal deploy modal_app.py`
+> [!NOTE]
+> You must update the root `.env` file for the app to recognize the deployed backend
diff --git a/flask/requirements.txt b/flask/requirements.txt
@@ -6,7 +6,6 @@ fal-client
flask
flask-cors
kornia
-modal
numpy
opencv-python
pillow
diff --git a/lib/ui/pages/stylesheet_page.dart b/lib/ui/pages/stylesheet_page.dart
@@ -28,6 +28,8 @@ class StylesheetPage extends StatefulWidget {
class _StylesheetPageState extends State<StylesheetPage> {
late int _currentProjectId;
bool _isLoading = false;
+ // State to toggle hex code visibility
+ bool _showHexCodes = false;
StylesheetData? _stylesheetData;
String? _rawJsonString;
@@ -80,7 +82,6 @@ class _StylesheetPageState extends State<StylesheetPage> {
super.initState();
_currentProjectId = widget.projectId;
if (widget.autoGenerate) {
- // Generate stylesheet automatically after a short delay to ensure page is built
WidgetsBinding.instance.addPostFrameCallback((_) {
_generateStylesheet();
});
@@ -129,7 +130,6 @@ class _StylesheetPageState extends State<StylesheetPage> {
StylesheetData? data;
if (rawJson != null && rawJson.isNotEmpty) {
- // Use the service to parse
data = _stylesheetService.parse(rawJson);
}
@@ -194,7 +194,6 @@ class _StylesheetPageState extends State<StylesheetPage> {
}),
onSettingsPressed: () {},
),
- // Only show content once full stylesheet is parsed atleast once
body: _isLoading
? const Center(child: CircularProgressIndicator(color: Variables.textPrimary))
: (_stylesheetData == null && _rawJsonString == null)
@@ -281,7 +280,8 @@ class _StylesheetPageState extends State<StylesheetPage> {
);
}
- Widget _buildSectionHeader(String title, {bool showArrow = true}) {
+ // Modified to support a custom trailing widget (e.g. Eye Icon)
+ Widget _buildSectionHeader(String title, {bool showArrow = true, Widget? trailing}) {
return Padding(
padding: const EdgeInsets.only(bottom: 12),
child: Row(
@@ -299,7 +299,9 @@ class _StylesheetPageState extends State<StylesheetPage> {
),
),
),
- if (showArrow)
+ if (trailing != null)
+ trailing
+ else if (showArrow)
Transform.rotate(
angle: 3.14159,
child: SvgPicture.asset(
@@ -329,10 +331,8 @@ class _StylesheetPageState extends State<StylesheetPage> {
}
Widget _buildLogosSection(dynamic data) {
- // Use manually uploaded logos
List<String> logoPaths = List.from(_logoPaths);
- // Also add any logos from data if present
if (data is List) {
for (var item in data) {
if (item is Map && item.containsKey('path')) logoPaths.add(item['path'].toString());
@@ -352,7 +352,6 @@ class _StylesheetPageState extends State<StylesheetPage> {
separatorBuilder: (_, __) => const SizedBox(width: 8),
itemBuilder: (context, index) {
if (index == logoPaths.length) {
- // Add button
return GestureDetector(
onTap: _pickLogo,
child: Container(
@@ -506,7 +505,19 @@ class _StylesheetPageState extends State<StylesheetPage> {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
- _buildSectionHeader("Colors", showArrow: false),
+ // Using custom trailing widget for the Eye Icon toggle
+ _buildSectionHeader(
+ "Colors",
+ showArrow: false,
+ trailing: GestureDetector(
+ onTap: () => setState(() => _showHexCodes = !_showHexCodes),
+ child: Icon(
+ _showHexCodes ? Icons.visibility : Icons.visibility_outlined,
+ color: Variables.textPrimary,
+ size: 20,
+ ),
+ ),
+ ),
Wrap(
spacing: 8, runSpacing: 8,
children: colors.take(5).map((color) => _buildColorSwatch(color)).toList(),
@@ -517,9 +528,25 @@ class _StylesheetPageState extends State<StylesheetPage> {
}
Widget _buildColorSwatch(Color color) {
+ final String hexCode = '#${color.value.toRadixString(16).padLeft(8, '0').substring(2).toUpperCase()}';
+ final Color textColor = color.computeLuminance() > 0.5 ? Colors.black : Colors.white;
+
return Container(
width: 104, height: 52,
decoration: BoxDecoration(color: color, borderRadius: BorderRadius.circular(8)),
+ alignment: Alignment.center,
+ // Only show text if _showHexCodes is true
+ child: _showHexCodes
+ ? Text(
+ hexCode,
+ style: TextStyle(
+ fontFamily: 'GeneralSans',
+ fontSize: 13,
+ fontWeight: FontWeight.w500,
+ color: textColor,
+ ),
+ )
+ : null,
);
}