Configuration¶
pic takes different approach to make a configuration. Instead of using javascript, it uses a plain JSON file. It’s because this tool doesn’t plan to be an advance tool but just simply combining different images together. So the configuration should be simple.
name
¶
This field is used as the directory name inside output directory to store the images. For instance, if we
change the name
into “sembarang” then when it generates the image, we will find our images inside
output/sembarang/images directory instead of output/Gambar/images.
This field is also used as the value of name
in the metadata. We will find the name
field has changed to
sembarang #1, sembarang #2, … instead of Gambar #1, Gambar #2, ….
amount
¶
This field is used to specify how many images we want to generate. We can specify the maximum amount up to 4,294,967,295 in the configuration file.
Under the hood, amount is using
uint32
type
batchSize
¶
This field is used to specify how many images are being processed at a time. Let’s take example from Lego house again. Let’s say we want to build 100 Lego houses, if we are going to build them all ourself that means we can build 1 house at a time. After the first one is done, we are building the second house. However, if we want to do it faster, we’ll need another hand. Let’s say we want to build 10 houses at a time, that means we need 9 other builders to help build the houses.
The amount of builder is similar to “batch size”. So if we set the batch size to 10 that means it will process 10 images at a time. This configuration is useful if we have multiple high-performance CPU and we want to generate all images quickly. The maximum batch size is 255.
Increasing batch size isn’t always increasing the performance, if the size is too big then it will send a huge load on the CPU and may prematurely stop the process. So keep monitoring on our CPU load when increasing the batch size
Under the hood, batchSize is using
byte
type
startTokenId
¶
This field is used to specify the starting point. Think of it like counting a number. If startTokenId = 2
then
we start counting from 2 then continue to 3, 4, 5, and so on. When we generate images, we name them with number
like 1.png, 2.png, … or 1.json, 2.json, … for metadata. startTokenId
will specify what’s the name of
the first file that will be generated. If we specify 23 as its value, then the first generated filename will be 23.png
or 23.json
then continue to increment the number by 1, which are 24, 25, 26, and so on.
width
¶
This field specifies the width of the generated image in pixel. If we specify 1000, it means the image width is 1000px. This can be used to resize the image to fit our case. The maximum image width is 65535
Under the hood, width is using
uint16
type
height
¶
This field specifies the height of the generated image in pixel. If we specify 1000, it means the image height is 1000px. This can be used to resize the image to fit our case. The maximum image height is 65535
Under the hood, height is using
uint16
type
outputDirectory
¶
This field is used to specify in which directory we want to store the output. The value in outputDirectory
will
not affect the image name nor the name in metadata. Say if we specify the value as “Other Image” then the
generated image will be stored in Other Image/Gambar/images instead of output/Gambar/images.
unique
¶
This field has no effect. Regardless of the value, it will not make any different. unique
is intended to
enable whether we want to generate unique images or not. Let’s say we generate 100 images and all of them should
be unique, then this field is intended for that functionality but it’s not ready yet.
We can abuse random
function to generate different combination until it gets a unique one, however
that approaches sometimes take a lot of time. There must be a better way to do it efficiently. Discrete math,
probably.
layers
¶
This field is used to setup the layer. Which image goes below other image and which goes on top of others. Let’s say we have the following value:
{
"layers": [
"Head",
"Eyes",
"Mouth",
"Head Accessories"
]
}
It means “Head” will be at the bottom. Then “Eyes” will be on top of the “Head” layer and “Mouth” layer is on top of “Eyes” layer. Last one, “Head Accessories” will be on top of the rest.
The name of the layer is actually the folder name inside layers directory. So if we put a
new folder in layers directory, we should add its name in the layers
configuration to set on which
layer we want to put it.
distribution
¶
This field is used to set distribution for each image in layers directory. Initially, we make the value empty like this
"distribution": {}
then when we run dotnet run
, it will be filled automatically with images path that found in layers
directory. Say we add Head layer in the configuration, then it will try to find image inside layers/Head
directory. By default, all distribution is 0 which means none of them will be used to generate image. So we have
to manually set the value. If we set the value as 35, it means 35% of total images will contain specific image.
Take the following example:
{
"distribution": {
"Head": {
"layers/Head/Blue.png": 40,
"layers/Head/Gray.png": 60
}
}
}
The example above means, 40% of total images will contain Blue.png image and 60% of them contain Gray.png. Details about distribution can be read in [