NAME
Langertha::Content::Image - Canonical image content block with cross-provider conversion (OpenAI / Anthropic / Gemini)
VERSION
version 0.500
SYNOPSIS
use Langertha::Content::Image;
# From a remote URL
my $img = Langertha::Content::Image->from_url('https://example.com/cat.jpg');
# From a local file (media_type sniffed from extension)
my $img = Langertha::Content::Image->from_file('/tmp/cat.png');
# From raw bytes
my $img = Langertha::Content::Image->from_data($bytes, media_type => 'image/jpeg');
# From an existing base64 string
my $img = Langertha::Content::Image->from_base64($b64, media_type => 'image/png');
# Embed in a chat message — Langertha::Role::Chat converts per engine
my $response = $engine->simple_chat_f({
role => 'user',
content => [ 'What is in this image?', $img ],
});
DESCRIPTION
Provider-neutral image block. Carries either a remote URL, a base64 payload, or both, plus an IANA media_type. Serializes to the three dominant vision-chat wire formats:
OpenAI chat completions —
{ type ='image_url', image_url => { url => ... } }>Anthropic messages —
{ type ='image', source => { type => 'url' | 'base64', ... } }>Google Gemini —
{ inline_data ={ mime_type => ..., data => <base64> } }>
Gemini requires base64, so to_gemini will transparently download a remote URL on first call (cached on the object).
url
Remote HTTP(S) URL of the image. May be passed through directly (OpenAI, Anthropic) or auto-downloaded and base64-encoded (Gemini).
base64
The base64-encoded image payload (no data: URL prefix). Can be supplied at construction, or populated lazily when a provider that requires inline data (Gemini) is targeted.
media_type
IANA media type (image/jpeg, image/png, image/gif, image/webp). Required for base64 payloads on Anthropic and Gemini. Sniffed from the file extension by from_file and from the URL path by from_url.
from_url
my $img = Langertha::Content::Image->from_url($url);
my $img = Langertha::Content::Image->from_url($url, media_type => 'image/jpeg');
Builds an image block referencing a remote URL. Media type is sniffed from the URL extension when not provided.
from_file
my $img = Langertha::Content::Image->from_file('/tmp/cat.png');
Reads a local file, base64-encodes it, and sniffs the media type from the extension (unless media_type is passed).
from_data
my $img = Langertha::Content::Image->from_data($bytes, media_type => 'image/jpeg');
Builds an image block from raw bytes. media_type is required.
from_base64
my $img = Langertha::Content::Image->from_base64($b64, media_type => 'image/png');
Builds an image block from an existing base64 string.
ensure_base64
my $b64 = $img->ensure_base64;
Returns the base64 payload, fetching the URL over HTTP if necessary. Populates media_type from the response Content-Type header when the image was URL-only. Caches the result on the object.
to_openai
my $block = $img->to_openai;
# { type => 'image_url', image_url => { url => ... } }
Serializes to the OpenAI chat-completions image block. Uses the URL when available, otherwise emits a data: URL from the base64 payload.
to_anthropic
my $block = $img->to_anthropic;
# { type => 'image', source => { type => 'url', url => ... } }
# or
# { type => 'image', source => { type => 'base64', media_type => ..., data => ... } }
Serializes to the Anthropic messages image block. Prefers a URL source when available; otherwise emits an inline base64 source (media_type required).
to_gemini
my $block = $img->to_gemini;
# { inline_data => { mime_type => ..., data => <base64> } }
Serializes to the Gemini inlineData part. Auto-downloads URL-only images because Gemini has no URL-fetching equivalent.
SEE ALSO
Langertha::Content - Base role this class implements
Langertha::Role::Chat - Normalizes content blocks per engine during
chat_messagesLangertha::ToolChoice - Sibling value object for tool_choice normalization
SUPPORT
Issues
Please report bugs and feature requests on GitHub at https://github.com/Getty/langertha/issues.
IRC
Join #langertha on irc.perl.org or message Getty directly.
CONTRIBUTING
Contributions are welcome! Please fork the repository and submit a pull request.
AUTHOR
Torsten Raudssus <getty@cpan.org>
COPYRIGHT AND LICENSE
This software is copyright (c) 2026 by Torsten Raudssus https://raudssus.de/.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.