> ## Documentation Index
> Fetch the complete documentation index at: https://cloudinary.com/documentation/llms.txt
> Use this file to discover all available pages before exploring further.

# Transformation basics (video tutorial)

## Overview

Watch this tutorial to learn the basics of transforming media on the fly.  See how to change the dimensions of images and videos, and apply effects simply by changing the URL.

## Video tutorial

  This video is brought to you by Cloudinary's video player - embed your own!Use the controls to set the playback speed, navigate to chapters of interest and select subtitles in your preferred language.

## Tutorial contents
This tutorial presents the following topics. Click a timestamp to jump to that part of the video.
### Transform assets on the fly
{table:class=tutorial-bullets}|  | 
| --- | --- |
|{videotime:id=media :min=0 :sec=14 :player=cld} |When you upload your images and videos to Cloudinary, you can access them using a URL. You can apply a transformation to your assets on the fly by adding a set of [transformation parameters](transformation_reference) into the [URL](image_transformations#transforming_media_assets_using_dynamic_urls). A transformation can change many things about the asset, including its color, brightness, angle and border, plus, amongst others, duration speed and volume for videos. Transformations are also used for optimization, reducing size, changing formats and applying compression.|

### Apply transformations to an image
{table:class=tutorial-bullets}|  | 
| --- | --- |
|{videotime:id=media :min=0 :sec=55 :player=cld} | To resize an image on the fly you can use the `ar_` parameter to change the aspect ratio (`ar_2:3`) and the `w_` parameter to change the width (`w_500`). To avoid squashing the image, use the `c_fill` parameter. Use automatic gravity (`g_auto`) to let Cloudinary AI decide what to focus on, rather than the center of the image.  Here's the whole transformation: `ar_2:3,c_fill,g_auto,w_500`.|

### Chaining transformations
{table:class=tutorial-bullets}|  | 
| --- | --- |
|{videotime:id=media :min=1 :sec=39 :player=cld} | You can chain transformations together in separate components, separated by a forward slash. For example, use the generative remove effect to remove the dog's tail by adding the `e_gen_remove` parameter (`e_gen_remove:prompt_tail\ar_2:3,c_fill,g_auto,w_500`). Each chained component applies its action to the result of the previous one.|

![Chained transformation](https://res.cloudinary.com/demo/image/upload/e_gen_remove:prompt_tail/ar_2:3,c_fill,g_auto,w_500/e_grayscale/bo_15px_solid_brown,r_30/b_black/co_brown,l_text:great%20vibes_52:Wish%20you%20were%20here.../fl_layer_apply,g_north,y_60/a_-5/docs/family-beach.png "thumb: c_scale,w_200")

```nodejs
cloudinary.image("docs/family-beach.png", {transformation: [
  {effect: "gen_remove:prompt_tail"},
  {aspect_ratio: "2:3", gravity: "auto", width: 500, crop: "fill"},
  {effect: "grayscale"},
  {border: "15px_solid_brown", radius: 30},
  {background: "black"},
  {color: "brown", overlay: {font_family: "vibes", font_size: 52, text: "Wish%20you%20were%20here..."}},
  {flags: "layer_apply", gravity: "north", y: 60},
  {angle: -5}
  ]})
```

```react
new CloudinaryImage("docs/family-beach.png")
  .effect(generativeRemove().prompt("tail"))
  .resize(
    fill()
      .width(500)
      .aspectRatio("2:3")
      .gravity(autoGravity())
  )
  .effect(grayscale())
  .border(solid(15, "brown").roundCorners(byRadius(30)))
  .backgroundColor("black")
  .overlay(
    source(
      text("Wish you were here...", new TextStyle("great vibes", 52)).textColor(
        "brown"
      )
    ).position(
      new Position()
        .gravity(compass("north"))
        .offsetY(60)
    )
  )
  .rotate(byAngle(-5));
```

```vue
new CloudinaryImage("docs/family-beach.png")
  .effect(generativeRemove().prompt("tail"))
  .resize(
    fill()
      .width(500)
      .aspectRatio("2:3")
      .gravity(autoGravity())
  )
  .effect(grayscale())
  .border(solid(15, "brown").roundCorners(byRadius(30)))
  .backgroundColor("black")
  .overlay(
    source(
      text("Wish you were here...", new TextStyle("great vibes", 52)).textColor(
        "brown"
      )
    ).position(
      new Position()
        .gravity(compass("north"))
        .offsetY(60)
    )
  )
  .rotate(byAngle(-5));
```

```angular
new CloudinaryImage("docs/family-beach.png")
  .effect(generativeRemove().prompt("tail"))
  .resize(
    fill()
      .width(500)
      .aspectRatio("2:3")
      .gravity(autoGravity())
  )
  .effect(grayscale())
  .border(solid(15, "brown").roundCorners(byRadius(30)))
  .backgroundColor("black")
  .overlay(
    source(
      text("Wish you were here...", new TextStyle("great vibes", 52)).textColor(
        "brown"
      )
    ).position(
      new Position()
        .gravity(compass("north"))
        .offsetY(60)
    )
  )
  .rotate(byAngle(-5));
```

```js
new CloudinaryImage("docs/family-beach.png")
  .effect(generativeRemove().prompt("tail"))
  .resize(
    fill()
      .width(500)
      .aspectRatio("2:3")
      .gravity(autoGravity())
  )
  .effect(grayscale())
  .border(solid(15, "brown").roundCorners(byRadius(30)))
  .backgroundColor("black")
  .overlay(
    source(
      text("Wish you were here...", new TextStyle("great vibes", 52)).textColor(
        "brown"
      )
    ).position(
      new Position()
        .gravity(compass("north"))
        .offsetY(60)
    )
  )
  .rotate(byAngle(-5));
```

```python
CloudinaryImage("docs/family-beach.png").image(transformation=[
  {'effect': "gen_remove:prompt_tail"},
  {'aspect_ratio': "2:3", 'gravity': "auto", 'width': 500, 'crop': "fill"},
  {'effect': "grayscale"},
  {'border': "15px_solid_brown", 'radius': 30},
  {'background': "black"},
  {'color': "brown", 'overlay': {'font_family': "vibes", 'font_size': 52, 'text': "Wish%20you%20were%20here..."}},
  {'flags': "layer_apply", 'gravity': "north", 'y': 60},
  {'angle': -5}
  ])
```

```php
(new ImageTag('docs/family-beach.png'))
	->effect(Effect::generativeRemove()->prompt("tail"))
	->resize(Resize::fill()->width(500)
->aspectRatio("2:3")
	->gravity(
	Gravity::autoGravity())
	)
	->effect(Effect::grayscale())
	->border(Border::solid(15,Color::BROWN)
	->roundCorners(
	RoundCorners::byRadius(30))
	)
	->backgroundColor(Color::BLACK)
	->overlay(Overlay::source(
	Source::text("Wish you were here...",(new TextStyle("great vibes",52)))
	->textColor(Color::BROWN)
	)
	->position((new Position())
	->gravity(
	Gravity::compass(
	Compass::north()))
->offsetY(60))
	)
	->rotate(Rotate::byAngle(-5));
```

```java
cloudinary.url().transformation(new Transformation()
  .effect("gen_remove:prompt_tail").chain()
  .aspectRatio("2:3").gravity("auto").width(500).crop("fill").chain()
  .effect("grayscale").chain()
  .border("15px_solid_brown").radius(30).chain()
  .background("black").chain()
  .color("brown").overlay(new TextLayer().fontFamily("vibes").fontSize(52).text("Wish%20you%20were%20here...")).chain()
  .flags("layer_apply").gravity("north").y(60).chain()
  .angle(-5)).imageTag("docs/family-beach.png");
```

```ruby
cl_image_tag("docs/family-beach.png", transformation: [
  {effect: "gen_remove:prompt_tail"},
  {aspect_ratio: "2:3", gravity: "auto", width: 500, crop: "fill"},
  {effect: "grayscale"},
  {border: "15px_solid_brown", radius: 30},
  {background: "black"},
  {color: "brown", overlay: {font_family: "vibes", font_size: 52, text: "Wish%20you%20were%20here..."}},
  {flags: "layer_apply", gravity: "north", y: 60},
  {angle: -5}
  ])
```

```csharp
cloudinary.Api.UrlImgUp.Transform(new Transformation()
  .Effect("gen_remove:prompt_tail").Chain()
  .AspectRatio("2:3").Gravity("auto").Width(500).Crop("fill").Chain()
  .Effect("grayscale").Chain()
  .Border("15px_solid_brown").Radius(30).Chain()
  .Background("black").Chain()
  .Color("brown").Overlay(new TextLayer().FontFamily("vibes").FontSize(52).Text("Wish%20you%20were%20here...")).Chain()
  .Flags("layer_apply").Gravity("north").Y(60).Chain()
  .Angle(-5)).BuildImageTag("docs/family-beach.png")
```

```dart
cloudinary.image('docs/family-beach.png').transformation(Transformation()
	.addTransformation("e_gen_remove:prompt_tail/ar_2:3,c_fill,g_auto,w_500/e_grayscale/bo_15px_solid_brown,r_30/b_black/co_brown,l_text:great vibes_52:Wish you were here.../fl_layer_apply,g_north,y_60/a_-5"));
```

```swift
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation()
  .setEffect("gen_remove:prompt_tail").chain()
  .setAspectRatio("2:3").setGravity("auto").setWidth(500).setCrop("fill").chain()
  .setEffect("grayscale").chain()
  .setBorder("15px_solid_brown").setRadius(30).chain()
  .setBackground("black").chain()
  .setColor("brown").setOverlay("text:great%20vibes_52:Wish%20you%20were%20here...").chain()
  .setFlags("layer_apply").setGravity("north").setY(60).chain()
  .setAngle(-5)).generate("docs/family-beach.png")!, cloudinary: cloudinary)
```

```android
MediaManager.get().url().transformation(new Transformation()
  .effect("gen_remove:prompt_tail").chain()
  .aspectRatio("2:3").gravity("auto").width(500).crop("fill").chain()
  .effect("grayscale").chain()
  .border("15px_solid_brown").radius(30).chain()
  .background("black").chain()
  .color("brown").overlay(new TextLayer().fontFamily("vibes").fontSize(52).text("Wish%20you%20were%20here...")).chain()
  .flags("layer_apply").gravity("north").y(60).chain()
  .angle(-5)).generate("docs/family-beach.png");
```

```flutter
cloudinary.image('docs/family-beach.png').transformation(Transformation()
	.addTransformation("e_gen_remove:prompt_tail/ar_2:3,c_fill,g_auto,w_500/e_grayscale/bo_15px_solid_brown,r_30/b_black/co_brown,l_text:great vibes_52:Wish you were here.../fl_layer_apply,g_north,y_60/a_-5"));
```

```kotlin
cloudinary.image {
	publicId("docs/family-beach.png")
	 effect(Effect.generativeRemove() { prompt("tail") })
	 resize(Resize.fill() { width(500)
 aspectRatio("2:3")
	 gravity(
	Gravity.autoGravity())
	 })
	 effect(Effect.grayscale())
	 border(Border.solid(15,Color.BROWN) {
	 roundCorners(
	RoundCorners.byRadius(30))
	 })
	 backgroundColor(Color.BLACK)
	 overlay(Overlay.source(
	Source.text("Wish you were here...",TextStyle("great vibes",52)) {
	 textColor(Color.BROWN)
	 }) {
	 position(Position() {
	 gravity(
	Gravity.compass(
	Compass.north()))
 offsetY(60) })
	 })
	 rotate(Rotate.byAngle(-5)) 
}.generate()
```

```jquery
$.cloudinary.image("docs/family-beach.png", {transformation: [
  {effect: "gen_remove:prompt_tail"},
  {aspect_ratio: "2:3", gravity: "auto", width: 500, crop: "fill"},
  {effect: "grayscale"},
  {border: "15px_solid_brown", radius: 30},
  {background: "black"},
  {color: "brown", overlay: new cloudinary.TextLayer().fontFamily("vibes").fontSize(52).text("Wish%20you%20were%20here...")},
  {flags: "layer_apply", gravity: "north", y: 60},
  {angle: -5}
  ]})
```

```react_native
new CloudinaryImage("docs/family-beach.png")
  .effect(generativeRemove().prompt("tail"))
  .resize(
    fill()
      .width(500)
      .aspectRatio("2:3")
      .gravity(autoGravity())
  )
  .effect(grayscale())
  .border(solid(15, "brown").roundCorners(byRadius(30)))
  .backgroundColor("black")
  .overlay(
    source(
      text("Wish you were here...", new TextStyle("great vibes", 52)).textColor(
        "brown"
      )
    ).position(
      new Position()
        .gravity(compass("north"))
        .offsetY(60)
    )
  )
  .rotate(byAngle(-5));
```

### Apply transformations to a video
{table:class=tutorial-bullets}|  | 
| --- | --- |
|{videotime:id=media :min=2 :sec=27 :player=cld} | You can apply transformations to videos in the same way. Here's an example of a text overlay. Use the `l_` parameter for the overlay (`l_text:times_80_bold:Beach%20Life`), and the `fl_layer_apply` parameter to specify its position (`fl_layer_apply,g_north,y_25`):|

![Video with text overlay](https://res.cloudinary.com/demo/video/upload/ar_2:3,c_fill,g_auto,w_500/l_text:times_80_bold:Beach%20Life/fl_layer_apply,g_north,y_25/docs/beach-walking.mp4 "thumb: c_scale,w_200")

```nodejs
cloudinary.video("docs/beach-walking", {transformation: [
  {aspect_ratio: "2:3", gravity: "auto", width: 500, crop: "fill"},
  {overlay: {font_family: "times", font_size: 80, font_weight: "bold", text: "Beach%20Life"}},
  {flags: "layer_apply", gravity: "north", y: 25}
  ]})
```

```react
new CloudinaryVideo("docs/beach-walking.mp4")
  .resize(
    fill()
      .width(500)
      .aspectRatio("2:3")
      .gravity(autoGravity())
  )
  .overlay(
    source(
      text("Beach Life", new TextStyle("times", 80).fontWeight("bold"))
    ).position(
      new Position()
        .gravity(compass("north"))
        .offsetY(25)
    )
  );
```

```vue
new CloudinaryVideo("docs/beach-walking.mp4")
  .resize(
    fill()
      .width(500)
      .aspectRatio("2:3")
      .gravity(autoGravity())
  )
  .overlay(
    source(
      text("Beach Life", new TextStyle("times", 80).fontWeight("bold"))
    ).position(
      new Position()
        .gravity(compass("north"))
        .offsetY(25)
    )
  );
```

```angular
new CloudinaryVideo("docs/beach-walking.mp4")
  .resize(
    fill()
      .width(500)
      .aspectRatio("2:3")
      .gravity(autoGravity())
  )
  .overlay(
    source(
      text("Beach Life", new TextStyle("times", 80).fontWeight("bold"))
    ).position(
      new Position()
        .gravity(compass("north"))
        .offsetY(25)
    )
  );
```

```js
new CloudinaryVideo("docs/beach-walking.mp4")
  .resize(
    fill()
      .width(500)
      .aspectRatio("2:3")
      .gravity(autoGravity())
  )
  .overlay(
    source(
      text("Beach Life", new TextStyle("times", 80).fontWeight("bold"))
    ).position(
      new Position()
        .gravity(compass("north"))
        .offsetY(25)
    )
  );
```

```python
CloudinaryVideo("docs/beach-walking").video(transformation=[
  {'aspect_ratio': "2:3", 'gravity': "auto", 'width': 500, 'crop': "fill"},
  {'overlay': {'font_family': "times", 'font_size': 80, 'font_weight': "bold", 'text': "Beach%20Life"}},
  {'flags': "layer_apply", 'gravity': "north", 'y': 25}
  ])
```

```php
(new VideoTag('docs/beach-walking.mp4'))
	->resize(Resize::fill()->width(500)
->aspectRatio("2:3")
	->gravity(
	Gravity::autoGravity())
	)
	->overlay(Overlay::source(
	Source::text("Beach Life",(new TextStyle("times",80))
	->fontWeight(
	FontWeight::bold())
	))
	->position((new Position())
	->gravity(
	Gravity::compass(
	Compass::north()))
->offsetY(25))
	);
```

```java
cloudinary.url().transformation(new Transformation()
  .aspectRatio("2:3").gravity("auto").width(500).crop("fill").chain()
  .overlay(new TextLayer().fontFamily("times").fontSize(80).fontWeight("bold").text("Beach%20Life")).chain()
  .flags("layer_apply").gravity("north").y(25)).videoTag("docs/beach-walking");
```

```ruby
cl_video_tag("docs/beach-walking", transformation: [
  {aspect_ratio: "2:3", gravity: "auto", width: 500, crop: "fill"},
  {overlay: {font_family: "times", font_size: 80, font_weight: "bold", text: "Beach%20Life"}},
  {flags: "layer_apply", gravity: "north", y: 25}
  ])
```

```csharp
cloudinary.Api.UrlVideoUp.Transform(new Transformation()
  .AspectRatio("2:3").Gravity("auto").Width(500).Crop("fill").Chain()
  .Overlay(new TextLayer().FontFamily("times").FontSize(80).FontWeight("bold").Text("Beach%20Life")).Chain()
  .Flags("layer_apply").Gravity("north").Y(25)).BuildVideoTag("docs/beach-walking")
```

```dart
cloudinary.video('docs/beach-walking.mp4').transformation(Transformation()
	.addTransformation("ar_2:3,c_fill,g_auto,w_500/l_text:times_80_bold:Beach Life/fl_layer_apply,g_north,y_25"));
```

```swift
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation()
  .setAspectRatio("2:3").setGravity("auto").setWidth(500).setCrop("fill").chain()
  .setOverlay("text:times_80_bold:Beach%20Life").chain()
  .setFlags("layer_apply").setGravity("north").setY(25)).generate("docs/beach-walking.mp4")
```

```android
MediaManager.get().url().transformation(new Transformation()
  .aspectRatio("2:3").gravity("auto").width(500).crop("fill").chain()
  .overlay(new TextLayer().fontFamily("times").fontSize(80).fontWeight("bold").text("Beach%20Life")).chain()
  .flags("layer_apply").gravity("north").y(25)).resourceType("video").generate("docs/beach-walking.mp4");
```

```flutter
cloudinary.video('docs/beach-walking.mp4').transformation(Transformation()
	.addTransformation("ar_2:3,c_fill,g_auto,w_500/l_text:times_80_bold:Beach Life/fl_layer_apply,g_north,y_25"));
```

```kotlin
cloudinary.video {
	publicId("docs/beach-walking.mp4")
	 resize(Resize.fill() { width(500)
 aspectRatio("2:3")
	 gravity(
	Gravity.autoGravity())
	 })
	 overlay(Overlay.source(
	Source.text("Beach Life",TextStyle("times",80) {
	 fontWeight(
	FontWeight.bold())
	 })) {
	 position(Position() {
	 gravity(
	Gravity.compass(
	Compass.north()))
 offsetY(25) })
	 }) 
}.generate()
```

```jquery
$.cloudinary.video("docs/beach-walking", {transformation: [
  {aspect_ratio: "2:3", gravity: "auto", width: 500, crop: "fill"},
  {overlay: new cloudinary.TextLayer().fontFamily("times").fontSize(80).fontWeight("bold").text("Beach%20Life")},
  {flags: "layer_apply", gravity: "north", y: 25}
  ]})
```

```react_native
new CloudinaryVideo("docs/beach-walking.mp4")
  .resize(
    fill()
      .width(500)
      .aspectRatio("2:3")
      .gravity(autoGravity())
  )
  .overlay(
    source(
      text("Beach Life", new TextStyle("times", 80).fontWeight("bold"))
    ).position(
      new Position()
        .gravity(compass("north"))
        .offsetY(25)
    )
  );
```

### Apply optimization transformations
{table:class=tutorial-bullets}|  | 
| --- | --- |
|{videotime:id=media :min=2 :sec=57 :player=cld} | You can apply transformations to optimize the delivery of assets. Let Cloudinary decide the best format using `f_auto`, and the best amount of compression to reduce the file size without impacting visual quality using `q_auto`.|

### Delivery lifestyle
{table:class=tutorial-bullets}|  | 
| --- | --- |
|{videotime:id=media :min=3 :sec=18 :player=cld} | When you request a transformation, your original asset remains intact, and a new derived version of the asset is created. Each new transformation that you request counts towards your quota, but because derived assets are cached on a CDN, you won’t be charged again for requesting the same URL. Any slight change to the URL, though, is counted as a new transformation, even if the result is the same. 
|
## Keep learning

> **READING**:
>
> * See all transformation parameters in the [Transformation URL API reference](transformation_reference).

> * Take a look at the [image](image_transformations) and [video](video_manipulation_and_delivery) transformation guides.

> * Discover how transformations are [counted](transformation_counts).

#### If you like this, you might also like...

  
  
  
    Named Transformations
    Simplify & standardize complex delivery URLs 
  

  
  
  
    Optimization Tips
    Tips for delivering optimized images 
  

  
  
  
    Enhance and Restore Images
    Use enhance, restore, upscale and improve effects to make your images shine 
  

&nbsp;

&nbsp;Check out the Cloudinary Academy for free self-paced Cloudinary courses on a variety of developer or DAM topics, or register for formal instructor-led courses, either virtual or on-site.
&nbsp;

