Blog Post

How to Convert HTML to an Image Using wkhtmltoimage and Laravel

Illustration: How to Convert HTML to an Image Using wkhtmltoimage and Laravel

Converting HTML to an image is a common task for developers, and it can be used for a variety of purposes, such as creating screenshots or thumbnails of webpages. One popular tool for converting HTML to an image is wkhtmltoimage, a command-line tool that uses the WebKit rendering engine. It’s lightweight and fast, and it runs headless, which means it doesn’t require a graphical user interface (GUI). It’s available for macOS, Linux, and Windows.

In this tutorial, you’ll learn how to use wkhtmltoimage in combination with Laravel, a popular PHP web application framework, to convert HTML to an image.

Development Considerations

Before getting started, it’s important to note that wkhtmltoimage is a command-line tool, and it doesn’t have a built-in GUI. It’s also an open source tool, created in 2008 by Jakob Truelsen, and it isn’t being consistently maintained at this time.

If you’re considering a commercial solution, PSPDFKit offers an HTML to Image API. Our hosted solution gives you 100 free image conversions per month, and for larger amounts, offers additional packages for a per-image fee. Our solutions are regularly maintained, with releases occurring multiple times throughout the year. We also offer one-on-one support to handle any issues or challenges that you encounter.

Requirements

  • PHP — You’ll need to have PHP installed on your system. You can download the latest version from the official PHP website.

To check if you have PHP installed on your system, you can open a terminal and run the command php -v.

  • Laravel framework — You can download the latest version from the Laravel website.

You can check if you have Laravel installed by running the command laravel -v in the terminal. If you don’t have Laravel installed, you can install it by running the following command:

composer global require laravel/installer
  • Next, add Composer, a dependency manager, to your path directory:

export PATH="$HOME/.composer/vendor/bin:$PATH"

Setting Up the Project

Create a new Laravel project by running the following:

laravel new html-to-image

This will create a new directory called html-to-image with the basic Laravel structure.

Navigate to the project directory by running the following command:

cd html-to-image

Installing wkhtmltoimage

Install wkhtmltoimage on your system. You can download the appropriate version for your operating system from the official website.

Check if wkhtmltoimage is installed by running the following command:

wkhtmltoimage -V

It’ll display the version number of the library like this:

wkhtmltoimage 0.12.6 (with patched qt)

Make sure you have wkhtmltoimage installed on your system and that the binary is in the system’s PATH. You can check this by running the following command:

which wkhtmltoimage

Terminal showing the path to wkhtmltoimage

If it’s not in the PATH, you can add the location to the PATH variable.

Integrating wkhtmltoimage with Laravel

  1. Once you have wkhtmltoimage installed, you can integrate it with Laravel by creating a new command that utilizes the library. To do this, use the following command to generate a new command class:

php artisan make:command ConvertHtmlToImage

This will create a new file in the app/Console/Commands directory.

  1. Open this file and update the handle method to use the wkhtmltoimage library to convert HTML to an image:

public function handle()
   {
      $html = $this->argument('html');
      $output = $this->argument('output');

      exec("wkhtmltoimage --format png $html $output");
      $this->info("HTML converted to image and saved to $output");
   }

This method takes the html and output arguments and passes them to the wkhtmltoimage command. The --format option is used to specify the output format, which, in this case, is PNG.

The exec() function is used to execute the wkhtmltoimage command, which takes the input HTML file and the output image file path as arguments.

The info() function is used to display a message indicating that the HTML has been converted to an image and saved to the specified output file path.

  1. In the signature property of the class, define the arguments and options that this command accepts:

protected $signature = 'convert:html-to-image {html : public/index.html} {output : public/image.png}';

The html argument is the path to the HTML file that will be converted to an image, and the output argument is the path to the output image file.

  1. Here’s the full code for the controller:

<!-- app/Console/Commands/ConvertHtmlToImage.php -->
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;

class ConvertHtmlToImage extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'convert:html-to-image {html : public/input.html} {output : public/image.png}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Convert HTML to image using wkhtmltoimage';

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        $html = $this->argument('html');
        $output = $this->argument('output');

        exec("wkhtmltoimage --format png $html $output");
        $this->info("HTML converted to image and saved to $output");
    }
}

Creating the HTML File

