Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/440 Per-image customization for quality, size, and style in Image Generation #857

Open
wants to merge 18 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 51 additions & 4 deletions includes/Classifai/Features/ImageGeneration.php
Original file line number Diff line number Diff line change
Expand Up @@ -271,10 +271,11 @@ public function print_media_templates() {
return;
}

$settings = $this->get_settings();
$provider_id = $settings['provider'];
$number_of_images = absint( $settings[ $provider_id ]['number_of_images'] );
$provider_instance = $this->get_feature_provider_instance( $provider_id );
$settings = $this->get_settings();
$provider_id = $settings['provider'];
$number_of_images = absint( $settings[ $provider_id ]['number_of_images'] );
$per_image_settings = isset( $settings[ $provider_id ]['per_image_settings'] ) ? $settings[ $provider_id ]['per_image_settings'] : false;
$provider_instance = $this->get_feature_provider_instance( $provider_id );
?>

<?php // Template for the Generate images tab content. Includes prompt input. ?>
Expand All @@ -299,6 +300,52 @@ public function print_media_templates() {
?>
</p>
<textarea class="prompt" placeholder="<?php esc_attr_e( 'Enter prompt', 'classifai' ); ?>" rows="4" maxlength="<?php echo absint( $provider_instance->max_prompt_chars ); ?>"></textarea>
<?php if ( $per_image_settings ) : ?>
<br>
<input type="checkbox" id="view-additional-image-generation-settings" />
<label id="view-additional-image-generation-settings-label" for="view-additional-image-generation-settings">
<?php esc_html_e( 'View Additional Settings', 'classifai' ); ?>
</label>
<div class="additional-image-generation-settings hidden">
<label>
<span><?php esc_html_e( 'Quality:', 'classifai' ); ?></span>
<select class="quality" name="quality">
<?php
$quality_options = DallE::get_image_quality_options();
$quality = $settings[ $provider_id ]['quality'];
foreach ( $quality_options as $key => $value ) {
echo '<option value="' . esc_attr( $key ) . '" ' . selected( $quality, $key, false ) . '>' . esc_html( $value ) . '</option>';
}
?>
</select>
</label>
<label>
<span><?php esc_html_e( 'Size:', 'classifai' ); ?></span>
<select class="size" name="size">
<?php
$size_options = DallE::get_image_size_options();
$size = $settings[ $provider_id ]['image_size'];
foreach ( $size_options as $key => $value ) {
echo '<option value="' . esc_attr( $key ) . '" ' . selected( $size, $key, false ) . '>' . esc_html( $value ) . '</option>';
}
?>
</select>
</label>
<label>
<span><?php esc_html_e( 'Style:', 'classifai' ); ?></span>
<select class="style" name="style">
<?php
$style_options = DallE::get_image_style_options();
$style = $settings[ $provider_id ]['style'];
foreach ( $style_options as $key => $value ) {
echo '<option value="' . esc_attr( $key ) . '" ' . selected( $style, $key, false ) . '>' . esc_html( $value ) . '</option>';
}
?>
</select>
</label>
</div>
<br>
<?php endif; ?>
<button type="button" class="button button-secondary button-large button-generate">
<?php
if ( $number_of_images > 1 ) {
Expand Down
69 changes: 56 additions & 13 deletions includes/Classifai/Providers/OpenAI/DallE.php
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,7 @@ public function render_provider_fields() {
[
'option_index' => static::ID,
'label_for' => 'quality',
'options' => [
'standard' => __( 'Standard', 'classifai' ),
'hd' => __( 'High Definition', 'classifai' ),
],
'options' => self::get_image_quality_options(),
'default_value' => $settings['quality'],
'description' => __( 'The quality of the image that will be generated. High Definition creates images with finer details and greater consistency across the image but costs more.', 'classifai' ),
'class' => 'classifai-provider-field hidden provider-scope-' . static::ID,
Expand All @@ -129,11 +126,7 @@ public function render_provider_fields() {
[
'option_index' => static::ID,
'label_for' => 'image_size',
'options' => [
'1024x1024' => '1024x1024 (square)',
'1792x1024' => '1792x1024 (landscape)',
'1024x1792' => '1024x1792 (portrait)',
],
'options' => self::get_image_size_options(),
'default_value' => $settings['image_size'],
'description' => __( 'Size of generated images. Larger sizes cost more.', 'classifai' ),
'class' => 'classifai-provider-field hidden provider-scope-' . static::ID,
Expand All @@ -149,15 +142,65 @@ public function render_provider_fields() {
[
'option_index' => static::ID,
'label_for' => 'style',
'options' => [
'vivid' => __( 'Vivid', 'classifai' ),
'natural' => __( 'Natural', 'classifai' ),
],
'options' => self::get_image_style_options(),
'default_value' => $settings['style'],
'description' => __( 'The style of the generated images. Vivid causes more hyper-real and dramatic images. Natural causes more natural, less hyper-real looking images.', 'classifai' ),
'class' => 'classifai-provider-field hidden provider-scope-' . static::ID,
]
);

add_settings_field(
static::ID . '_per_image_settings',
esc_html__( 'Enable per-image settings for quality, size, and style', 'classifai' ),
[ $this, 'render_input' ],
$this->feature_instance->get_option_name(),
$this->feature_instance->get_option_name() . '_section',
[
'option_index' => static::ID,
'label_for' => 'per_image_settings',
'input_type' => 'checkbox',
'default_value' => $settings['per_image_settings'] ?? false,
'description' => __( 'Enable this to allow users to select the quality, size, and style of the generated image.', 'classifai' ),
'class' => 'classifai-user-based-opt-out',
]
);
}

/**
* Returns the quality options for the provider.
*
* @return array
*/
public static function get_image_quality_options() {
return array(
'standard' => __( 'Standard', 'classifai' ),
'hd' => __( 'High Definition', 'classifai' ),
);
}

/**
* Returns the image size options for the provider.
*
* @return array
*/
public static function get_image_size_options() {
return array(
'1024x1024' => '1024x1024 (square)',
'1792x1024' => '1792x1024 (landscape)',
'1024x1792' => '1024x1792 (portrait)',
);
}

/**
* Returns the style options for the provider.
*
* @return array
*/
public static function get_image_style_options() {
return array(
'vivid' => __( 'Vivid', 'classifai' ),
'natural' => __( 'Natural', 'classifai' ),
);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,22 @@ const Images = Backbone.Collection.extend( {
/**
* Send a request to our API endpoint.
*
* @param {string} prompt Prompt used in generating images.
* @param {string} prompt Prompt used in generating images.
* @param {string} quality Quality of the image.
* @param {string} size Size of the image.
* @param {string} style Style of the image.
*/
makeRequest: function ( prompt ) {
makeRequest: function ( prompt, quality, size, style ) {
this.fetch( {
type: 'get',
beforeSend: function ( xhr ) {
xhr.setRequestHeader( 'X-WP-Nonce', wpApiSettings.nonce );
},
data: {
prompt: prompt,
quality: quality,
size: size,
style: style,
format: 'b64_json',
},
reset: true,
Expand Down
31 changes: 31 additions & 0 deletions src/js/features/image-generation/media-modal/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,35 @@
padding: 10px 0;
}
}

#view-additional-image-generation-settings {
margin: 10px 3px 15px 0;
display: inline-block;

&:checked ~ .additional-image-generation-settings.hidden {
display: block;
}
}

#view-additional-image-generation-settings-label {
display: inline-block;
margin: 10px 0 15px;
cursor: pointer;
}

.additional-image-generation-settings {
label {
display: block;
margin-top: 10px;
}

span {
display: inline-block;
min-width: 60px;
}

select {
min-width: 200px;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,19 @@ const GeneratedImagesContainer = wp.media.View.extend( {
initialize: function ( options ) {
this.collection = new Images();
this.prompt = options.prompt;
this.quality = options.quality;
this.size = options.size;
this.style = options.style;

this.listenTo( this.collection, 'reset', this.renderAll );
this.listenTo( this.collection, 'error', this.error );

this.collection.makeRequest( this.prompt );
this.collection.makeRequest(
this.prompt,
this.quality,
this.size,
this.style
);
this.render();
},

Expand Down
16 changes: 15 additions & 1 deletion src/js/features/image-generation/media-modal/views/prompt.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,31 @@ const Prompt = wp.media.View.extend( {
*/
promptRequest: function ( event ) {
let prompt = '';
let quality = '';
let size = '';
let style = '';

if ( event.which === 13 ) {
prompt = event.target.value.trim();
} else if ( event.target.nodeName === 'BUTTON' ) {
prompt = event.target.parentElement
.querySelector( '.prompt' )
.value.trim();
quality = event.target.parentElement
.querySelector( '.quality' )
.value.trim();

size = event.target.parentElement
.querySelector( '.size' )
.value.trim();

style = event.target.parentElement
.querySelector( '.style' )
.value.trim();
}

if ( prompt ) {
new GeneratedImagesContainer( { prompt } );
new GeneratedImagesContainer( { prompt, quality, size, style } );
}
},
} );
Expand Down
16 changes: 16 additions & 0 deletions src/js/settings/components/provider-settings/openai-dalle.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import {
__experimentalInputControl as InputControl, // eslint-disable-line @wordpress/no-unsafe-wp-apis
SelectControl,
ToggleControl,
} from '@wordpress/components';
import { __ } from '@wordpress/i18n';

Expand Down Expand Up @@ -157,6 +158,21 @@ export const OpenAIDallESettings = ( { isConfigured = false } ) => {
__nextHasNoMarginBottom
/>
</SettingsRow>
<SettingsRow
label={ __( 'Enable per-image settings', 'classifai' ) }
description={ __(
'Enable this to allow users to select the quality, size, and style of the generated image.',
'classifai'
) }
>
<ToggleControl
id={ `${ providerName }_per_image_settings` }
onChange={ ( value ) =>
onChange( { per_image_settings: value } )
}
checked={ providerSettings.per_image_settings || false }
/>
</SettingsRow>
</>
);
};
Loading