Skip to content

Commit

Permalink
Merge branch 'ShiftHackZ:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
Itsfitts committed Aug 14, 2024
2 parents 3ea4970 + 989bc02 commit 26d0132
Show file tree
Hide file tree
Showing 621 changed files with 29,102 additions and 1,728 deletions.
26 changes: 26 additions & 0 deletions .github/workflows/android_test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: AndroidTest

on:
pull_request :
branches : [ master ]
push :
branches : [ master ]

jobs:
test-feature:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/[email protected]
- name: Set up JDK 17
uses: actions/[email protected]
with:
distribution: 'adopt'
java-version: '17'

- name: Grant execute permissions for gradlew
run: chmod +x ./gradlew

- name: Run Tests with Gradle
run: ./gradlew clean testDebugUnitTest
39 changes: 0 additions & 39 deletions .github/workflows/build_release.yml

This file was deleted.

Empty file modified .idea/inspectionProfiles/Project_Default.xml
100755 → 100644
Empty file.
43 changes: 31 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,22 @@
[![F-Droid](docs/assets/fdroid.png)](https://f-droid.org/packages/com.shifthackz.aisdv1.app.foss)
[![4pda](docs/assets/4pda.png)](https://4pda.to/forum/index.php?showtopic=1082639)

Stable Diffusion AI is an easy-to-use app that lets you quickly generate images from text or other images with just a few clicks. With this app, you can communicate with your own server and generate high-quality images in seconds.
Stable Diffusion AI (SDAI) is an easy-to-use app that:

- Brings you the power of digital art creativity with Stable Diffusion AI
- Gives you freedom to choose your AI generation provider
- Has no ADs, telemetry and does not spy on you

## Screenshots

![](docs/assets/scr_group_1.png)
![](docs/assets/scr_group_2.png)

## Features

- Can use server environment powered by [AI Horde](https://stablehorde.net/) (a crowdsourced distributed cluster of Stable Diffusion workers)
- Can use server environment powered by [Stable-Diffusion-WebUI](https://github.com/AUTOMATIC1111/stable-diffusion-webui) (AUTOMATIC1111)
- Can use server environment powered by [SwarmUI](https://github.com/mcmonkeyprojects/SwarmUI)
- Can use server envitonment powered by [Hugging Face Inference API](https://huggingface.co/docs/api-inference/quicktour).
- Can use server environment powered by [OpenAI](https://platform.openai.com/docs/api-reference/images) (DALL-E-2, DALL-E-3).
- Can use server environment powered by [Stability AI](https://platform.stability.ai/).
Expand All @@ -36,7 +46,7 @@ Stable Diffusion AI is an easy-to-use app that lets you quickly generate images
- Mask mode (Masked, not masked)
- Masked content (Fill, Original, Latent noise, Latent nothing)
- Inpaint area (Whole picture, only masked)
- Only maked padding (0 to 256 px)
- Only masked padding (0 to 256 px)
- Batch generation with maximum of 20 images (for A1111 and Horde)
- Lora picker (for A1111)
- Textual inversion picker (for A1111)
Expand Down Expand Up @@ -66,35 +76,43 @@ You can have it running either on your own hardware with modern GPU from Nvidia
1. Follow the setup instructions on [Stable-Diffusion-WebUI](https://github.com/AUTOMATIC1111/stable-diffusion-webui) repository.
2. Add the arguments `--api --listen` to the command line arguments of WebUI launch script.
3. After running the server, get the IP address, or URL of your WebUI server.
4. On the first launch, app will ask you for the server URL, enter it and press Connect button. If you want to change the server URL, go to Settings tab, choose Configure option, and repeat the setup flow.
4. On the first launch, app will ask you for the server URL, enter it and press "Connect" button. If you want to change the server URL, go to Settings tab, choose "Configure" option and repeat the setup flow.

If for some reason you have no ability to run your server instance, you can toggle the **Demo mode** switch on server setup page: it will allow you to test the app and get familiar with it, but it will return some mock images instead of AI-generated ones.

### Option 2: Use your own SwarmUI instance

This requires you to have the SwarmUI that is running in server mode.

You can have it running either on your own hardware with modern GPU from Nvidia or AMD, or running it using Google Colab.

If for some reason you have no ability to run your server instance, you can toggle the **Demo mode** swith on server setup page: it will allow you to test the app and get familiar with it, but it will return some mock images instead of AI-generated ones.
Please refer to the [SwarmUI documentation](https://github.com/mcmonkeyprojects/SwarmUI?tab=readme-ov-file#swarmui) for installation instructions.

### Option 2: Use AI Horde
### Option 3: Use AI Horde

[AI Horde](https://stablehorde.net/) is a crowdsourced distributed cluster of Image generation workers and text generation workers.

AI Horde requires to use API KEY, this mobile app alows to use either default API KEY (which is "0000000000"), or type your own. You can sign up and get your own AI Horde API KEY [here](https://stablehorde.net/register).
AI Horde requires to use API KEY, this mobile app allows to use either default API KEY (which is "0000000000"), or type your own. You can sign up and get your own AI Horde API KEY [here](https://stablehorde.net/register).

### Option 3: Hugging Face Inference
### Option 4: Hugging Face Inference

[Hugging Face Inference API](https://huggingface.co/docs/api-inference/index) allows to test and evaluate, over 150,000 publicly accessible machine learning models, or your own private models, via simple HTTP requests, with fast inference hosted on Hugging Face shared infrastructure. This service is free, but is rate-limited.

Hugging Face Inference requires to use API KEY, which can be created in [Hugging Face account settings](https://huggingface.co/settings/tokens).

### Option 4: OpenAI
### Option 5: OpenAI

OpenAI provides a service for text to image generation using [DALLE-2](https://openai.com/dall-e-2) or [DALLE-3](https://openai.com/dall-e-3) models. This service is paid,
OpenAI provides a service for text to image generation using [DALLE-2](https://openai.com/dall-e-2) or [DALLE-3](https://openai.com/dall-e-3) models. This service is paid.

OpenAI requires to use API KEY, which can be created in [OpenAI API Key settings](https://platform.openai.com/api-keys).

### Option 5: StabilityAI
### Option 6: StabilityAI

[StabilityAI](https://platform.stability.ai/) is the image generation service provided by DreamStudio.

StabilityAI requires to use API KEY, which can be created in [API Keys page](https://platform.stability.ai/account/keys).

### Option 6: Local Diffusion (Beta)
### Option 7: Local Diffusion (Beta)

Only **txt2img** mode is supported.

Expand All @@ -112,12 +130,13 @@ User interface of the app is translated for languages listed in this table:
| Ukrainian | 0.1.0 | `Translated` |
| Turkish | 0.4.1 | `Translated` |
| Russian | 0.5.5 | `Translated` |
| Chinese (Simplified) | 0.6.2 | `Translated` |

Any contributions to the translations are welcome.

## Difference between builds from Google Play and F-Droid/GitHub releases

As Google Play has some policies that app needs to be compliant with in order to be allowed to publist on Google Play there are some differences between builds distributed via Google Play and F-Droid/GitHub releases, listed in table.
As Google Play has some policies that app needs to be compliant with in order to be allowed to publish on Google Play there are some differences between builds distributed via Google Play and F-Droid/GitHub releases, listed in this table:

| Feature | Google Play build | F-Droid/GitHub build | Reason |
| --- |:---:|:---:| --- |
Expand Down
10 changes: 7 additions & 3 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ android {
namespace 'com.shifthackz.aisdv1.app'
defaultConfig {
applicationId "com.shifthackz.aisdv1.app"
versionName "0.6.1"
versionCode 180
versionName "0.6.3"
versionCode 183

buildConfigField "String", "IMAGE_CDN_URL", "\"https://random.imagecdn.app/\""
buildConfigField "String", "HUGGING_FACE_URL", "\"https://huggingface.co/\""
Expand All @@ -34,8 +34,9 @@ android {
buildConfigField "String", "DONATE_URL", "\"https://www.buymeacoffee.com/shifthackz\""
buildConfigField "String", "GITHUB_SOURCE_URL", "\"https://github.com/ShiftHackZ/Stable-Diffusion-Android\""
buildConfigField "String", "SETUP_INSTRUCTIONS_URL", "\"https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki\""
buildConfigField "String", "SWARM_UI_INFO_URL", "\"https://github.com/mcmonkeyprojects/SwarmUI/tree/master/docs\""

resourceConfigurations = ["en", "ru", "uk", "tr"]
resourceConfigurations = ["en", "ru", "uk", "tr", "zh"]
}

def hasPropertiesFile = new File("app/keystore/signing.properties").exists()
Expand Down Expand Up @@ -89,13 +90,15 @@ android {
dependencies {
implementation project(":core:common")
implementation project(":core:imageprocessing")
implementation project(":core:notification")
implementation project(":core:validation")
implementation project(":presentation")
implementation project(":network")
implementation project(":storage")
implementation project(":domain")
implementation project(":feature:auth")
implementation project(":feature:diffusion")
implementation project(":feature:work")
implementation project(":data")
implementation project(":demo")
implementation di.koinCore
Expand All @@ -106,6 +109,7 @@ dependencies {
implementation log.timber
implementation ui.catppuccinSplashscreen
implementation ui.catppuccinLegacy
implementation androidx.workManager
}

kapt {
Expand Down
31 changes: 31 additions & 0 deletions app/src/dev/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android">

<uses-feature
android:name="android.hardware.camera"
android:required="false" />

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />

<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="32" />

<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="31"
tools:ignore="ScopedStorage" />

<uses-permission
android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />

</manifest>
3 changes: 3 additions & 0 deletions app/src/foss/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />

<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE"
Expand Down
11 changes: 11 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@
</intent-filter>
</activity>

<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
tools:node="remove">
</provider>

<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
Expand All @@ -35,6 +41,11 @@
android:resource="@xml/file_provider_paths" />
</provider>

<service
android:name="androidx.work.impl.foreground.SystemForegroundService"
android:foregroundServiceType="dataSync"
tools:node="merge" />

<service
android:name="androidx.appcompat.app.AppLocalesMetadataHolderService"
android:enabled="false"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,29 @@ import android.app.Application
import android.database.CursorWindow
import android.os.StrictMode
import android.os.StrictMode.VmPolicy
import androidx.work.Configuration
import androidx.work.WorkManager
import com.shifthackz.aisdv1.app.di.featureModule
import com.shifthackz.aisdv1.app.di.preferenceModule
import com.shifthackz.aisdv1.app.di.providersModule
import com.shifthackz.aisdv1.core.common.log.FileLoggingTree
import com.shifthackz.aisdv1.core.common.log.errorLog
import com.shifthackz.aisdv1.core.imageprocessing.di.imageProcessingModule
import com.shifthackz.aisdv1.core.notification.di.notificationModule
import com.shifthackz.aisdv1.core.validation.di.validatorsModule
import com.shifthackz.aisdv1.data.di.dataModule
import com.shifthackz.aisdv1.demo.di.demoModule
import com.shifthackz.aisdv1.domain.di.domainModule
import com.shifthackz.aisdv1.network.di.networkModule
import com.shifthackz.aisdv1.presentation.di.presentationModule
import com.shifthackz.aisdv1.storage.di.databaseModule
import com.shifthackz.aisdv1.work.di.SdaiWorkerFactory
import com.shifthackz.aisdv1.work.di.backgroundWorkModule
import org.koin.android.ext.android.inject
import org.koin.android.ext.koin.androidContext
import org.koin.core.context.startKoin
import timber.log.Timber


class AiStableDiffusionClientApp : Application() {

override fun onCreate() {
Expand All @@ -32,6 +37,7 @@ class AiStableDiffusionClientApp : Application() {
initializeKoin()
initializeLogging()
initializeCursorSize()
initializeWorkManager()
}

/**
Expand All @@ -53,12 +59,14 @@ class AiStableDiffusionClientApp : Application() {
private fun initializeKoin() = startKoin {
androidContext(this@AiStableDiffusionClientApp)
modules(
notificationModule,
demoModule,
*featureModule,
preferenceModule,
providersModule,
*domainModule,
*dataModule,
backgroundWorkModule,
networkModule,
databaseModule,
validatorsModule,
Expand All @@ -73,4 +81,17 @@ class AiStableDiffusionClientApp : Application() {
}
Timber.plant(FileLoggingTree())
}

private fun initializeWorkManager() {
try {
val workerFactory: SdaiWorkerFactory by inject()
val configuration = Configuration.Builder()
.setWorkerFactory(workerFactory)
.build()

WorkManager.initialize(this, configuration)
} catch (e: Exception) {
errorLog(e)
}
}
}
Loading

0 comments on commit 26d0132

Please sign in to comment.