'No file uploaded']; } $file = $_FILES[$field_name]; // Check for upload errors if ($file['error'] !== UPLOAD_ERR_OK) { $upload_errors = [ UPLOAD_ERR_INI_SIZE => 'File exceeds upload_max_filesize directive in php.ini', UPLOAD_ERR_FORM_SIZE => 'File exceeds MAX_FILE_SIZE directive in HTML form', UPLOAD_ERR_PARTIAL => 'File was only partially uploaded', UPLOAD_ERR_NO_FILE => 'No file was uploaded', UPLOAD_ERR_NO_TMP_DIR => 'Missing temporary folder', UPLOAD_ERR_CANT_WRITE => 'Failed to write file to disk', UPLOAD_ERR_EXTENSION => 'File upload stopped by PHP extension' ]; return ['error' => $upload_errors[$file['error']] ?? 'Unknown upload error']; } // Check file size if ($file['size'] > $MAX_FILE_SIZE) { return ['error' => 'File is too large. Maximum size is ' . format_bytes($MAX_FILE_SIZE)]; } // Check file type $finfo = new finfo(FILEINFO_MIME_TYPE); $mime = $finfo->file($file['tmp_name']); if (!in_array($mime, $allowed_types)) { return ['error' => 'Invalid file type. Only PDF files are allowed']; } // Generate unique filename if (!is_dir($UPLOAD_DIR)) { mkdir($UPLOAD_DIR, 0755, true); } $filename = uniqid() . '.pdf'; $destination = $UPLOAD_DIR . $filename; if (!move_uploaded_file($file['tmp_name'], $destination)) { return ['error' => 'Failed to move uploaded file']; } return [ 'success' => true, 'filepath' => $destination, 'filename' => $filename, 'original_name' => $file['name'], 'size' => $file['size'] ]; } // Format bytes to human-readable format function format_bytes($bytes, $precision = 2) { $units = ['B', 'KB', 'MB', 'GB', 'TB']; $bytes = max($bytes, 0); $pow = floor(($bytes ? log($bytes) : 0) / log(1024)); $pow = min($pow, count($units) - 1); $bytes /= pow(1024, $pow); return round($bytes, $precision) . ' ' . $units[$pow]; } // PDF Tools Functions function merge_pdfs($files, $output_filename) { $cmd = "gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=" . escapeshellarg($output_filename) . " "; foreach ($files as $file) { $cmd .= escapeshellarg($file) . ' '; } exec($cmd, $output, $return_var); if ($return_var !== 0) { return ['error' => 'Failed to merge PDFs. Ghostscript error.']; } if (!file_exists($output_filename) || filesize($output_filename) === 0) { return ['error' => 'Merged PDF creation failed']; } return ['success' => true, 'filepath' => $output_filename]; } function split_pdf($filepath, $output_dir, $pages) { $output_files = []; foreach ($pages as $i => $page_range) { $output_file = $output_dir . 'split_' . ($i + 1) . '.pdf'; $cmd = "gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -dFirstPage={$page_range[0]} -dLastPage={$page_range[1]} -sOutputFile=" . escapeshellarg($output_file) . " " . escapeshellarg($filepath); exec($cmd, $output, $return_var); if ($return_var !== 0 || !file_exists($output_file)) { return ['error' => "Failed to split PDF at page range {$page_range[0]}-{$page_range[1]}"]; } $output_files[] = $output_file; } return ['success' => true, 'files' => $output_files]; } function pdf_to_images($filepath, $output_dir, $format = 'jpg', $dpi = 150) { $output_pattern = $output_dir . 'page_%d.' . $format; $device = $format === 'png' ? 'png16m' : 'jpeg'; $cmd = "gs -q -dNOPAUSE -dBATCH -sDEVICE=$device -r$dpi -sOutputFile=" . escapeshellarg($output_pattern) . " " . escapeshellarg($filepath); exec($cmd, $output, $return_var); if ($return_var !== 0) { return ['error' => 'Failed to convert PDF to images']; } // Get list of generated images $images = glob($output_dir . 'page_*.' . $format); if (empty($images)) { return ['error' => 'No images were generated']; } sort($images); return ['success' => true, 'images' => $images]; } function compress_pdf($filepath, $output_file, $quality = 'ebook') { // Quality levels: screen (72dpi), ebook (150dpi), printer (300dpi), prepress (high quality) $cmd = "gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/$quality -sOutputFile=" . escapeshellarg($output_file) . " " . escapeshellarg($filepath); exec($cmd, $output, $return_var); if ($return_var !== 0 || !file_exists($output_file)) { return ['error' => 'Failed to compress PDF']; } return ['success' => true, 'filepath' => $output_file]; } function protect_pdf($filepath, $output_file, $password) { $cmd = "qpdf --encrypt " . escapeshellarg($password) . " " . escapeshellarg($password) . " 256 -- " . escapeshellarg($filepath) . " " . escapeshellarg($output_file); exec($cmd, $output, $return_var); if ($return_var !== 0 || !file_exists($output_file)) { return ['error' => 'Failed to password protect PDF']; } return ['success' => true, 'filepath' => $output_file]; } function unlock_pdf($filepath, $output_file, $password) { $cmd = "qpdf --decrypt --password=" . escapeshellarg($password) . " " . escapeshellarg($filepath) . " " . escapeshellarg($output_file); exec($cmd, $output, $return_var); if ($return_var !== 0 || !file_exists($output_file)) { return ['error' => 'Failed to unlock PDF. Wrong password or corrupted file.']; } return ['success' => true, 'filepath' => $output_file]; } function pdf_to_text($filepath, $output_file) { $cmd = "pdftotext " . escapeshellarg($filepath) . " " . escapeshellarg($output_file); exec($cmd, $output, $return_var); if ($return_var !== 0 || !file_exists($output_file) || filesize($output_file) === 0) { return ['error' => 'Failed to extract text from PDF']; } return ['success' => true, 'filepath' => $output_file]; } function create_zip($files, $zip_filename) { $zip = new ZipArchive(); if ($zip->open($zip_filename, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== TRUE) { return ['error' => 'Failed to create zip file']; } foreach ($files as $file) { if (file_exists($file)) { $zip->addFile($file, basename($file)); } } $zip->close(); if (!file_exists($zip_filename)) { return ['error' => 'Zip file creation failed']; } return ['success' => true, 'filepath' => $zip_filename]; } // Clean up old files function cleanup_old_files() { global $UPLOAD_DIR, $FILE_LIFETIME; $files = glob($UPLOAD_DIR . '*'); $now = time(); foreach ($files as $file) { if (is_file($file) && ($now - filemtime($file) > $FILE_LIFETIME)) { if (is_dir($file)) { array_map('unlink', glob("$file/*")); rmdir($file); } else { unlink($file); } } } } // Main processing session_start(); cleanup_old_files(); $errors = check_requirements(); $action = $_GET['action'] ?? ''; $result = null; $download_link = ''; $original_filename = ''; // Process actions if (empty($errors)) { switch ($action) { case 'merge': if ($_SERVER['REQUEST_METHOD'] === 'POST') { $files = []; $upload_errors = []; foreach ($_FILES['pdf_files']['tmp_name'] as $i => $tmp_name) { if ($_FILES['pdf_files']['error'][$i] === UPLOAD_ERR_OK) { $upload = handle_upload('pdf_files'); if (isset($upload['filepath'])) { $files[] = $upload['filepath']; if ($i === 0) $original_filename = pathinfo($upload['original_name'], PATHINFO_FILENAME); } else { $upload_errors[] = $upload['error']; } } } if (count($files) > 1) { $output_file = $UPLOAD_DIR . 'merged_' . uniqid() . '.pdf'; $result = merge_pdfs($files, $output_file); if (isset($result['filepath'])) { $download_link = $result['filepath']; $original_filename = $original_filename ? $original_filename . '_merged' : 'merged'; } } else { $result = ['error' => 'You need to upload at least 2 PDF files to merge']; } if (!empty($upload_errors)) { $result['upload_errors'] = $upload_errors; } } break; case 'split': if ($_SERVER['REQUEST_METHOD'] === 'POST') { $upload = handle_upload('pdf_file'); if (isset($upload['filepath'])) { $original_filename = pathinfo($upload['original_name'], PATHINFO_FILENAME); $page_ranges = []; $ranges = explode(',', $_POST['page_ranges']); foreach ($ranges as $range) { $parts = explode('-', trim($range)); if (count($parts) === 1) { $page_ranges[] = [$parts[0], $parts[0]]; } else { $page_ranges[] = [$parts[0], $parts[1] ?? $parts[0]]; } } $output_dir = $UPLOAD_DIR . 'split_' . uniqid() . '/'; mkdir($output_dir, 0755, true); $result = split_pdf($upload['filepath'], $output_dir, $page_ranges); if (isset($result['files'])) { $zip_filename = $UPLOAD_DIR . 'split_' . uniqid() . '.zip'; $zip_result = create_zip($result['files'], $zip_filename); if (isset($zip_result['filepath'])) { $download_link = $zip_result['filepath']; $original_filename = $original_filename ? $original_filename . '_split' : 'split'; } else { $result = $zip_result; } } } else { $result = $upload; } } break; case 'pdf_to_jpg': if ($_SERVER['REQUEST_METHOD'] === 'POST') { $upload = handle_upload('pdf_file'); if (isset($upload['filepath'])) { $original_filename = pathinfo($upload['original_name'], PATHINFO_FILENAME); $output_dir = $UPLOAD_DIR . 'images_' . uniqid() . '/'; mkdir($output_dir, 0755, true); $format = $_POST['format'] ?? 'jpg'; $dpi = min(max(intval($_POST['dpi'] ?? 150), 300, 72); $result = pdf_to_images($upload['filepath'], $output_dir, $format, $dpi); if (isset($result['images'])) { $zip_filename = $UPLOAD_DIR . 'images_' . uniqid() . '.zip'; $zip_result = create_zip($result['images'], $zip_filename); if (isset($zip_result['filepath'])) { $download_link = $zip_result['filepath']; $original_filename = $original_filename ? $original_filename . '_images' : 'images'; } else { $result = $zip_result; } } } else { $result = $upload; } } break; case 'compress': if ($_SERVER['REQUEST_METHOD'] === 'POST') { $upload = handle_upload('pdf_file'); if (isset($upload['filepath'])) { $original_filename = pathinfo($upload['original_name'], PATHINFO_FILENAME); $quality = $_POST['quality'] ?? 'ebook'; $output_file = $UPLOAD_DIR . 'compressed_' . uniqid() . '.pdf'; $result = compress_pdf($upload['filepath'], $output_file, $quality); if (isset($result['filepath'])) { $download_link = $result['filepath']; $original_filename = $original_filename ? $original_filename . '_compressed' : 'compressed'; } } else { $result = $upload; } } break; case 'protect': if ($_SERVER['REQUEST_METHOD'] === 'POST') { $upload = handle_upload('pdf_file'); if (isset($upload['filepath'])) { $original_filename = pathinfo($upload['original_name'], PATHINFO_FILENAME); $password = $_POST['password'] ?? ''; if (empty($password)) { $result = ['error' => 'Password is required']; } else { $output_file = $UPLOAD_DIR . 'protected_' . uniqid() . '.pdf'; $result = protect_pdf($upload['filepath'], $output_file, $password); if (isset($result['filepath'])) { $download_link = $result['filepath']; $original_filename = $original_filename ? $original_filename . '_protected' : 'protected'; } } } else { $result = $upload; } } break; case 'unlock': if ($_SERVER['REQUEST_METHOD'] === 'POST') { $upload = handle_upload('pdf_file'); if (isset($upload['filepath'])) { $original_filename = pathinfo($upload['original_name'], PATHINFO_FILENAME); $password = $_POST['password'] ?? ''; if (empty($password)) { $result = ['error' => 'Password is required']; } else { $output_file = $UPLOAD_DIR . 'unlocked_' . uniqid() . '.pdf'; $result = unlock_pdf($upload['filepath'], $output_file, $password); if (isset($result['filepath'])) { $download_link = $result['filepath']; $original_filename = $original_filename ? $original_filename . '_unlocked' : 'unlocked'; } } } else { $result = $upload; } } break; case 'pdf_to_text': if ($_SERVER['REQUEST_METHOD'] === 'POST') { $upload = handle_upload('pdf_file'); if (isset($upload['filepath'])) { $original_filename = pathinfo($upload['original_name'], PATHINFO_FILENAME); $output_file = $UPLOAD_DIR . 'text_' . uniqid() . '.txt'; $result = pdf_to_text($upload['filepath'], $output_file); if (isset($result['filepath'])) { $download_link = $result['filepath']; $original_filename = $original_filename ? $original_filename . '_text' : 'text'; } } else { $result = $upload; } } break; } } // HTML Interface ?> PDF Tools - All-in-One PDF Solution

