Skip to content

Commit

Permalink
Add Pictures faker (#254)
Browse files Browse the repository at this point in the history
  • Loading branch information
serpro69 authored Nov 17, 2024
1 parent 8e77afd commit 3cd58d7
Show file tree
Hide file tree
Showing 218 changed files with 267 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
[discrete]
=== Added

* https://github.com/serpro69/kotlin-faker/pull/254[#254] (:faker) Add Pictures faker
* https://github.com/serpro69/kotlin-faker/pull/245[#245] (:extension) Add extension for testing with BLNS
* https://github.com/serpro69/kotlin-faker/pull/243[#243] (:core) Add collection element and map k/v type gen for random class instance
* https://github.com/serpro69/kotlin-faker/pull/234[#234] (:extension) Add extension module for kotest property testing
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -584,7 +584,7 @@ class FakerService {
* has declared a provider that matches the [simpleClassName] parameter.
*/
private fun getProviderData(primary: YamlCategory, secondary: Category? = null): YamlCategoryData {
return dictionary[primary]
return dictionary[primary]
?: secondary?.let { load(primary, secondary)[primary] }
?: load(primary)[primary]
?: throw NoSuchElementException("Category $primary not found in $this")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
---

== `Faker().uiFaces`

.Available Functions
[%collapsible]
====
[source,kotlin]
----
Faker().uiFaces.avatar()
----
====
53 changes: 53 additions & 0 deletions faker/pictures/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
## `PicturesFaker`

[![Maven Central](https://img.shields.io/maven-central/v/io.github.serpro69/kotlin-faker-pictures?style=for-the-badge)](https://search.maven.org/artifact/io.github.serpro69/kotlin-faker-pictures)
[![Sonatype Nexus (Snapshots)](https://img.shields.io/nexus/s/io.github.serpro69/kotlin-faker-pictures?label=snapshot-version&server=https%3A%2F%2Foss.sonatype.org&style=for-the-badge&color=yellow)](#downloading)

Provides access to fake data generators within the Pictures domain.

## Usage

Documentation for kotlin-faker is available at [serpro69.github.io/kotlin-faker/](https://serpro69.github.io/kotlin-faker/).

### Downloading

Latest releases are always available on maven central.

**With gradle**

```groovy
dependencies {
implementation 'io.github.serpro69:kotlin-faker:$version'
implementation 'io.github.serpro69:kotlin-faker-pictures:$version'
}
```

**With maven**

```xml
<dependencies>
<dependency>
<groupId>io.github.serpro69</groupId>
<artifactId>kotlin-faker</artifactId>
<version>${version}</version>
</dependency>
<dependency>
<groupId>io.github.serpro69</groupId>
<artifactId>kotlin-faker-pictures</artifactId>
<version>${version}</version>
</dependency>
</dependencies>
```

_NB! An additional fake data provider like 'pictures' requires the main `kotlin-faker` dependency to be on the classpath._

### Generating data

```kotlin
// NB! the package you import if using multiple fakers
import io.github.serpro69.kfaker.pictures.faker

val faker = faker { }

faker.uiFaces.avatar()
```
42 changes: 42 additions & 0 deletions faker/pictures/api/pictures.api
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
public final class io/github/serpro69/kfaker/pictures/PicturesFaker : io/github/serpro69/kfaker/AbstractFaker {
public fun <init> ()V
public fun <init> (Lio/github/serpro69/kfaker/FakerConfig;)V
public synthetic fun <init> (Lio/github/serpro69/kfaker/FakerConfig;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun getUiFaces ()Lio/github/serpro69/kfaker/pictures/provider/UiFaces;
}

public final class io/github/serpro69/kfaker/pictures/PicturesFaker$Builder : io/github/serpro69/kfaker/AbstractFaker$Builder {
public synthetic fun build ()Lio/github/serpro69/kfaker/AbstractFaker;
public fun build ()Lio/github/serpro69/kfaker/pictures/PicturesFaker;
}

public final class io/github/serpro69/kfaker/pictures/PicturesFakerKt {
public static final fun faker (Lkotlin/jvm/functions/Function1;)Lio/github/serpro69/kfaker/pictures/PicturesFaker;
}

public final class io/github/serpro69/kfaker/pictures/provider/UiFaces : io/github/serpro69/kfaker/provider/FakeDataProvider {
public final fun avatar (Lio/github/serpro69/kfaker/pictures/provider/UiFacesAvatarType;Lio/github/serpro69/kfaker/pictures/provider/UiFacesAvatarGender;)[B
public static synthetic fun avatar$default (Lio/github/serpro69/kfaker/pictures/provider/UiFaces;Lio/github/serpro69/kfaker/pictures/provider/UiFacesAvatarType;Lio/github/serpro69/kfaker/pictures/provider/UiFacesAvatarGender;ILjava/lang/Object;)[B
}

public final class io/github/serpro69/kfaker/pictures/provider/UiFacesAvatarGender : java/lang/Enum {
public static final field FEMALE Lio/github/serpro69/kfaker/pictures/provider/UiFacesAvatarGender;
public static final field MALE Lio/github/serpro69/kfaker/pictures/provider/UiFacesAvatarGender;
public static fun getEntries ()Lkotlin/enums/EnumEntries;
public fun toString ()Ljava/lang/String;
public static fun valueOf (Ljava/lang/String;)Lio/github/serpro69/kfaker/pictures/provider/UiFacesAvatarGender;
public static fun values ()[Lio/github/serpro69/kfaker/pictures/provider/UiFacesAvatarGender;
}

public final class io/github/serpro69/kfaker/pictures/provider/UiFacesAvatarType : java/lang/Enum {
public static final field ABSTRACT Lio/github/serpro69/kfaker/pictures/provider/UiFacesAvatarType;
public static final field ALIEN Lio/github/serpro69/kfaker/pictures/provider/UiFacesAvatarType;
public static final field CARTOON Lio/github/serpro69/kfaker/pictures/provider/UiFacesAvatarType;
public static final field HUMAN Lio/github/serpro69/kfaker/pictures/provider/UiFacesAvatarType;
public static final field ROBOT Lio/github/serpro69/kfaker/pictures/provider/UiFacesAvatarType;
public static fun getEntries ()Lkotlin/enums/EnumEntries;
public fun toString ()Ljava/lang/String;
public static fun valueOf (Ljava/lang/String;)Lio/github/serpro69/kfaker/pictures/provider/UiFacesAvatarType;
public static fun values ()[Lio/github/serpro69/kfaker/pictures/provider/UiFacesAvatarType;
}

3 changes: 3 additions & 0 deletions faker/pictures/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
plugins {
`faker-provider-conventions`
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package io.github.serpro69.kfaker.pictures

import io.github.serpro69.kfaker.AbstractFaker
import io.github.serpro69.kfaker.FakerConfig
import io.github.serpro69.kfaker.FakerDsl
import io.github.serpro69.kfaker.fakerConfig
import io.github.serpro69.kfaker.pictures.provider.UiFaces
import java.awt.image.BufferedImage
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
import javax.imageio.ImageIO

/**
* Typealias for the [PicturesFaker]
*/
typealias Faker = PicturesFaker

/**
* Provides access to fake data generators within the Pictures domain.
*
* Each category (generator) from this [PicturesFaker] is represented by a property
* that (usually) has the same name as the `.yml` dictionary file.
*
* @property unique global provider for generation of unique values.
*/
@Suppress("unused")
class PicturesFaker @JvmOverloads constructor(config: FakerConfig = fakerConfig { }) : AbstractFaker(config) {

val uiFaces: UiFaces by lazy { UiFaces(randomService) }

@FakerDsl
/**
* DSL builder for creating instances of [Faker]
*/
class Builder internal constructor() : AbstractFaker.Builder<Faker>() {

/**
* Builds an instance of [Faker] with this [config].
*/
override fun build(): Faker = Faker(config)
}
}

/**
* Applies the [block] function to [PicturesFaker.Builder]
* and returns as an instance of [PicturesFaker] from that builder.
*/
fun faker(block: PicturesFaker.Builder.() -> Unit): PicturesFaker = PicturesFaker.Builder().apply(block).build()

/**
* Returns the [input] as 32bit RGBA [ByteArray]
*/
internal fun convertTo32BitRGBA(input: ByteArray): ByteArray {
// read the input ByteArray into a BufferedImage
val inputImage = ImageIO.read(ByteArrayInputStream(input))
?: throw IllegalArgumentException("Invalid image data")
// create a new BufferedImage in 32-bit RGBA format
val rgbaImage = BufferedImage(inputImage.width, inputImage.height, BufferedImage.TYPE_INT_ARGB)
// draw the input image onto the RGBA BufferedImage
val graphics = rgbaImage.createGraphics()
graphics.drawImage(inputImage, 0, 0, null)
graphics.dispose()
// extract raw RGBA data from the BufferedImage
val width = rgbaImage.width
val height = rgbaImage.height
val pixelData = IntArray(width * height)
rgbaImage.getRGB(0, 0, width, height, pixelData, 0, width)
// convert the IntArray to a ByteArray
val byteArrayOutput = ByteArrayOutputStream()
for (pixel in pixelData) {
byteArrayOutput.write((pixel shr 16) and 0xFF) // Red
byteArrayOutput.write((pixel shr 8) and 0xFF) // Green
byteArrayOutput.write(pixel and 0xFF) // Blue
byteArrayOutput.write((pixel shr 24) and 0xFF) // Alpha
}
return byteArrayOutput.toByteArray()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
@file:Suppress("unused")

package io.github.serpro69.kfaker.pictures.provider

import io.github.serpro69.kfaker.RandomService
import io.github.serpro69.kfaker.pictures.convertTo32BitRGBA
import io.github.serpro69.kfaker.pictures.provider.UiFacesAvatarGender.FEMALE
import io.github.serpro69.kfaker.provider.FakeDataProvider

/**
* [FakeDataProvider] implementation for AI-generated [UiFaces](https://uifaces.co/#browse-avatars) avatars.
*/
class UiFaces internal constructor(
private val randomService: RandomService
) : FakeDataProvider {
fun avatar(type: UiFacesAvatarType? = null, gender: UiFacesAvatarGender? = null): ByteArray {
val t = type ?: randomService.nextEnum()
val g = gender ?: randomService.nextEnum()
val n = randomService.randomValue(if (g == FEMALE) t.f else t.m)
val instr = requireNotNull(javaClass.classLoader.getResourceAsStream("uifaces/$t/$g/$n.jpg")) {
"UiFaces avatar $t/$g/$n.jpg does not exist"
}
return convertTo32BitRGBA(instr.readBytes())
}
}

enum class UiFacesAvatarGender {
FEMALE,
MALE,
;

override fun toString(): String = name.lowercase()
}

enum class UiFacesAvatarType(internal val f: List<Int> = emptyList(), internal val m: List<Int> = emptyList()) {
ABSTRACT(
listOf(1, 5, 6, 8, 12, 15, 16, 23, 26, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42),
listOf(2, 3, 4, 7, 9, 10, 11, 13, 14, 17, 18, 19, 20, 21, 22, 24, 25, 27, 43, 44, 45, 46, 47, 48, 49, 50, 51),
),
ALIEN(
listOf(1, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 16, 18),
listOf(2, 7, 14, 15, 17)
),
CARTOON(
listOf(2, 4, 6, 7, 8, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 27, 29, 32),
listOf(3, 5, 9, 10, 11, 25, 26, 28, 30, 31)
),
HUMAN(
listOf(
1, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 26, 28, 32, 33, 34, 35, 36, 38, 40, 43, 44, 47, 48, 49, 51, 52,
55, 56, 64, 66, 67, 68, 69, 71, 74, 76, 78
),
listOf(
2, 3, 4, 5, 7, 18, 19, 20, 21, 22, 23, 24, 25, 27, 29, 30, 31, 37, 39, 41, 42, 45, 46, 50, 53, 54, 57, 58,
59, 60, 61, 62, 63, 65, 70, 72, 73, 75, 77,
)
),
ROBOT(
listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15),
listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15),
),
;

override fun toString(): String = name.lowercase()
}
11 changes: 11 additions & 0 deletions faker/pictures/src/main/resources/uifaces/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
This repo contains free AI-generated avatars from [uifaces](https://uifaces.co/#browse-avatars).

These images were downloaded from the above URI and are provided as is without any warranty.

As of 2024-10-15, the AI-generated avatars on UI Faces are distributed under the following terms:

> ✨ AI-generated images
>
> Images generated by OpenAI's DALL-E are offered under a license that allows for both internal and commercial use. This means you can freely utilize these AI-generated photos in a variety of settings, from personal projects to commercial applications, without concerns about licensing restrictions.
See the [uifaces_licenses](./uifaces_licenses.png) and the [licenses](https://uifaces.co/licenses) page for more details.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ val fakers =
"misc",
"movies",
"music",
"pictures",
"sports",
"tech",
"travel",
Expand Down

0 comments on commit 3cd58d7

Please sign in to comment.