Skip to content

Commit 74e64dd

Browse files
committed
Generating image guide
1 parent 19ebb02 commit 74e64dd

File tree

4 files changed

+128
-0
lines changed

4 files changed

+128
-0
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package io.quarkiverse.langchain4j.samples.images;
2+
3+
import java.io.IOException;
4+
import java.net.URI;
5+
6+
import jakarta.inject.Inject;
7+
import jakarta.ws.rs.GET;
8+
import jakarta.ws.rs.Path;
9+
import jakarta.ws.rs.Produces;
10+
11+
@Path("/endpoint")
12+
public class EndpointGeneration {
13+
14+
@Inject
15+
ImageGenerationAiService imageGenerationAiService;
16+
17+
@GET
18+
@Path("/generate-image")
19+
@Produces("image/png")
20+
public byte[] generateImage() {
21+
var image = imageGenerationAiService.generateImage("a rabbit in a space suit");
22+
return readBytes(image.url());
23+
}
24+
25+
private byte[] readBytes(URI url) {
26+
try (var is = url.toURL().openStream()) {
27+
return is.readAllBytes();
28+
} catch (IOException e) {
29+
throw new RuntimeException("Failed to read image from URL: " + url, e);
30+
}
31+
}
32+
33+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// tag::head[]
2+
package io.quarkiverse.langchain4j.samples.images;
3+
4+
import dev.langchain4j.data.image.Image;
5+
import dev.langchain4j.service.SystemMessage;
6+
import dev.langchain4j.service.UserMessage;
7+
import io.quarkiverse.langchain4j.RegisterAiService;
8+
9+
@RegisterAiService
10+
@SystemMessage("You are an AI that generates images from text prompts.")
11+
public interface ImageGenerationAiService {
12+
// end::head[]
13+
14+
// tag::generation[]
15+
@UserMessage("Generate an image of a {subject}.")
16+
Image generateImage(String subject);
17+
// end::generation[]
18+
19+
// tag::head[]
20+
}
21+
// end::head[]

docs/modules/ROOT/nav.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
* xref:guide-csv.adoc[Index CSVs in a RAG pipeline]
1919
* xref:guide-web-search.adoc[Using Tavily Web Search]
2020
* xref:guide-passing-image.adoc[Passing Images to Models]
21+
* xref:guide-generating-image.adoc[Generating Images]
2122
// * xref:guide-agentic-patterns.adoc[Implementing Agentic patterns]
2223
// * xref:guide-structured-output.adoc[Returning structured data from a model]
2324
// * xref:guide-streamed-responses.adoc[Using function calling]
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
= Generating Images
2+
3+
include::./includes/attributes.adoc[]
4+
include::./includes/customization.adoc[]
5+
6+
Text completions are powerful, but many modern AI use cases also demand image generation.
7+
With Quarkus LangChain4j’s Image model support, you can declare a service method that returns a `dev.langchain4j.data.image.Image` instance, letting your microservice request, receive, and expose AI‐generated visuals seamlessly.
8+
9+
== Prerequisites
10+
11+
* A Quarkus project with the `quarkus-langchain4j-openai` extension on the classpath (or another model provider that supports image models)
12+
* OpenAI (or another provider) API Key configured in `application.properties` or via `QUARKUS_LANGCHAIN4J_OPENAI_API_KEY`
13+
* An **Image Model** enabled (e.g. `dall-e-3` or `GPT-Image-1`) in your config:
14+
15+
[source,properties]
16+
----
17+
quarkus.langchain4j.openai.api-key=${OPENAI_API_KEY}
18+
quarkus.langchain4j.openai.image-model.model-name=dall-e-3 # This is the default model, but you can specify another one if needed
19+
----
20+
21+
* Extended timeout for image generation, which can take longer than text completions. For example:
22+
23+
[source,properties]
24+
----
25+
quarkus.langchain4j.openai.timeout=60s
26+
----
27+
28+
== Step 1. Define the AI service
29+
30+
Declare an AI Service interface to encapsulate image generation calls:
31+
32+
[source,java]
33+
----
34+
include::{examples-dir}/io/quarkiverse/langchain4j/samples/images/ImageGenerationAiService.java[tags=head]
35+
----
36+
37+
Here, `@RegisterAiService` creates the xref:ai-services.adoc[AI Service], and `@SystemMessage` supplies the global instruction for all methods in the service.
38+
39+
== Step 2. Define the Generation Method
40+
41+
Add a method annotated with `@UserMessage` that returns Image.
42+
Quarkus LangChain4j will call the configured image model and wrap the response in an `Image` object.
43+
44+
[source,java]
45+
----
46+
include::{examples-dir}/io/quarkiverse/langchain4j/samples/images/ImageGenerationAiService.java[tags=head;generation]
47+
----
48+
49+
When invoked, Quarkus will substitute the subject into the prompt, send it to the AI model provider, and return the generated image (URL or Base64).
50+
51+
NOTE: When using OpenAI image model, the returned `Image` object contains a URL to the generated image, which you can use to display or download the image.
52+
53+
54+
== Step 3. Expose an HTTP Endpoint
55+
56+
Finally, expose a REST resource that injects and calls your AI Service:
57+
58+
Use the `Image` data type for local or in-memory images:
59+
60+
[source,java]
61+
----
62+
include::{examples-dir}/io/quarkiverse/langchain4j/samples/images/EndpointGeneration.java[]
63+
----
64+
65+
== Conclusion
66+
67+
You’ve now seen how to:
68+
1. Register an image‐generation AI service (`@RegisterAiService`).
69+
2. Declare a method returning `Image` with `@UserMessage`.
70+
3. Expose a REST endpoint that returns the generated image back to clients.
71+
72+
With this pattern, you can build rich, AI‐driven visual applications—everything from dynamic marketing graphics to in‐app illustration.
73+

0 commit comments

Comments
 (0)