All Your PDF Needs in One Place

Merge, split, compress, convert and more - 100% free and easy to use. No installation or registration required.

Get Started

Server Requirements Not Met

Please contact your hosting provider to resolve these issues.

Popular PDF Tools

Select the tool you need to work with your PDF files

Merge PDF

Combine multiple PDF files into a single document in seconds.

Merge PDFs

Split PDF

Extract pages or split a PDF into multiple files.

Split PDF

PDF to JPG

Convert each page of your PDF to a JPG image.

Convert to JPG

Compress PDF

Reduce the file size of your PDF documents.

Compress PDF

Protect PDF

Add password protection to your PDF files.

Protect PDF

Unlock PDF

Remove password protection from PDF files.

Unlock PDF

PDF to Text

Extract text from your PDF documents.

Extract Text
Back to Tools

Operation Completed Successfully!

Your file is ready to download.

Download File

Merge PDF Files

Select multiple PDF files to merge them into a single document.

Upload Errors:

Drag & drop your PDF files here or click to browse

(Maximum file size: )

Split PDF File

Upload a PDF file and specify page ranges to split (e.g., "1-3,5,7-9").

Drag & drop your PDF file here or click to browse

(Maximum file size: )

Enter page ranges separated by commas (e.g., 1-3,5,7-9)

