Kotchasan Framework Documentation

Kotchasan Framework Documentation

Image Class - Image Processing

EN 05 Feb 2026 07:40

Image Class - Image Processing

The Image class is a utility for loading, processing, and saving images. It supports multiple formats and includes functionality for cropping, resizing, flipping, and adding watermarks.

Namespace

Kotchasan\Image

Overview

The Image class provides:

  • Load images from files or Base64
  • Crop and resize images
  • Flip images (horizontal and vertical)
  • Add text watermarks
  • Adjust image orientation based on EXIF data
  • Support for JPG, PNG, GIF, WEBP

Static Properties

public static $quality = 75;                           // Image quality (0-100)
public static $backgroundColor = [255, 255, 255];       // Default background color (RGB white)
public static $fontPath = __DIR__.'/fonts/leelawad.ttf'; // Font for Thai text watermarks

API Reference

loadImageResource()

Load an image from a file and create an image resource

public static function loadImageResource($source)

Parameters:

  • $source (string) - Path to the source image file

Returns: Mixed - Image resource (GD library resource)

Throws: \RuntimeException - If the image file is invalid or unsupported

Example:

use Kotchasan\Image;

try {
    $imageResource = Image::loadImageResource('/path/to/image.jpg');

    // Use image resource
    $width = imagesx($imageResource);
    $height = imagesy($imageResource);

    echo "Size: {$width}x{$height}";

    imagedestroy($imageResource);
} catch (\RuntimeException $e) {
    echo "Error: " . $e->getMessage();
}

loadImageFromBase64()

Load an image from a Base64 string

