cloudinary/transformation-builder-sdk
Installation:
composer require cloudinary/transformation-builder-sdk
Add Cloudinary credentials to .env:
CLOUDINARY_CLOUD_NAME=your_cloud_name
CLOUDINARY_API_KEY=your_api_key
CLOUDINARY_API_SECRET=your_api_secret
Basic Usage:
use Cloudinary\Transformation;
use Cloudinary\Transformation\Resize;
use Cloudinary\Transformation\Format;
$transformation = new Transformation();
$url = $transformation
->resize(Resize::fill()->width(300)->height(200))
->format(Format::auto())
->buildImageTag('sample.jpg');
First Use Case: Dynamically generate responsive image URLs in Blade:
<img src="{{ Cloudinary::resize(Resize::scale()->width(100))->buildImageTag($product->image) }}" alt="Product">
Define reusable transformations in a config file (config/cloudinary.php):
'presets' => [
'thumbnail' => fn($t) => $t->resize(Resize::fill()->width(200)->height(200)),
'social_share' => fn($t) => $t->resize(Resize::crop()->width(1200)->height(630)),
],
Use in controllers:
$transformation = app('cloudinary')->preset('thumbnail');
Create a Blade directive for concise syntax:
// app/Providers/BladeServiceProvider.php
Blade::directive('cloudinary', function ($expression) {
return "<?php echo app('cloudinary')->{$expression}; ?>";
});
Usage:
<img src="@cloudinary(resize(Resize::fill()->width(300)->height(300))->buildImageTag($image))">
Leverage Cloudinary’s video-specific effects (e.g., fetchFormat, overlay):
$transformation = new Transformation();
$url = $transformation
->video()
->fetchFormat(Video::mp4())
->overlay(Video::source('logo.mp4')->gravity(Gravity::southEast)->width(100))
->buildImageTag('video.mp4');
Use generative or background removal:
$transformation = new Transformation();
$url = $transformation
->effect(Effect::backgroundRemoval())
->format(Format::webp())
->buildImageTag('ugc_image.jpg');
Bind the SDK as a singleton in AppServiceProvider:
public function register() {
$this->app->singleton('cloudinary', function () {
return new Transformation();
});
}
Generate transformation URLs via CLI:
// app/Console/Commands/GenerateTransformations.php
public function handle() {
$transformation = app('cloudinary');
$url = $transformation->resize(Resize::scale()->width(800))->buildImageTag('hero.jpg');
$this->info("Generated URL: {$url}");
}
Attach transformations to model attributes:
// User.php
public function getAvatarUrlAttribute() {
return app('cloudinary')
->resize(Resize::circle()->radius(100))
->gravity(Gravity::face())
->buildImageTag($this->avatar);
}
Cache transformation URLs in Laravel’s cache:
$cacheKey = "cloudinary_transform_{$image}_{$width}x{$height}";
$url = Cache::remember($cacheKey, now()->addHours(1), function () use ($image, $width, $height) {
return app('cloudinary')
->resize(Resize::scale()->width($width)->height($height))
->buildImageTag($image);
});
Generate signed URLs for secure delivery:
use Cloudinary\Api\ApiResponse;
use Cloudinary\Configuration\Configuration;
$transformation = new Transformation();
$url = $transformation
->resize(Resize::fill()->width(500))
->buildImageTag('private_image.jpg', [
'type' => 'authenticated',
'expiration' => time() + 3600,
]);
PHP Version Mismatch:
composer.json:
"require": {
"cloudinary/transformation-builder-sdk": "^2.1"
}
Transformation Order:
gravity must precede resize; otherwise, they’re ignored.// Correct: gravity before resize
$transformation->gravity(Gravity::face())->resize(Resize::fill()->width(200));
AI Effect Limitations:
generativeFill) require Cloudinary’s AI add-on and may incur additional costs.Video Transformation Quirks:
blurFaces works only on images).video() method explicitly:
$transformation->video()->effect(Effect::blurFaces());
URL Encoding:
flags) must be URL-encoded manually.Str::of():
$transformation->addParam('flags', Str::of('lossless')->replace(' ', '%20'));
Deprecated Parameters:
crop in favor of resize).Invalid Transformation Strings:
buildUrl() to inspect the raw transformation string:
$url = $transformation->buildUrl('image.jpg');
// Output: https://res.cloudinary.com/demo/image/upload/w_300,h_200/c_fill...
Performance Bottlenecks:
$start = microtime(true);
$url = $transformation->complexChain()->buildUrl('image.jpg');
$time = microtime(true) - $start;
Caching Issues:
php artisan cache:clear
In Cloudinary dashboard: Settings > Transformation Cache > Clear Cache.Custom Effects: Extend the SDK by creating a custom effect class:
use Cloudinary\Transformation\Effect;
class CustomEffect extends Effect {
public function __construct() {
parent::__construct('custom', 'value');
}
}
Usage:
$transformation->effect(new CustomEffect());
Transformation Decorators: Wrap the SDK to add pre/post-processing:
class AnalyticsTransformation {
public function __construct(private Transformation $transformation) {}
public function track($event) {
$this->transformation->addParam('callback', "image.tag={$event}");
return $this->transformation;
}
}
Bind to Laravel’s container:
$this->app->bind(AnalyticsTransformation::class, function ($app) {
return new AnalyticsTransformation($app->make(Transformation::class));
});
Local Testing: Mock Cloudinary responses in tests:
$transformation = Mockery::mock(Transformation::class);
$
How can I help you explore Laravel packages today?