Convert PDF to Images

Convert each page of your PDF to JPG or PNG images.

Drag & drop your PDF file here or click to browse

(Maximum file size: )

Compress PDF

Reduce the file size of your PDF document.

Drag & drop your PDF file here or click to browse

(Maximum file size: )

Protect PDF

Add password protection to your PDF file.

Drag & drop your PDF file here or click to browse

(Maximum file size: )

Remember this password. You'll need it to open the PDF.

Unlock PDF

Remove password protection from a PDF file.

Drag & drop your PDF file here or click to browse

(Maximum file size: )

Enter the password for the PDF file.

PDF to Text

Extract text from your PDF document.

Drag & drop your PDF file here or click to browse

(Maximum file size: )

Why Choose Our PDF Tools?

We provide the best PDF tools with these amazing features

Secure Processing

Your files are processed securely and deleted automatically after 1 hour. We don't store your documents permanently.

Fast Processing

Our tools use optimized algorithms to process your PDF files as quickly as possible, saving you time.

No Installation

All tools work directly in your browser. No software installation or registration required.

100% Free

All our PDF tools are completely free to use with no hidden charges or limitations.

Mobile Friendly

Works perfectly on all devices including smartphones and tablets.

Unlimited Usage

Use our tools as many times as you need without any restrictions.