public static function loadImageFromBase64($base64_string, $allowedExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp'])

Parameters:

  • $base64_string (string) - Base64 encoded string of the image
  • $allowedExtensions (array) - List of allowed file extensions

Returns: array|false - Array containing resource, mime, extension or false on failure

Example:

use Kotchasan\Image;

$base64 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...';

$result = Image::loadImageFromBase64($base64);

if ($result) {
    echo "MIME Type: " . $result['mime'];
    echo "Extension: " . $result['extension'];

    // Save as file
    Image::saveImageResource($result['resource'], '/path/to/output.png');

    imagedestroy($result['resource']);
} else {
    echo "Cannot load image from Base64";
}

// Limit to JPG and PNG only
$result = Image::loadImageFromBase64($base64, ['jpg', 'jpeg', 'png']);

processImageResource()

Process an image resource by resizing or cropping based on provided dimensions

public static function processImageResource($o_im, $thumbwidth, $thumbheight = 0, $watermark = '', $fit = false)

Parameters:

  • $o_im (Mixed) - Original image resource
  • $thumbwidth (int) - Desired width
  • $thumbheight (int) - Desired height (0 = maintain aspect ratio)
  • $watermark (string) - Watermark text (optional)
  • $fit (bool) - true = fit image to dimensions, false = crop to fill

Returns: Mixed - Processed image resource

Example:

use Kotchasan\Image;

$sourceImage = Image::loadImageResource('/path/to/photo.jpg');

// Resize maintaining aspect ratio (max width 800px)
$resized = Image::processImageResource($sourceImage, 800);

// Crop to 300x300
$cropped = Image::processImageResource($sourceImage, 300, 300);

// Fit to 400x300 with watermark
$fitted = Image::processImageResource($sourceImage, 400, 300, 'Copyright 2024', true);

// Save
Image::saveImageResource($fitted, '/path/to/output.jpg');

imagedestroy($sourceImage);
imagedestroy($fitted);

saveImageResource()

Save an image resource to a file

public static function saveImageResource($imageResource, $target)

Parameters:

  • $imageResource (Mixed) - The image resource to save
  • $target (string) - Path to the target image file

Returns: bool - Success or failure

Throws: \RuntimeException - If the file extension is unsupported or save fails

Example:

use Kotchasan\Image;

$image = Image::loadImageResource('/path/to/source.jpg');

// Save as JPG
Image::saveImageResource($image, '/path/to/output.jpg');

// Save as PNG
Image::saveImageResource($image, '/path/to/output.png');

// Save as WEBP
Image::saveImageResource($image, '/path/to/output.webp');

imagedestroy($image);

crop()

Crop and resize an image based on specified dimensions

public static function crop($source, $target, $thumbwidth, $thumbheight, $watermark = '', $fit = false)

Parameters:

  • $source (string) - Path to source file
  • $target (string) - Path to save the cropped image
  • $thumbwidth (int) - Desired width
  • $thumbheight (int) - Desired height
  • $watermark (string) - Watermark text (optional)
  • $fit (bool) - true = fit, false = crop

Returns: bool - Success or failure

Example:

use Kotchasan\Image;

// Crop to 200x200 (crop mode)
Image::crop('/path/to/photo.jpg', '/path/to/thumb.jpg', 200, 200);

// Fit to 300x200 with watermark
Image::crop('/path/to/photo.jpg', '/path/to/fitted.jpg', 300, 200, 'My Photo', true);

// Create thumbnail
Image::crop('/uploads/profile.jpg', '/uploads/thumb_profile.jpg', 150, 150);

resize()

Resize an image and save it

public static function resize($source, $target, $name, $width = 0, $watermark = '')

Parameters:

  • $source (string) - Path to source file
  • $target (string) - Target directory
  • $name (string) - Output filename
  • $width (int) - Desired width (0 = use original size)
  • $watermark (string) - Watermark text (optional)

Returns: array|false - Image info array or false on failure

Example:

use Kotchasan\Image;

$result = Image::resize(
    '/uploads/original.jpg',
    '/uploads/',
    'resized.jpg',
    800,
    'Copyright 2024'
);

if ($result) {
    echo "Filename: " . $result['name'];
    echo "Size: {$result['width']}x{$result['height']}";
    echo "MIME: " . $result['mime'];
}

flip()

Flip an image horizontally

public static function flip($imgsrc)

Parameters:

  • $imgsrc (Mixed) - Source image resource

Returns: Mixed - Flipped image resource

Example:

use Kotchasan\Image;

$image = Image::loadImageResource('/path/to/photo.jpg');
$flipped = Image::flip($image);

Image::saveImageResource($flipped, '/path/to/flipped.jpg');

imagedestroy($image);
imagedestroy($flipped);

flipVertical()

Flip an image vertically

public static function flipVertical($imgsrc)

Parameters:

  • $imgsrc (Mixed) - Source image resource

Returns: Mixed - Flipped image resource

Example:

use Kotchasan\Image;

$image = Image::loadImageResource('/path/to/photo.jpg');
$flipped = Image::flipVertical($image);

Image::saveImageResource($flipped, '/path/to/flipped_vertical.jpg');

imagedestroy($image);
imagedestroy($flipped);

info()

Get information about an image such as width, height, and MIME type

public static function info($source)

Parameters:

  • $source (string) - Path to the image file

Returns: array - Image information (width, height, mime)

Throws: \RuntimeException - If unable to get image info

Example:

use Kotchasan\Image;

try {
    $info = Image::info('/path/to/photo.jpg');

    echo "Width: " . $info['width'];
    echo "Height: " . $info['height'];
    echo "MIME Type: " . $info['mime'];

    // Check size
    if ($info['width'] > 2000 || $info['height'] > 2000) {
        echo "Image is too large";
    }
} catch (\RuntimeException $e) {
    echo "Error: " . $e->getMessage();
}

orient()

Adjust image orientation based on EXIF data

public static function orient($source)

Parameters:

  • $source (string) - Path to JPEG image file

Returns: Mixed - Image resource with corrected orientation

Throws: \RuntimeException - If image resource creation fails

Example:

use Kotchasan\Image;

// Fix orientation from mobile phone photo
$image = Image::orient('/path/to/phone_photo.jpg');

Image::saveImageResource($image, '/path/to/corrected.jpg');

imagedestroy($image);

watermarkText()

Add a text watermark to an image

public static function watermarkText($imgsrc, $text, $pos = 'bottom-right', $color = 'CCCCCC', $font_size = 20, $opacity = 50)

Parameters:

  • $imgsrc (Mixed) - Source image resource
  • $text (string) - Watermark text
  • $pos (string) - Position: 'center', 'bottom-right', 'bottom-left', 'top-right', 'top-left'
  • $color (string) - Color in hex format (e.g., 'CCCCCC')
  • $font_size (int) - Font size
  • $opacity (int) - Opacity (0-100)

Returns: Mixed - Image resource with watermark added

Throws: \RuntimeException - If the font file is not found

Example:

use Kotchasan\Image;

$image = Image::loadImageResource('/path/to/photo.jpg');

// Watermark at bottom-right
Image::watermarkText($image, 'Copyright 2024');

// Watermark at center, white color, 70% opacity
Image::watermarkText($image, 'DRAFT', 'center', 'FFFFFF', 40, 70);

// Thai text watermark
Image::watermarkText($image, 'ลิขสิทธิ์ 2567', 'bottom-right', '000000', 18, 60);

Image::saveImageResource($image, '/path/to/watermarked.jpg');

imagedestroy($image);

setQuality()

Set the image quality for JPEG and WEBP images

public static function setQuality($quality)

Parameters:

  • $quality (int) - Quality level (0-100)

Returns: void

Example:

use Kotchasan\Image;

// Set high quality
Image::setQuality(90);

$image = Image::loadImageResource('/path/to/photo.jpg');
Image::saveImageResource($image, '/path/to/high_quality.jpg');

// Set low quality (reduce file size)
Image::setQuality(60);
Image::saveImageResource($image, '/path/to/low_quality.jpg');

imagedestroy($image);

Real-World Examples

1. Profile Image Upload System

use Kotchasan\Image;
use Kotchasan\File;

class ProfileImageUploader
{
    public function upload($uploadedFile, $userId)
    {
        $uploadDir = ROOT_PATH . "uploads/profiles/{$userId}/";
        File::makeDirectory($uploadDir);

        $tempPath = $uploadedFile->getStream()->getMetadata('uri');
        $extension = File::ext($uploadedFile->getClientFilename());

        // Check if it's an image
        try {
            $info = Image::info($tempPath);
        } catch (\RuntimeException $e) {
            return ['error' => 'File is not an image'];
        }

        // Check size
        if ($info['width'] < 200 || $info['height'] < 200) {
            return ['error' => 'Image is too small (minimum 200x200 required)'];
        }

        $filename = 'profile_' . time() . '.jpg';

        // Create main image (800x800)
        Image::crop($tempPath, $uploadDir . $filename, 800, 800);

        // Create thumbnail (150x150)
        Image::crop($tempPath, $uploadDir . 'thumb_' . $filename, 150, 150);

        return [
            'success' => true,
            'filename' => $filename,
            'url' => "/uploads/profiles/{$userId}/{$filename}"
        ];
    }
}

2. Automatic Thumbnail Generator

class ThumbnailGenerator
{
    private $sizes = [
        'small' => 150,
        'medium' => 300,
        'large' => 600
    ];

    public function generateThumbnails($sourcePath, $outputDir)
    {
        File::makeDirectory($outputDir);

        $results = [];
        $baseName = pathinfo($sourcePath, PATHINFO_FILENAME);

        foreach ($this->sizes as $sizeName => $width) {
            $targetFile = "{$baseName}_{$sizeName}.jpg";
            $targetPath = $outputDir . $targetFile;

            $result = Image::resize($sourcePath, $outputDir, $targetFile, $width);

            if ($result) {
                $results[$sizeName] = [
                    'filename' => $result['name'],
                    'width' => $result['width'],
                    'height' => $result['height']
                ];
            }
        }

        return $results;
    }
}

3. Product Image Processor

class ProductImageProcessor
{
    public function process($uploadedFile, $productId)
    {
        $productDir = ROOT_PATH . "products/{$productId}/";
        File::makeDirectory($productDir);

        $tempPath = $uploadedFile->getStream()->getMetadata('uri');

        // Set high quality
        Image::setQuality(85);

        // Fix orientation (from mobile photos)
        $image = Image::orient($tempPath);

        // Create main image 1200x1200 with watermark
        $mainImage = Image::processImageResource($image, 1200, 1200, 'MyShop.com');
        Image::saveImageResource($mainImage, $productDir . 'main.jpg');

        // Create thumbnail 300x300
        $thumb = Image::processImageResource($image, 300, 300);
        Image::saveImageResource($thumb, $productDir . 'thumb.jpg');

        // Create gallery (fit mode) 800x600
        $gallery = Image::processImageResource($image, 800, 600, '', true);
        Image::saveImageResource($gallery, $productDir . 'gallery.jpg');

        imagedestroy($image);
        imagedestroy($mainImage);
        imagedestroy($thumb);
        imagedestroy($gallery);

        return [
            'main' => "products/{$productId}/main.jpg",
            'thumb' => "products/{$productId}/thumb.jpg",
            'gallery' => "products/{$productId}/gallery.jpg"
        ];
    }
}

4. Base64 Image Handler

class Base64ImageHandler
{
    public function saveFromBase64($base64String, $outputPath)
    {
        $result = Image::loadImageFromBase64($base64String, ['jpg', 'png']);

        if (!$result) {
            return ['error' => 'Invalid Base64 or unsupported file type'];
        }

        // Save original
        $originalPath = $outputPath . 'original.' . $result['extension'];
        Image::saveImageResource($result['resource'], $originalPath);

        // Create thumbnail
        $thumb = Image::processImageResource($result['resource'], 200, 200);
        Image::saveImageResource($thumb, $outputPath . 'thumb.jpg');

        imagedestroy($result['resource']);
        imagedestroy($thumb);

        return [
            'success' => true,
            'original' => $originalPath,
            'thumb' => $outputPath . 'thumb.jpg'
        ];
    }
}

Best Practices

1. Destroy Image Resources After Use

// ✅ Good
$image = Image::loadImageResource($source);
// ... use
imagedestroy($image);

// ❌ Bad - memory leak
$image = Image::loadImageResource($source);
// ... use without destroying

2. Check Image Info Before Processing

// ✅ Good
try {
    $info = Image::info($source);

    if ($info['width'] > 5000 || $info['height'] > 5000) {
        throw new \Exception('Image is too large');
    }

    Image::crop($source, $target, 800, 800);
} catch (\Exception $e) {
    // Handle error
}

3. Set Quality Based on Purpose

// ✅ Good
// For thumbnails - use lower quality
Image::setQuality(70);
Image::resize($source, $thumbDir, 'thumb.jpg', 200);

// For main images - use higher quality
Image::setQuality(90);
Image::resize($source, $mainDir, 'main.jpg', 1200);

4. Use try-catch for Operations That May Fail

// ✅ Good
try {
    $image = Image::loadImageResource($source);
    Image::saveImageResource($image, $target);
    imagedestroy($image);
} catch (\RuntimeException $e) {
    error_log("Image processing failed: " . $e->getMessage());
    return false;
}

Important Considerations

[!WARNING]
Memory Usage: Processing large images uses significant memory. Increase memory_limit for large images.

[!IMPORTANT]
GD Library Required: PHP GD extension must be installed.

[!NOTE]
EXIF Support: orient() requires EXIF extension to read orientation data.

[!TIP]
Font Path: For Thai text watermarks, font must be at /fonts/leelawad.ttf.

  • [File] - File and directory management
  • [Files] - File upload collections

Summary

Image class has 11 main methods:

  1. loadImageResource() - Load image from file
  2. loadImageFromBase64() - Load image from Base64
  3. processImageResource() - Process resize/crop
  4. saveImageResource() - Save to file
  5. crop() - Crop image
  6. resize() - Resize image
  7. flip() - Flip horizontally
  8. flipVertical() - Flip vertically
  9. info() - Get image information
  10. orient() - Adjust orientation from EXIF
  11. watermarkText() - Add text watermark
  12. setQuality() - Set image quality

Perfect for:

  • Profile image upload systems
  • Product image management
  • Automatic thumbnail generation
  • Base64 image processing
  • Adding copyright watermarks