Currently, there isn’t an HTML file inside the public directory. So, create a file called index.html and paste the following code into it:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>
			A simple, clean, and responsive HTML invoice template
		</title>

		<style>
			.invoice-box {
				max-width: 800px;
				margin: auto;
				padding: 30px;
				border: 1px solid #eee;
				box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
				font-size: 16px;
				line-height: 24px;
				font-family: 'Helvetica Neue', 'Helvetica', Helvetica,
					Arial, sans-serif;
				color: #555;
			}

			.invoice-box table {
				width: 100%;
				line-height: inherit;
				text-align: left;
			}

			.invoice-box table td {
				padding: 5px;
				vertical-align: top;
			}

			.invoice-box table tr td:nth-child(2) {
				text-align: right;
			}

			.invoice-box table tr.top table td {
				padding-bottom: 20px;
			}

			.invoice-box table tr.top table td.title {
				font-size: 45px;
				line-height: 45px;
				color: #333;
			}

			.invoice-box table tr.information table td {
				padding-bottom: 40px;
			}

			.invoice-box table tr.heading td {
				background: #eee;
				border-bottom: 1px solid #ddd;
				font-weight: bold;
			}

			.invoice-box table tr.details td {
				padding-bottom: 20px;
			}

			.invoice-box table tr.item td {
				border-bottom: 1px solid #eee;
			}

			.invoice-box table tr.item.last td {
				border-bottom: none;
			}

			.invoice-box table tr.total td:nth-child(2) {
				border-top: 2px solid #eee;
				font-weight: bold;
			}

			@media only screen and (max-width: 600px) {
				.invoice-box table tr.top table td {
					width: 100%;
					display: block;
					text-align: center;
				}

				.invoice-box table tr.information table td {
					width: 100%;
					display: block;
					text-align: center;
				}
			}

			/** RTL **/
			.invoice-box.rtl {
				direction: rtl;
				font-family: Tahoma, 'Helvetica Neue', 'Helvetica',
					Helvetica, Arial, sans-serif;
			}

			.invoice-box.rtl table {
				text-align: right;
			}

			.invoice-box.rtl table tr td:nth-child(2) {
				text-align: left;
			}
		</style>
	</head>

	<body>
		<div class="invoice-box">
			<table cellpadding="0" cellspacing="0">
				<tr class="top">
					<td colspan="2">
						<table>
							<tr>
								<td>
									Invoice #: 123
									<br />
									Created: January 23, 2023
									<br />
									Due: January 31, 2023
								</td>
							</tr>
						</table>
					</td>
				</tr>

				<tr class="information">
					<td colspan="2">
						<table>
							<tr>
								<td>
									Acme, Inc.
									<br />
									12345 Sunny Road
									<br />
									Sunnyville, TX 12345
								</td>

								<td>
									Acme Corp.
									<br />
									John Doe
									<br />
									john@example.com
								</td>
							</tr>
						</table>
					</td>
				</tr>

				<tr class="heading">
					<td>Payment Method</td>

					<td>Check #</td>
				</tr>

				<tr class="details">
					<td>Check</td>

					<td>1000</td>
				</tr>

				<tr class="heading">
					<td>Item</td>

					<td>Price</td>
				</tr>

				<tr class="item">
					<td>Website design</td>

					<td>$300.00</td>
				</tr>

				<tr class="item">
					<td>Hosting (3 months)</td>

					<td>$75.00</td>
				</tr>

				<tr class="item last">
					<td>Domain name (1 year)</td>

					<td>$10.00</td>
				</tr>

				<tr class="total">
					<td></td>

					<td>Total: $385.00</td>
				</tr>
			</table>
		</div>
	</body>
</html>

Converting HTML to PNG

Navigate to the project directory and run the following command:

php artisan convert:html-to-image public/index.html public/image.png

This runs the ConvertHtmlToImage command, which is defined in the app/Console/Commands/ConvertHtmlToImage.php file.

It takes two arguments:

  • The first argument is the path to the input HTML file (public/index.html).

  • The second argument is the path to the output image file (public/image.png).

This command will convert the HTML file to an image and save it to the public/image.png file.

Final result

Information

You can check the source code of the demo project on GitHub.

Conclusion

In this tutorial, you learned how to set up a Laravel project and integrate the wkhtmltoimage library to convert HTML to an image. By following these steps, you can easily add this functionality to your application. Converting HTML to an image can be a useful feature for many web applications, and the wkhtmltoimage library in conjunction with the Laravel framework makes it easy to implement.

You can also consider using a package like Spatie/Browsershot, which uses headless Chrome to convert HTML to an image, but you need to have Chrome and Puppeteer installed on your system.

If you’re looking to add more robust image capabilities, PSPDFKit offers a commercial option that gives you 100 free conversions per month. Our HTML to Image API can easily be integrated into your workflow or application. Create an account to unlock 100 free conversions per month.

Related Products
Share Post
Free 60-Day Trial Try PSPDFKit in your app today.
Free Trial

Related Articles

Explore more
PRODUCTS  |  Web • Releases • Components

PSPDFKit for Web 2024.2 Features New Unified UI Icons, Shadow DOM, and Tab Ordering

PRODUCTS  |  Web

Now Available for Public Preview: New Document Authoring Experience Provides Glimpse into the Future of Editing

PRODUCTS  |  Web • Releases • Components

PSPDFKit for Web 2024.1 Adds LTV Support for Digital Signatures and Improves the Document Editor UI