Skip to content

Commit

Permalink
Finish up all functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
cynthiajoan committed Jan 24, 2025
1 parent 8eefb6e commit 8922f9b
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 90 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,15 @@ class _ImagenPageState extends State<ImagenPage> {
@override
void initState() {
super.initState();
var generationConfig = ImagenGenerationConfig(
negativePrompt: 'frog',
numberOfImages: 1,
aspectRatio: ImagenAspectRatio.square1x1,
imageFormat: ImagenFormat.jpeg(compressionQuality: 75),
);
_imagenModel = FirebaseVertexAI.instance.imageModel(
modelName: 'imagen-3.0-generate-001',
generationConfig: ImagenGenerationConfig(
imageFormat: ImagenFormat.jpeg(compressionQuality: 75),
),
generationConfig: generationConfig,
safetySettings: ImagenSafetySettings(
ImagenSafetyFilterLevel.blockLowAndAbove,
ImagenPersonFilterLevel.allowAdult,
Expand Down Expand Up @@ -133,15 +137,7 @@ class _ImagenPageState extends State<ImagenPage> {
_loading = true;
});

var generationConfig = ImagenGenerationConfig(
negativePrompt: 'frog',
numberOfImages: 1,
aspectRatio: ImagenAspectRatio.square1x1);

var response = await _imagenModel.generateImages(
prompt,
generationConfig: generationConfig,
);
var response = await _imagenModel.generateImages(prompt);

if (response.images.isNotEmpty) {
var imagenImage = response.images[0];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,14 @@ abstract class BaseModel {
required FirebaseApp app,
required ApiClient client,
}) : _model = normalizeModelName(model),
_app = app,
_location = location,
_projectUri = _vertexUri(app, location),
_client = client;

static const _baseUrl = 'firebasevertexai.googleapis.com';
static const _apiVersion = 'v1beta';

final ({String prefix, String name}) _model;
final FirebaseApp _app;
final String _location;

final Uri _projectUri;
final ApiClient _client;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,10 @@ class FirebaseVertexAI extends FirebasePluginPlatform {
);
}

/// Create a [ImagenModel].
///
/// The optional [safetySettings] can be used to control and guide the
/// generation. See [ImagenSafetySettings] for details.
ImagenModel imageModel(
{required String modelName,
ImagenGenerationConfig? generationConfig,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,21 @@
// See the License for the specific language governing permissions and
// limitations under the License.

///
/// Specifies the level of safety filtering for image generation.
/// If not specified, default will be "block_medium_and_above".
enum ImagenSafetyFilterLevel {
///
/// Strongest filtering level, most strict blocking.
blockLowAndAbove('block_low_and_above'),

///
/// Block some problematic prompts and responses.
blockMediumAndAbove('block_medium_and_above'),

///
/// Reduces the number of requests blocked due to safety filters.
/// May increase objectionable content generated by Imagen.
blockOnlyHigh('block_only_high'),

///
/// Block very few problematic prompts and responses.
/// Access to this feature is restricted.
blockNone('block_none');

const ImagenSafetyFilterLevel(this._jsonString);
Expand All @@ -49,15 +52,16 @@ enum ImagenSafetyFilterLevel {
String toString() => name;
}

///
/// Allow generation of people by the model.
/// If not specified, the default value is "allow_adult".
enum ImagenPersonFilterLevel {
///
/// Disallow the inclusion of people or faces in images.
blockAll('dont_allow'),

///
/// Allow generation of adults only.
allowAdult('allow_adult'),

///
/// Allow generation of people of all ages.
allowAll('allow_all');

const ImagenPersonFilterLevel(this._jsonString);
Expand All @@ -82,15 +86,17 @@ enum ImagenPersonFilterLevel {
String toString() => name;
}

/// A class representing safety settings for image generation.
///
/// It includes a safety filter level and a person filter level.
final class ImagenSafetySettings {
/// Constructor
ImagenSafetySettings(this.safetyFilterLevel, this.personFilterLevel);

///
/// The safety filter level
final ImagenSafetyFilterLevel? safetyFilterLevel;

///
/// The person filter level
final ImagenPersonFilterLevel? personFilterLevel;

/// Convert to json format.
Expand All @@ -102,21 +108,21 @@ final class ImagenSafetySettings {
};
}

///
/// The aspect ratio for the image. The default value is "1:1".
enum ImagenAspectRatio {
///
/// Square (1:1).
square1x1('1:1'),

///
/// Portrait (9:16).
portrait9x16('9:16'),

///
/// Landscape (16:9).
landscape16x9('16:9'),

///
/// Portrait (3:4).
portrait3x4('3:4'),

///
/// Landscape (4:3).
landscape4x3('4:3');

const ImagenAspectRatio(this._jsonString);
Expand All @@ -143,17 +149,31 @@ enum ImagenAspectRatio {
String toString() => name;
}

/// Configuration options for image generation.
final class ImagenGenerationConfig {
/// Constructor
ImagenGenerationConfig(
{this.negativePrompt,
this.numberOfImages,
{this.numberOfImages,
this.negativePrompt,
this.aspectRatio,
this.imageFormat,
this.addWatermark});
final String? negativePrompt;

/// The number of images to generate. Default is 1.
final int? numberOfImages;

/// A description of what to discourage in the generated images.
final String? negativePrompt;

/// The aspect ratio for the image. The default value is "1:1".
final ImagenAspectRatio? aspectRatio;

/// The image format of the generated images.
final ImagenFormat? imageFormat;

/// Add an invisible watermark to the generated images.
/// Default value for each imagen model can be found in
/// https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/imagen-api#generate_images
final bool? addWatermark;

/// Convert to json format.
Expand All @@ -166,15 +186,26 @@ final class ImagenGenerationConfig {
};
}

/// Represents the image format and compression quality.
final class ImagenFormat {
/// Constructor
ImagenFormat(this.mimeType, this.compressionQuality);

ImagenFormat.png() : this("image/png", null);
/// Constructor for png
ImagenFormat.png() : this('image/png', null);

/// Constructor for jpeg
ImagenFormat.jpeg({int? compressionQuality})
: this("image/jpeg", compressionQuality);
: this('image/jpeg', compressionQuality);

/// The MIME type of the image format. The default value is "image/png".
final String mimeType;

/// The level of compression if the output type is "image/jpeg".
/// Accepted values are 0 through 100. The default value is 75.
final int? compressionQuality;

/// Convert to json format.
Map<String, dynamic> toJson() => {
'mimeType': mimeType,
if (compressionQuality != null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,62 +15,69 @@ import 'dart:convert';
import 'dart:typed_data';
import 'error.dart';

///
/// Base type of Imagen Image.
sealed class ImagenImage {
/// Constructor
ImagenImage({required this.mimeType});

/// The MIME type of the image format.
final String mimeType;

/// Convert the [ImagenImage] content to json format.
Object toJson();

ImagenImage({required this.mimeType});
}

/// Represents an image stored as a base64-encoded string.
final class ImagenInlineImage implements ImagenImage {
/// Data contents in bytes.
final Uint8List bytesBase64Encoded;

@override
final String mimeType;

/// Constructor
ImagenInlineImage({
required this.bytesBase64Encoded,
required this.mimeType,
});

/// The data contents in bytes, encoded as base64.
final Uint8List bytesBase64Encoded;

@override
final String mimeType;

@override
Object toJson() => {
'mimeType': mimeType,
'bytesBase64Encoded': bytesBase64Encoded,
};
}

/// Represents an image stored in Google Cloud Storage.
final class ImagenGCSImage implements ImagenImage {
@override
final String mimeType;

final String gcsUri;

/// Constructor
ImagenGCSImage({
required this.gcsUri,
required this.mimeType,
});

/// The storage URI of the image.
final String gcsUri;

@override
final String mimeType;

@override
Object toJson() => {
'mimeType': mimeType,
'gcsUri': gcsUri,
};
}

/// Represents the response from an image generation request.
final class ImagenGenerationResponse<T extends ImagenImage> {
/// Constructor
ImagenGenerationResponse({
required this.images,
this.filteredReason,
});

final List<T> images;
final String? filteredReason;

/// Factory method to create an ImagenGenerationResponse from a JSON object.
factory ImagenGenerationResponse.fromJson(Map<String, dynamic> json) {
final filteredReason = json['filteredReason'] as String?;
final imagesJson = json['predictions'] as List<dynamic>;
Expand Down Expand Up @@ -102,6 +109,12 @@ final class ImagenGenerationResponse<T extends ImagenImage> {
throw ArgumentError('Unsupported ImagenImage type: $T');
}
}

/// A list of generated images. The type of the images depends on the T parameter.
final List<T> images;

/// If the generation was filtered due to safety reasons, a message explaining the reason.
final String? filteredReason;
}

/// Parse the json to [ImagenGenerationResponse]
Expand Down
Loading

0 comments on commit 8922f9b

Please sign in to comment.