Skip to content

Commit

Permalink
add product image styles
Browse files Browse the repository at this point in the history
  • Loading branch information
boxblinkracer committed Dec 27, 2024
1 parent 49edf94 commit f52d910
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 32 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ using the [Keep a CHANGELOG](https://keepachangelog.com/) principles.

- Add brand new option to generate **product variants**. Configure what property group to use, and AI will automatically generate all variants, if appropriate for the product.
- Add 2 files in the cache directory for the generated prompt and response of product generation requests.
- Add new product image styles. Open the plugin configuration an select what styles to use for the product images.

### Changed

Expand Down
38 changes: 26 additions & 12 deletions src/Command/ProductGenerateCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use AIDemoData\Service\Generator\ProductGenerator;
use AIDemoData\Service\Generator\ProductGeneratorInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
Expand Down Expand Up @@ -121,27 +122,43 @@ protected function execute(InputInterface $input, OutputInterface $output): int

# -----------------------------------------------------------------------------------------------------------------------

$rows = [];

if ($category === '') {
$this->io->note('No category given. Products will be generated without a category.');
$rows[] = ['Category', '-'];
} else {
$this->io->note('Products will be generated for category: ' . $category);
$rows[] = ['Category', $category];
}

if ($salesChannel === '') {
$this->io->note('No sales channel given. Products will be added the first found storefront sales channel.');
$rows[] = ['Sales Channel', '-'];
} else {
$this->io->note('Products will be added to sales channel: ' . $salesChannel);
$rows[] = ['Sales Channel', $salesChannel];
}

$rows[] = ['Description Length', $descriptionLength . ' characters'];

if ($withImages) {
$this->io->note('Images will be generated for the products: ' . $imgSize . 'px');
$rows[] = ['Generate Images', 'Yes'];
} else {
$this->io->note('Images will not be generated for the products.');
$rows[] = ['Generate Images', 'No'];
}

$imageStyles = $this->configService->getProductImageStyles();
$rows[] = ['Image Styles', implode(', ', $imageStyles)];

$rows[] = ['Image Size', $imgSize];


$this->io->note('Product description length: ' . $descriptionLength . ' characters');

$table = new Table($output);
$table->setStyle('default');
$table->setHeaders(['Configuration', 'Value']);
$table->setRows($rows);
$table->render();

$this->io->writeln('');
$this->io->writeln('');

# -----------------------------------------------------------------------------------------------------------------------

Expand All @@ -151,15 +168,14 @@ protected function execute(InputInterface $input, OutputInterface $output): int

# -----------------------------------------------------------------------------------------------------------------------

$this->io->writeln('Starting product generation...');

$this->productGenerator->generate(
$keyWords,
$count,
$category,
$salesChannel,
$descriptionLength,
$this->configService->getProductVariantPropertyGroupId()
$this->configService->getProductVariantPropertyGroupId(),
$imageStyles
);

if ($this->errorCount <= 0) {
Expand Down Expand Up @@ -193,8 +209,6 @@ public function onProductGenerating(string $number, string $name, int $count, in
*/
public function onProductGenerated(string $number, string $name, int $count, int $maxCount): void
{
$this->io->writeln('Product generated');

$this->generatedCount++;
}

Expand Down
37 changes: 33 additions & 4 deletions src/Resources/config/config.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,35 @@
<helpText>If enabled product images will be automatically generated if no CLI argument is provided.</helpText>
</input-field>

<input-field type="multi-select">
<name>productImageStyles</name>
<label>Image Styles</label>
<helpText>Select what styles you want to use for the images. These will be picked by random.</helpText>
<defaultValue>isolated</defaultValue>
<options>
<option>
<id>isolated</id>
<name>Isolated</name>
</option>
<option>
<id>transparent-background</id>
<name>Transparent Background</name>
</option>
<option>
<id>detailed-close-up</id>
<name>Detailed Close-up</name>
</option>
<option>
<id>lifestyle-context</id>
<name>Lifestyle Context</name>
</option>
<option>
<id>luxury</id>
<name>Luxury</name>
</option>
</options>
</input-field>

<input-field type="single-select">
<name>productImageSize</name>
<label>Image Size (px)</label>
Expand Down Expand Up @@ -73,12 +102,12 @@
<name>1024x1024</name>
</option>
<option>
<id>256x256</id>
<name>256x256</name>
<id>1792x1024</id>
<name>1792x1024</name>
</option>
<option>
<id>512x512</id>
<name>512x512</name>
<id>1024x1792</id>
<name>1024x1792</name>
</option>
</options>
</input-field>
Expand Down
21 changes: 21 additions & 0 deletions src/Service/Config/ConfigService.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ class ConfigService
*/
private $productVariantPropertyGroup;

/**
* @var string[]
*/
private $productImageStyles;


/**
* @param SystemConfigService $configService
Expand All @@ -53,6 +58,10 @@ public function __construct(SystemConfigService $configService)
$this->productDescriptionLength = $configService->getInt('AIDemoData.config.productDescriptionLength');

$this->productVariantPropertyGroup = $configService->getString('AIDemoData.config.productVariantPropertyGroup');

/** @var string[] $tmpImageStyles */
$tmpImageStyles = $configService->get('AIDemoData.config.productImageStyles');
$this->productImageStyles = $tmpImageStyles;
}

/**
Expand All @@ -79,6 +88,18 @@ public function getProductVariantPropertyGroupId(): string
return $this->productVariantPropertyGroup;
}

/**
* @return string[]
*/
public function getProductImageStyles(): array
{
if ($this->productImageStyles === null) {
return [];
}

return $this->productImageStyles;
}

/**
* @return string
*/
Expand Down
34 changes: 18 additions & 16 deletions src/Service/Generator/ProductGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -127,10 +127,12 @@ public function setGenerateImages(bool $generateImages, string $imageSize): void
* @param string $category
* @param string $salesChannel
* @param int $descriptionLength
* @param string $variantPropertyGroupId
* @param string[] $imageStyles
* @throws \JsonException
* @return void
*/
public function generate(string $keywords, int $maxCount, string $category, string $salesChannel, int $descriptionLength, string $variantPropertyGroupId)
public function generate(string $keywords, int $maxCount, string $category, string $salesChannel, int $descriptionLength, string $variantPropertyGroupId, array $imageStyles)
{
if (empty($keywords)) {
throw new \Exception('No keywords provided. Please tell the plugin what to generate.');
Expand All @@ -145,14 +147,14 @@ public function generate(string $keywords, int $maxCount, string $category, stri
$prompt .= 'the following properties should be generated.' . PHP_EOL;
$prompt .= 'Every resulting line should be in the order and sort provided below:' . PHP_EOL;
$prompt .= PHP_EOL;
$prompt .= 'product count.' . PHP_EOL;
$prompt .= 'product number code. should be 24 unique random alphanumeric.' . PHP_EOL;
$prompt .= 'name of the product.' . PHP_EOL;
$prompt .= 'description (about ' . $descriptionLength . ' characters).' . PHP_EOL;
$prompt .= 'price value (no currency just number).' . PHP_EOL;
$prompt .= 'EAN code.' . PHP_EOL;
$prompt .= 'SEO description (max 100 characters).' . PHP_EOL;
$prompt .= 'variant indicator (1 if variants make sense for the product, 0 if it does not make sense).' . PHP_EOL;
$prompt .= '- product count.' . PHP_EOL;
$prompt .= '- product number code. should be 24 unique random alphanumeric (always unique, maybe consider datetime now).' . PHP_EOL;
$prompt .= '- name of the product.' . PHP_EOL;
$prompt .= '- description (about ' . $descriptionLength . ' characters).' . PHP_EOL;
$prompt .= '- price value (no currency just number).' . PHP_EOL;
$prompt .= '- EAN code.' . PHP_EOL;
$prompt .= '- SEO description (max 100 characters).' . PHP_EOL;
$prompt .= '- variant indicator (1 if variants make sense for the product, 0 if it does not make sense).' . PHP_EOL;
$prompt .= PHP_EOL;
$prompt .= 'Please only create exactly this number of products: ' . $maxCount . PHP_EOL;
$prompt .= PHP_EOL;
Expand Down Expand Up @@ -214,7 +216,7 @@ public function generate(string $keywords, int $maxCount, string $category, stri
$this->callback->onProductImageGenerating();
}

$tmpImageFile = $this->generateImage($name, $description);
$tmpImageFile = $this->generateImage($name, $description, $imageStyles);
} else {
$tmpImageFile = '';
}
Expand All @@ -238,9 +240,6 @@ public function generate(string $keywords, int $maxCount, string $category, stri
$this->callback->onProductGenerated($number, $name, $currentCount, $maxCount);
}
} catch (\Exception $ex) {
var_dump($ex->getMessage());
var_dump($ex->getTraceAsString());

if ($this->callback !== null) {
$this->callback->onProductGenerationFailed($ex->getMessage(), $currentCount, $maxCount);
}
Expand Down Expand Up @@ -394,12 +393,15 @@ private function createProduct(string $id, string $name, string $number, string
/**
* @param string $productName
* @param string $productDescription
* @throws \Exception
* @param string[] $imageStyles
* @throws \JsonException
* @return string
*/
private function generateImage(string $productName, string $productDescription): string
private function generateImage(string $productName, string $productDescription, array $imageStyles): string
{
$prompt = $productName . ' ' . $productDescription;
$prompt = "Generate image for our online shop. It has to be really good and present the product in the best way possible." . PHP_EOL;
$prompt .= "Exactly stick to a style that matches one of these: " . implode(', ', $imageStyles) . PHP_EOL;
$prompt .= "Here are instructions about the product: " . $productName . ' ' . $productDescription . '.';

$url = $this->openAI->generateImage($prompt, $this->imageSize);

Expand Down
1 change: 1 addition & 0 deletions src/Service/OpenAI/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ public function generateImage(string $prompt, string $size): string
"prompt" => $prompt,
"n" => 1,
"size" => $size,
"style" => "natural",
"response_format" => "url",
]);

Expand Down

0 comments on commit f52d910

Please sign in to comment.