# Transformations

Learn how to resize, rotate, crop, flip, and transform images in BoxLang.

## Table of Contents

* [Resizing Images](#resizing-images)
* [Scaling Images](#scaling-images)
* [Rotating Images](#rotating-images)
* [Cropping Images](#cropping-images)
* [Flipping & Transposing](#flipping--transposing)
* [Shearing](#shearing)
* [Translation](#translation)
* [Drawing Axis Transformations](#drawing-axis-transformations)

## Resizing Images

### Resize to Exact Dimensions

```js
// Resize to exact width and height
ImageNew("photo.jpg")
    .resize(800, 600)
    .write("resized.jpg");

// With interpolation method
ImageNew("photo.jpg")
    .resize(800, 600, "bicubic", 0)
    .write("resized-hq.jpg");
```

**Interpolation Options:**

* `nearest` - Fastest, lowest quality
* `bilinear` - Good balance of speed and quality (default)
* `bicubic` - Highest quality, slower

**BIF Syntax:**

```js
img = ImageRead("photo.jpg");
ImageResize(img, 800, 600);
ImageResize(img, 800, 600, "bicubic");  // High quality
ImageWrite(img, "resized.jpg");
```

## Scaling Images

### Scale to Fit (Proportional)

Scales the image to fit within specified dimensions while maintaining aspect ratio:

```js
// Scale to fit within 800x600 (maintains aspect ratio)
ImageNew("photo.jpg")
    .scaleToFit(800, 600)
    .write("scaled.jpg");

// With interpolation
ImageNew("photo.jpg")
    .scaleToFit(800, 600, "bicubic")
    .write("scaled-hq.jpg");
```

**BIF Syntax:**

```js
img = ImageRead("photo.jpg");
ImageScaleToFit(img, 800, 600);
ImageScaleToFit(img, 800, 600, "bicubic", 0);  // High quality
ImageWrite(img, "scaled.jpg");
```

### Resize vs ScaleToFit

```js
// Resize: Forces exact dimensions (may distort)
ImageNew("photo.jpg")
    .resize(800, 600)     // Exactly 800x600
    .write("resized.jpg");

// ScaleToFit: Maintains aspect ratio (may be smaller)
ImageNew("photo.jpg")
    .scaleToFit(800, 600) // Max 800x600, keeps proportions
    .write("scaled.jpg");
```

**Example:**

If your image is 1600x900 (16:9 aspect ratio):

* `resize(800, 600)` → 800x600 (distorted to 4:3)
* `scaleToFit(800, 600)` → 800x450 (maintains 16:9)

## Rotating Images

### Rotate by Angle

```js
// Rotate 90 degrees clockwise
ImageNew("photo.jpg")
    .rotate(90)
    .write("rotated-90.jpg");

// Rotate 45 degrees
ImageNew("photo.jpg")
    .rotate(45)
    .write("rotated-45.jpg");

// Rotate counter-clockwise (negative angle)
ImageNew("photo.jpg")
    .rotate(-90)
    .write("rotated-ccw.jpg");
```

**BIF Syntax:**

```js
img = ImageRead("photo.jpg");
ImageRotate(img, 90);
ImageWrite(img, "rotated.jpg");
```

**Notes:**

* Positive angles rotate clockwise
* Negative angles rotate counter-clockwise
* Canvas size expands to accommodate rotated image
* Empty areas filled with background color

### Rotate with Interpolation

```js
// High-quality rotation
ImageNew("photo.jpg")
    .rotate(45, "bicubic")
    .write("rotated-hq.jpg");
```

## Cropping Images

### Basic Cropping

```js
// Crop: x, y, width, height
ImageNew("photo.jpg")
    .crop(100, 100, 400, 300)
    .write("cropped.jpg");
```

**BIF Syntax:**

```js
img = ImageRead("photo.jpg");
ImageCrop(img, x=100, y=100, width=400, height=300);
ImageWrite(img, "cropped.jpg");
```

### Center Crop to Square

```js
// Crop image to square from center
img = ImageNew("photo.jpg");
width = img.getWidth();
height = img.getHeight();

// Calculate square crop from center
cropSize = min(width, height);
x = (width - cropSize) / 2;
y = (height - cropSize) / 2;

img.crop(x, y, cropSize, cropSize)
   .write("square.jpg");
```

### Creating Thumbnails with Cropping

```js
// Create 200x200 thumbnail with center crop
img = ImageNew("large-photo.jpg");
width = img.getWidth();
height = img.getHeight();

// Determine crop dimensions
cropSize = min(width, height);
x = (width - cropSize) / 2;
y = (height - cropSize) / 2;

img.crop(x, y, cropSize, cropSize)
   .resize(200, 200)
   .write("thumbnail.jpg");
```

## Flipping & Transposing

### Flip Horizontally

```js
// Mirror image left-to-right
ImageNew("photo.jpg")
    .flip("horizontal")
    .write("flipped-h.jpg");
```

### Flip Vertically

```js
// Mirror image top-to-bottom
ImageNew("photo.jpg")
    .flip("vertical")
    .write("flipped-v.jpg");
```

### Transpose Operations

The `flip()` function supports various transpose operations:

```js
// Horizontal flip
ImageFlip(img, "horizontal");

// Vertical flip
ImageFlip(img, "vertical");

// Rotate 90 degrees
ImageFlip(img, "90");

// Rotate 180 degrees
ImageFlip(img, "180");

// Rotate 270 degrees
ImageFlip(img, "270");

// Diagonal transpose
ImageFlip(img, "diagonal");

// Anti-diagonal transpose
ImageFlip(img, "antidiagonal");
```

**Member Function:**

```js
ImageNew("photo.jpg")
    .flip("horizontal")
    .write("mirrored.jpg");
```

## Shearing

Shearing skews the image along an axis:

### Shear Horizontally

```js
// Shear along width (horizontal skew)
ImageNew("photo.jpg")
    .shear(0.5, "width")
    .write("sheared-h.jpg");
```

### Shear Vertically

```js
// Shear along height (vertical skew)
ImageNew("photo.jpg")
    .shear(0.5, "height")
    .write("sheared-v.jpg");
```

**BIF Syntax:**

```js
img = ImageRead("photo.jpg");
ImageShear(img, shear=0.5, direction="width");
ImageWrite(img, "sheared.jpg");
```

**Shear Amount:**

* Positive values shear in one direction
* Negative values shear in opposite direction
* Typical range: -1.0 to 1.0

## Translation

Translation moves the image within its canvas:

```js
// Translate (move) image: x-offset, y-offset
ImageNew("photo.jpg")
    .translate(50, 100)
    .write("translated.jpg");
```

**BIF Syntax:**

```js
img = ImageRead("photo.jpg");
ImageTranslate(img, x=50, y=100);
ImageWrite(img, "translated.jpg");
```

**Use Cases:**

* Adjusting image position
* Creating padding/margins
* Aligning images for compositing

## Drawing Axis Transformations

These transformations affect the coordinate system for subsequent **drawing** operations, not the image itself.

### Translate Drawing Axis

Moves the origin point for drawing operations:

```js
img = ImageNew(400, 300, "rgb", "white");

// Move origin to center
img.translateDrawingAxis(200, 150);

// Now (0,0) is at image center
img.setDrawingColor("red");
img.drawRect(0, 0, 50, 50, true);  // Draws at center

img.write("translated-axis.jpg");
```

**BIF Syntax:**

```js
ImageTranslateDrawingAxis(img, x=200, y=150);
```

### Rotate Drawing Axis

Rotates the coordinate system for drawing:

```js
img = ImageNew(400, 300, "rgb", "white");

// Rotate drawing axis 45 degrees
img.rotateDrawingAxis(45);

// Subsequent drawing operations are rotated
img.setDrawingColor("blue");
img.drawRect(100, 100, 100, 50, true);

img.write("rotated-axis.jpg");
```

**BIF Syntax:**

```js
ImageRotateDrawingAxis(img, angle=45);
```

### Shear Drawing Axis

Shears the coordinate system for drawing:

```js
img = ImageNew(400, 300, "rgb", "white");

// Shear drawing axis
img.shearDrawingAxis(0.3, 0.1);

// Drawing operations will be sheared
img.setDrawingColor("green");
img.drawRect(50, 50, 100, 100, false);

img.write("sheared-axis.jpg");
```

**BIF Syntax:**

```js
ImageShearDrawingAxis(img, shearX=0.3, shearY=0.1);
```

### Why Use Drawing Axis Transformations?

Drawing axis transformations are useful for:

1. **Creating rotated text/graphics** without rotating the entire image
2. **Perspective effects** using shearing
3. **Complex compositions** with transformed coordinate systems
4. **Efficient drawing** - transform once, draw many times

## Complete Transformation Examples

### Create Multiple Sizes

```js
// Generate multiple image sizes from one source
original = ImageNew("photo.jpg");

// Thumbnail
original.copy().scaleToFit(200, 200).write("thumb.jpg");

// Medium
original.copy().scaleToFit(800, 600).write("medium.jpg");

// Large
original.copy().scaleToFit(1920, 1080).write("large.jpg");
```

### Rotate and Crop

```js
// Rotate then crop to remove empty corners
ImageNew("photo.jpg")
    .rotate(15)
    .crop(100, 100, 600, 400)
    .write("rotated-cropped.jpg");
```

### Scale, Crop, and Sharpen

```js
// Professional thumbnail generation
ImageNew("raw-photo.jpg")
    .scaleToFit(400, 400)
    .crop(0, 0, 300, 300)
    .sharpen(1.5)
    .write("thumbnail.jpg");
```

### Flip and Transform

```js
// Create mirror effect
ImageNew("photo.jpg")
    .flip("horizontal")
    .translate(20, 0)
    .write("mirrored.jpg");
```

## Performance Tips

1. **Resize before other operations** - Smaller images process faster
2. **Choose interpolation wisely:**
   * Use `nearest` for pixel art or when speed is critical
   * Use `bilinear` for good balance (default)
   * Use `bicubic` only when quality is paramount
3. **Batch transformations** - Apply multiple operations before saving
4. **Use scaleToFit()** instead of manual ratio calculations

## Next Steps

* [**Filters & Effects**](/boxlang-framework/modularity/image-manipulation/filters-effects.md) - Apply blur, sharpen, and color effects
* [**Drawing**](/boxlang-framework/modularity/image-manipulation/drawing.md) - Add shapes, lines, and text
* [**Advanced Examples**](/boxlang-framework/modularity/image-manipulation/advanced-examples.md) - Real-world transformation pipelines


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://boxlang.ortusbooks.com/boxlang-framework/modularity/image-manipulation/transformations.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
