save()
public function save(?string $filename = null, int $compression = 100, ?int $permissions = null): void
Description
Saves the currently loaded and processed image to disk. This method writes the image resource to a file with optional compression settings for JPEG and WEBP formats, and allows setting file permissions. The method automatically handles format-specific requirements such as transparency preservation for PNG images.
Load and Process First: This method requires an image to be loaded first using load() or upload(). Any processing operations (resize, crop, etc.) must be performed before calling save(). The method saves the current state of the image resource.
Parameters
| Parameter |
Type |
Description |
Default |
Required |
| $filename |
string|null |
The path where the image will be saved. If null, uses the internal filename from load(). |
null |
No |
| $compression |
int |
Compression level for JPEG/WEBP (0-100). Higher values = better quality, larger files. Has no effect on GIF/PNG. |
100 |
No |
| $permissions |
int|null |
File permissions in octal format (e.g., 0644, 0755). If null, uses system defaults. |
null |
No |
Understanding Compression
The $compression parameter controls the quality vs. file size trade-off for JPEG and WEBP images:
- 100: Maximum quality, largest file size - ideal for archival or source images
- 85-95: High quality, reasonable file size - recommended for most web use
- 70-84: Good quality, smaller files - suitable for thumbnails or bandwidth-conscious applications
- Below 70: Noticeable quality loss - generally not recommended unless file size is critical
Format-Specific Behaviour: The compression parameter only affects JPEG and WEBP images. PNG uses lossless compression automatically, and GIF has no compression options. PNG images also have transparency (alpha channel) preserved automatically via imagesavealpha().
Return Value
| Type |
Description |
| void |
This method does not return a value. It writes the image to disk. |
Example #1
The code sample below demonstrates the most basic use of save().
// Load an image
$this->image->load('modules/gallery/photos/original.jpg');
// Resize it
$this->image->resize_to_width(800);
// Save to a new location
$this->image->save('modules/gallery/photos/resized.jpg', 85);
The Standard Workflow: The typical pattern is load → manipulate → save. All processing operations (resize, crop, etc.) modify the image resource in memory. Call save() as the final step to write the processed image to disk. The compression value of 85 provides excellent quality whilst significantly reducing file size compared to 100.
Example #2
The example above shows how to save an image with specific permissions for security.
public function process_secure_upload(): void {
$document_id = segment(3, 'int');
// Validate upload
$this->validation->set_rules('userfile', 'Secure Document', 'required|allowed_types[jpg,png]|max_size[5000]');
if ($this->validation->run() === true) {
// Configure upload to secure directory
$config = [
'destination' => 'secure/documents',
'upload_to_module' => true,
'target_module' => 'documents',
'make_rand_name' => true
];
// Ensure secure directory exists
$secure_dir = 'modules/documents/secure/documents';
if (!$this->file->exists($secure_dir)) {
$this->file->create_directory($secure_dir, 0750);
}
// Upload the image
$file_info = $this->image->upload($config);
// Load for processing
$this->image->load($file_info['file_path']);
// Resize if necessary
if ($this->image->get_width() > 1200) {
$this->image->resize_to_width(1200);
}
// Save with restricted permissions (owner read/write only)
$this->image->save($file_info['file_path'], 85, 0600);
$this->image->destroy();
// Store in database
$data = [
'document_id' => $document_id,
'filename' => $file_info['file_name'],
'file_path' => $file_info['file_path'],
'uploaded_at' => date('Y-m-d H:i:s')
];
$this->model->insert($data, 'secure_documents');
set_flashdata('Secure document uploaded successfully');
redirect('documents/view/' . $document_id);
} else {
$this->upload_form($document_id);
}
}
Security Through Permissions: Use the $permissions parameter to control file access. Common values include 0644 (owner read/write, others read), 0600 (owner read/write only), and 0755 (owner full access, others read/execute). For sensitive images, use restrictive permissions like 0600 and store outside the public directory.
Example #3
The example above demonstrates creating multiple quality versions of the same image.
public function generate_quality_variants(): void {
$photo_id = segment(3, 'int');
// Get photo record
$photo = $this->db->get_where($photo_id, 'photos');
if ($photo === false) {
redirect('photos/not_found');
}
$source_path = 'modules/gallery/originals/' . $photo->filename;
if (!$this->file->exists($source_path)) {
redirect('photos/file_missing');
}
// Define quality/compression variants
$quality_settings = [
'high' => 95, // Near-lossless
'standard' => 85, // Excellent quality, good compression
'web' => 75, // Good quality, smaller files
'thumbnail' => 70 // Acceptable quality, minimal size
];
foreach ($quality_settings as $quality_name => $compression) {
// Load source fresh for each variant
$this->image->load($source_path);
// Resize appropriately for quality level
if ($quality_name === 'thumbnail') {
$this->image->resize_to_width(300);
} else {
$this->image->resize_to_width(1200);
}
// Ensure quality directory exists
$output_dir = 'modules/gallery/quality/' . $quality_name;
if (!$this->file->exists($output_dir)) {
$this->file->create_directory($output_dir, 0755);
}
// Save with specific compression level
$output_path = $output_dir . '/' . $photo->filename;
$this->image->save($output_path, $compression);
$this->image->destroy();
}
set_flashdata('Quality variants generated successfully');
redirect('gallery/view/' . $photo_id);
}
Compression Strategy: Different use cases require different compression levels. Use high compression (95-100) for archival copies, moderate compression (80-90) for web display, and lower compression (70-80) for thumbnails where small file size matters more than perfect quality. This multi-quality approach allows you to serve appropriate versions based on context.
Example #4
The example above shows saving processed images whilst preserving transparency for PNG format.
public function process_logo_upload(): void {
$company_id = segment(3, 'int');
// Validate PNG upload
$this->validation->set_rules('userfile', 'Company Logo', 'required|allowed_types[png]|max_size[2000]');
if ($this->validation->run() === true) {
// Configure upload
$config = [
'destination' => 'logos',
'upload_to_module' => true,
'target_module' => 'companies',
'make_rand_name' => true
];
// Ensure directory exists
$logo_dir = 'modules/companies/logos';
if (!$this->file->exists($logo_dir)) {
$this->file->create_directory($logo_dir, 0755);
}
// Upload the logo
$file_info = $this->image->upload($config);
// Create multiple sizes whilst preserving transparency
$sizes = [
'large' => 400,
'medium' => 200,
'small' => 100,
'favicon' => 32
];
foreach ($sizes as $size_name => $width) {
// Load source fresh
$this->image->load($file_info['file_path']);
// Resize
$this->image->resize_to_width($width);
// Save PNG (transparency preserved automatically)
$filename_parts = pathinfo($file_info['file_name']);
$sized_filename = $filename_parts['filename'] . '_' . $size_name . '.png';
$output_path = $logo_dir . '/' . $sized_filename;
// PNG compression parameter is ignored, but transparency is preserved
$this->image->save($output_path, 100, 0644);
$this->image->destroy();
}
// Update company record
$data = [
'logo_filename' => $file_info['file_name'],
'logo_updated_at' => date('Y-m-d H:i:s')
];
$this->model->update($company_id, $data, 'companies');
set_flashdata('Company logo uploaded and processed successfully');
redirect('companies/view/' . $company_id);
} else {
$this->logo_upload_form($company_id);
}
}
Transparency Preservation: When working with PNG images that contain transparency (alpha channels), the save() method automatically preserves transparency through the imagesavealpha() function. This happens regardless of the compression parameter value. This is essential for logos, icons, and overlay images that require transparent backgrounds.