{"id":27809,"date":"2022-06-28T09:45:38","date_gmt":"2022-06-28T09:45:38","guid":{"rendered":"http:\/\/watermarking-images-using-laravel-and-cloudinary"},"modified":"2025-02-19T15:52:59","modified_gmt":"2025-02-19T23:52:59","slug":"watermarking-images-using-laravel-and-cloudinary","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/guest_post\/watermarking-images-using-laravel-and-cloudinary\/","title":{"rendered":"Watermarking Images using Laravel &amp; Cloudinary"},"content":{"rendered":"<div class=\"wp-block-cloudinary-markdown \"><p>Laravel is a PHP framework developed with developer productivity in mind. The framework also aims to evolve with the web and has already incorporated several new features and ideas in the web development world\u2014such as job queues, <strong>API authentication<\/strong> out of the box, real-time communication, and much more.<\/p>\n<h2>Introduction<\/h2>\n<p>In this article, we\u2019ll explore the ways you can build a simple Cloudinary Watermark API using Laravel. The API will allow you to add a watermark to an image using Cloudinary\u2019s powerful transformational API. We\u2019ll be using Laravel 8, and all of the code is available for reference on GitHub.<\/p>\n<h2>Github<\/h2>\n<p>You can find the full source code on my <a href=\"https:\/\/github.com\/musebe\/laravel-cloudinaty-watermark\">Github<\/a> repository.<\/p>\n<h2>PHPSandbox and Github<\/h2>\n<p>The final project can be viewed on <a href=\"https:\/\/phpsandbox.io\/e\/x\/nupqt?layout=EditorPreview&amp;defaultPath=%2F&amp;theme=dark&amp;showExplorer=no&amp;openedFiles=\">PHPSandbox<\/a><\/p>\n<h2>Prerequisites<\/h2>\n<p>Using Cloudinary in your Laravel projects is pretty straightforward. However, for you to be able to easily follow along,\nyou need to have a good command of your terminal, Git, and entry knowledge of PHP specifically with the Laravel\nframework.<\/p>\n<p>You also need to understand what a RESTful API is. REST stands for <em>REpresentational State Transfer<\/em> and is an architectural style for network communication between applications, which relies on a stateless protocol (usually HTTP) for interaction.<\/p>\n<p>Lastly, you will need an API Client\/Platform such as <a href=\"https:\/\/www.postman.com\/\">Postman<\/a> or <a href=\"https:\/\/insomnia.rest\/\">Insomnia<\/a> installed on your system to test the API endpoints.<\/p>\n<h2>Getting Started<\/h2>\n<p>Being that Laravel is a PHP Framework, we will need Composer. Like any modern PHP framework, Laravel uses Composer to manage its dependencies. So, before we can\nstart ensure you have Composer installed on your machine. Follow step 1 below to install Composer and PHP.<\/p>\n<ol>\n<li>\n<p>Install <a href=\"https:\/\/getcomposer.org\/\">Composer<\/a> and <a href=\"https:\/\/www.php.net\/manual\/en\/install.windows.tools.php\">PHP<\/a> on\nyour development or production machine.<\/p>\n<\/li>\n<li>\n<p>Install Laravel<\/p>\n<ol>\n<li>\n<p>Via Composer:<\/p>\n<p><code>composer create-project --prefer-dist laravel\/laravel cloudinary-watermark-api<\/code><\/p>\n<\/li>\n<li>\n<p>Via Laravel Installer<\/p>\n<p><code>composer global require laravel\/installer<\/code><\/p>\n<p><code>laravel new cloudinary-watermark-api<\/code><\/p>\n<\/li>\n<\/ol>\n<\/li>\n<li>\n<p>In step 2 above we have installed the Laravel Installer and used it to scaffold a new application in the folder <code>cloudinary-watermark-api<\/code>. With Laravel installed, we should be able to start and test the server ensuring everything is okay. Change the directory to the project folder and run the local development server by typing the following commands:<\/p>\n<p><code>cd cloudinary-watermark-api<\/code><\/p>\n<p><code>php artisan serve<\/code><\/p>\n<\/li>\n<\/ol>\n<p>The Laravel project is now up and running. When you open <code>http:\/\/localhost:8000<\/code> on your computer, you should see the image below:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/dgrpkngjn\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/v1655887283\/watermark-api\/assets\/laravel-running_zqk8ol.png\" alt=\"Laravel Server Running\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1239\" height=\"638\"\/><\/p>\n<h2>Routes and Controllers<\/h2>\n<p>In the <code>routes\/<\/code> folder you will notice that Laravel has a couple of files. We will work with the <code>routes\/api.php<\/code> file to create the routes we need for our API.<\/p>\n<p>For a start, we will need two endpoints, one to upload the watermark to Cloudinary and the other to create the watermark branded images, but you can add more routes you need as you continue exploring the Cloudinary APIs.<\/p>\n<p>We have a route now we need to create a controller. Run the following commands to create one.<\/p>\n<p><code>php artisan make:controller WatermarkController<\/code><\/p>\n<p>This will create the controller <code>app\/Http\/Controllers\/WatermarkController.php<\/code><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/dgrpkngjn\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/v1655887282\/watermark-api\/assets\/watermark_controller_axuzlv.png\" alt=\"WatermarkController\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"877\" height=\"472\"\/><\/p>\n<p>At the moment it is empty, but we will populate it shortly. First things first, let us set up Cloudinary \ud83d\ude4c\ud83c\udffe\ud83d\ude0a.<\/p>\n<h2>Setting up Cloudinary\u2019s Laravel SDK<\/h2>\n<p>Cloudinary has a tonne of features from media upload, storage, administration, and manipulation to optimization and delivery. In this case, we will use Cloudinary\u2019s transformation features to create an API endpoint that will automatically overlay a brand\/watermark image over our media.<\/p>\n<p>That way our media content will be authentic and super professional which is a requirement for excellent brand management<\/p>\n<p>To get started:<\/p>\n<ol>\n<li>\n<p>Sign up for a free Cloudinary account then navigate to the Console page and take note of your Cloud name, API Key and\nAPI Secret.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/dgrpkngjn\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/v1655887283\/watermark-api\/assets\/cloudinary_dashboard_m5d8ye.png\" alt=\"Cloudinary Dashboard\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"940\" height=\"441\"\/><\/p>\n<\/li>\n<li>\n<p>Install <a href=\"https:\/\/github.com\/cloudinary-labs\/cloudinary-laravel#installation\">Cloudinary\u2019s Laravel SDK<\/a>:<\/p>\n<p><code>composer require cloudinary-labs\/cloudinary-laravel<\/code><\/p>\n<\/li>\n<\/ol>\n<p><strong>Note<\/strong>: Please ensure you follow all the steps in the #Installation section. Publish the configuration file and add\nthe Cloudinary credentials you noted in Step 1 to the <code>.env<\/code> file.<\/p>\n<h2>Creating the Watermark Endpoint<\/h2>\n<p>We will make use of the <code>WatermarkController<\/code> we had created earlier. It will take two required inputs from the <code>POST<\/code> request:<\/p>\n<ol>\n<li>\n<code>watermark<\/code> &#8211; This is a required image input of type PNG since we need our watermark to be transparent in order to overlay it over other images.<\/li>\n<li>\n<code>public_id<\/code> &#8211; We need to implicitly provide the public id for our watermark since we will need to specify this when performing the overlay transformation later on.<\/li>\n<\/ol>\n<p>Open the file <code>app\/Http\/WatermarkController.php<\/code> and add the following code:<\/p>\n<ol>\n<li>First we create the function upload which will correspond to our <code>watermark\/upload<\/code> endpoint.<\/li>\n<\/ol>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">upload<\/span><span class=\"hljs-params\">(Request $request)<\/span> <\/span>{\n\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<ol start=\"2\">\n<li>Add the functionality to validate the required inputs, upload the watermark to Cloudinary and send a response to the user. Here is how it works:<\/li>\n<\/ol>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">upload<\/span><span class=\"hljs-params\">(Request $request)<\/span>: <span class=\"hljs-title\">JsonResource<\/span> <\/span>{\n    <span class=\"hljs-comment\">\/\/ Validates the request from the user<\/span>\n    <span class=\"hljs-comment\">\/\/ If the validation failed, throw a ValidationException and inform the user.\t<\/span>\n    $data = <span class=\"hljs-keyword\">$this<\/span>-&gt;validate($request, &#91;\n        <span class=\"hljs-string\">'watermark'<\/span> =&gt; &#91;\n            <span class=\"hljs-string\">'required'<\/span>,\n            <span class=\"hljs-string\">'image'<\/span>,\n            <span class=\"hljs-string\">'mimes:png'<\/span>,\n        ],\n        <span class=\"hljs-string\">'public_id'<\/span> =&gt; &#91;\n            <span class=\"hljs-string\">'required'<\/span>,\n            <span class=\"hljs-string\">'string'<\/span>\n        ]\n    ]);\n\t\n\t<span class=\"hljs-comment\">\/\/ If there are no validation errors, proceed and upload the watermark to Cloudinary and return a Json response to the user.\t\t<\/span>\n    $watermark = $data&#91;<span class=\"hljs-string\">'watermark'<\/span>];\n    $public_id = $data&#91;<span class=\"hljs-string\">'public_id'<\/span>];\n    cloudinary()-&gt;upload($watermark-&gt;getRealPath(), &#91;\n        <span class=\"hljs-string\">'folder'<\/span>    =&gt; <span class=\"hljs-string\">'watermark-api'<\/span>,\n        <span class=\"hljs-string\">'public_id'<\/span> =&gt; $public_id\n    ])-&gt;getSecurePath();\n    \n    <span class=\"hljs-keyword\">return<\/span> JsonResource::make(&#91;\n        <span class=\"hljs-string\">'message'<\/span>   =&gt; <span class=\"hljs-string\">\"Watermark created successfully\"<\/span>,\n        <span class=\"hljs-string\">'watermark'<\/span> =&gt; &#91;<span class=\"hljs-string\">'public_id'<\/span> =&gt; $public_id]\n    ]);\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<ol start=\"3\">\n<li>Now we can link this in the routes file. Open your <code>routes\/api.php<\/code> and add the following code:<\/li>\n<\/ol>\n<p><code>Route::post('watermark\/upload', [WatermarkController::class, 'upload']);<\/code><\/p>\n<p><strong>Testing:<\/strong> You can test the route using Postman or Insomnia. Below is an example of a successful and failed response:<\/p>\n<figure class=\"table-wrapper\"><table>\n<thead>\n<tr>\n<th><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/dgrpkngjn\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/v1655895878\/watermark-api\/assets\/api_successful_response.png\" alt=\"Successful API Response\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1012\" height=\"386\"\/><\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Successful API Response<\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/figure>\n<figure class=\"table-wrapper\"><table>\n<thead>\n<tr>\n<th><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/dgrpkngjn\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/v1655895361\/watermark-api\/assets\/api_failed_response.png\" alt=\"Failed API Response\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"887\" height=\"427\"\/><\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Failed API Response<\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/figure>\n<p>Awesome, moving on nicely.<\/p>\n<h2>Creating the Overlay or Branding Endpoint<\/h2>\n<p>By now you know how to create an endpoint, this should be a breeze. We will use the same <code>WatermarkController<\/code> but create a new method for this endpoint.<\/p>\n<p>Similar to the previous endpoint this one will also take two inputs:<\/p>\n<ol>\n<li>\n<code>media<\/code> &#8211; This is a required image\/video input. It is the media file that we want to be branded with our cool watermark, which we created earlier.<\/li>\n<li>\n<code>public_id<\/code> &#8211; This is the public id of the watermark we passed to the previous endpoint. This needs to be exactly the same as the one we provided previously.<\/li>\n<\/ol>\n<p>In our WatermarkController add the following method:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">create<\/span><span class=\"hljs-params\">(Request $request)<\/span>: <span class=\"hljs-title\">JsonResource<\/span> <\/span>{\n\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>We will populate the create method above with the following code:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">create<\/span><span class=\"hljs-params\">(Request $request)<\/span>: <span class=\"hljs-title\">JsonResource<\/span> <\/span>{\n  <span class=\"hljs-comment\">\/\/ Validation<\/span>\n    $data = <span class=\"hljs-keyword\">$this<\/span>-&gt;validate($request, &#91;\n        <span class=\"hljs-string\">'media'<\/span>     =&gt; &#91;<span class=\"hljs-string\">'required'<\/span>, <span class=\"hljs-string\">'image'<\/span>, <span class=\"hljs-string\">'max:1024'<\/span>],\n        <span class=\"hljs-string\">'public_id'<\/span> =&gt; &#91;\n            <span class=\"hljs-string\">'required'<\/span>,\n            <span class=\"hljs-string\">'string'<\/span>\n        ]\n    ]);\n\t\n    <span class=\"hljs-comment\">\/\/ Uploading image to Cloudinary with transformation parameters that will overlay our watermark on our image\t\t<\/span>\n    $media = $data&#91;<span class=\"hljs-string\">'media'<\/span>];\n    $public_id = $data&#91;<span class=\"hljs-string\">'public_id'<\/span>];\n    $branded = cloudinary()-&gt;upload($media-&gt;getRealPath(), &#91;\n        <span class=\"hljs-string\">'folder'<\/span>         =&gt; <span class=\"hljs-string\">'watermark-api'<\/span>,\n        <span class=\"hljs-string\">'transformation'<\/span> =&gt; &#91;\n            <span class=\"hljs-string\">'overlay'<\/span> =&gt; $public_id,\n            <span class=\"hljs-string\">'gravity'<\/span> =&gt; <span class=\"hljs-string\">'south_east'<\/span>, <span class=\"hljs-comment\">\/\/ watermark location bottom right<\/span>\n            <span class=\"hljs-string\">'x'<\/span>       =&gt; <span class=\"hljs-number\">0.02<\/span>, <span class=\"hljs-comment\">\/\/ 2 percent offset horizontally<\/span>\n            <span class=\"hljs-string\">'y'<\/span>       =&gt; <span class=\"hljs-number\">0.02<\/span>, <span class=\"hljs-comment\">\/\/ 2 percent offset vertically<\/span>\n            <span class=\"hljs-string\">'crop'<\/span>    =&gt; <span class=\"hljs-string\">'scale'<\/span>,\n        ],\n    ])-&gt;getSecurePath();\n\t\n    <span class=\"hljs-comment\">\/\/ We return a response to the user with the URL of the branded or watermarked image\t\t<\/span>\n    <span class=\"hljs-keyword\">return<\/span> JsonResource::make(&#91;\n        <span class=\"hljs-string\">'message'<\/span> =&gt; <span class=\"hljs-string\">\"Watermark created successfully\"<\/span>,\n        <span class=\"hljs-string\">'url'<\/span>     =&gt; $branded\n    ]);\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p><strong>Important:<\/strong> Take note of the following transformation that makes the magic happen. Please refer to this <a href=\"https:\/\/cloudinary.com\/documentation\/layers\">Cloudinary Layers documentation<\/a> to learn more about these transformation options and experiment with several other awesome features:<\/p>\n<ol>\n<li>\n<p><code>overlay<\/code> &#8211; This is the public id of the watermark we uploaded earlier. Please note that since we provided a <code>folder_name<\/code> when uploading the watermark. We will need to include the folder name in the <code>public_id<\/code> input we send to the server, otherwise, Cloudinary will look for the watermark in the root folder and not find it.<\/p>\n<\/li>\n<li>\n<p><code>gravity<\/code> &#8211; This is where the overlay will be placed. it can be center, north, south, east, and so on and so forth.<\/p>\n<\/li>\n<li>\n<p><code>x<\/code> and <code>y<\/code> offsets &#8211; These parameters accept either integer values representing the number of pixels to adjust the overlay position in the horizontal or vertical directions or decimal values representing a percentage-based offset relative to the containing image (e.g., 0.2 for an offset of 20%).<\/p>\n<\/li>\n<li>\n<p>Install Livewire Package by running the following command in your Laravel project:\n<code>composer require livewire\/livewire<\/code><\/p>\n<\/li>\n<\/ol>\n<p>If you followed along with this article keenly, you should be able to use an API client such as Postman or Insomnia to hit the endpoints to upload a watermark or create a watermarked\/branded image similar to the one below:<\/p>\n<figure class=\"table-wrapper\"><table>\n<thead>\n<tr>\n<th><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/dgrpkngjn\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/v1655904199\/watermark-api\/jnamglffdarl5pcyiujd.jpg\" alt=\"Cloudinary Watermarked Image\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1920\" height=\"1280\"\/><\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Photo by Justin  Brian: <a href=\"https:\/\/www.pexels.com\/photo\/city-landscape-beach-water-9833512\/\">https:\/\/www.pexels.com\/photo\/city-landscape-beach-water-9833512\/<\/a><\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/figure>\n<p><strong>Note:<\/strong> Cloudinary is super powerful for the management of your media assets in your project that will not only optimize your assets for visual quality but also cost savings in terms of performance, storage, and AI-powered transformations as well.<\/p>\n<h1>Excel with Cloudinary<\/h1>\n<p>Building an API is a whole technical process that requires you to think about the goals, architecture, testing, scaling, security, and more, but in this implementation, with Cloudinary we had fun building a very simple API.<\/p>\n<p>Cloudinary is your A to Z media management solution &#8211; upload, storage, administration, manipulation, optimization, and delivery.<\/p>\n<p><a href=\"https:\/\/cloudinary.com\/signup\">Get started<\/a> with Cloudinary in your Laravel projects for FREE!<\/p>\n<\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":41,"featured_media":27810,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[134,387,229,371],"class_list":["post-27809","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-guest-post","tag-laravel","tag-php","tag-under-review"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.6 (Yoast SEO v26.9) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Watermarking Images using Laravel &amp; Cloudinary<\/title>\n<meta name=\"description\" content=\"In this article, we\u2019ll explore the ways you can build a simple Cloudinary Watermark API using Laravel. The API will allow you to add a watermark to an image using Cloudinary&#039;s powerful transformational API. We\u2019ll be using Laravel 8, and all of the code is available for reference on GitHub.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/cloudinary.com\/blog\/guest_post\/watermarking-images-using-laravel-and-cloudinary\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Watermarking Images using Laravel &amp; Cloudinary\" \/>\n<meta property=\"og:description\" content=\"In this article, we\u2019ll explore the ways you can build a simple Cloudinary Watermark API using Laravel. The API will allow you to add a watermark to an image using Cloudinary&#039;s powerful transformational API. We\u2019ll be using Laravel 8, and all of the code is available for reference on GitHub.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/guest_post\/watermarking-images-using-laravel-and-cloudinary\/\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2022-06-28T09:45:38+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-02-19T23:52:59+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1681926204\/Web_Assets\/blog\/7395253613bde54649dfe1d422c6a322212003bc-2000x2000-1_278109d6fa\/7395253613bde54649dfe1d422c6a322212003bc-2000x2000-1_278109d6fa-jpg?_i=AA\" \/>\n\t<meta property=\"og:image:width\" content=\"2000\" \/>\n\t<meta property=\"og:image:height\" content=\"2000\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"NewsArticle\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/watermarking-images-using-laravel-and-cloudinary\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/watermarking-images-using-laravel-and-cloudinary\/\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"Watermarking Images using Laravel &amp; Cloudinary\",\"datePublished\":\"2022-06-28T09:45:38+00:00\",\"dateModified\":\"2025-02-19T23:52:59+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/watermarking-images-using-laravel-and-cloudinary\/\"},\"wordCount\":6,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/watermarking-images-using-laravel-and-cloudinary\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681926204\/Web_Assets\/blog\/7395253613bde54649dfe1d422c6a322212003bc-2000x2000-1_278109d6fa\/7395253613bde54649dfe1d422c6a322212003bc-2000x2000-1_278109d6fa.jpg?_i=AA\",\"keywords\":[\"Guest Post\",\"Laravel\",\"PHP\",\"Under Review\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2022\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/watermarking-images-using-laravel-and-cloudinary\/\",\"url\":\"https:\/\/cloudinary.com\/blog\/guest_post\/watermarking-images-using-laravel-and-cloudinary\/\",\"name\":\"Watermarking Images using Laravel &amp; Cloudinary\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/watermarking-images-using-laravel-and-cloudinary\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/watermarking-images-using-laravel-and-cloudinary\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681926204\/Web_Assets\/blog\/7395253613bde54649dfe1d422c6a322212003bc-2000x2000-1_278109d6fa\/7395253613bde54649dfe1d422c6a322212003bc-2000x2000-1_278109d6fa.jpg?_i=AA\",\"datePublished\":\"2022-06-28T09:45:38+00:00\",\"dateModified\":\"2025-02-19T23:52:59+00:00\",\"description\":\"In this article, we\u2019ll explore the ways you can build a simple Cloudinary Watermark API using Laravel. The API will allow you to add a watermark to an image using Cloudinary's powerful transformational API. We\u2019ll be using Laravel 8, and all of the code is available for reference on GitHub.\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/watermarking-images-using-laravel-and-cloudinary\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/guest_post\/watermarking-images-using-laravel-and-cloudinary\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/watermarking-images-using-laravel-and-cloudinary\/#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681926204\/Web_Assets\/blog\/7395253613bde54649dfe1d422c6a322212003bc-2000x2000-1_278109d6fa\/7395253613bde54649dfe1d422c6a322212003bc-2000x2000-1_278109d6fa.jpg?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681926204\/Web_Assets\/blog\/7395253613bde54649dfe1d422c6a322212003bc-2000x2000-1_278109d6fa\/7395253613bde54649dfe1d422c6a322212003bc-2000x2000-1_278109d6fa.jpg?_i=AA\",\"width\":2000,\"height\":2000},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/watermarking-images-using-laravel-and-cloudinary\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Watermarking Images using Laravel &amp; Cloudinary\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"name\":\"Cloudinary Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/cloudinary.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\",\"name\":\"Cloudinary Blog\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"width\":312,\"height\":60,\"caption\":\"Cloudinary Blog\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Watermarking Images using Laravel &amp; Cloudinary","description":"In this article, we\u2019ll explore the ways you can build a simple Cloudinary Watermark API using Laravel. The API will allow you to add a watermark to an image using Cloudinary's powerful transformational API. We\u2019ll be using Laravel 8, and all of the code is available for reference on GitHub.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/cloudinary.com\/blog\/guest_post\/watermarking-images-using-laravel-and-cloudinary\/","og_locale":"en_US","og_type":"article","og_title":"Watermarking Images using Laravel &amp; Cloudinary","og_description":"In this article, we\u2019ll explore the ways you can build a simple Cloudinary Watermark API using Laravel. The API will allow you to add a watermark to an image using Cloudinary's powerful transformational API. We\u2019ll be using Laravel 8, and all of the code is available for reference on GitHub.","og_url":"https:\/\/cloudinary.com\/blog\/guest_post\/watermarking-images-using-laravel-and-cloudinary\/","og_site_name":"Cloudinary Blog","article_published_time":"2022-06-28T09:45:38+00:00","article_modified_time":"2025-02-19T23:52:59+00:00","og_image":[{"width":2000,"height":2000,"url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1681926204\/Web_Assets\/blog\/7395253613bde54649dfe1d422c6a322212003bc-2000x2000-1_278109d6fa\/7395253613bde54649dfe1d422c6a322212003bc-2000x2000-1_278109d6fa-jpg?_i=AA","type":"image\/jpeg"}],"twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/watermarking-images-using-laravel-and-cloudinary\/#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/watermarking-images-using-laravel-and-cloudinary\/"},"author":{"name":"","@id":""},"headline":"Watermarking Images using Laravel &amp; Cloudinary","datePublished":"2022-06-28T09:45:38+00:00","dateModified":"2025-02-19T23:52:59+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/watermarking-images-using-laravel-and-cloudinary\/"},"wordCount":6,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/watermarking-images-using-laravel-and-cloudinary\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681926204\/Web_Assets\/blog\/7395253613bde54649dfe1d422c6a322212003bc-2000x2000-1_278109d6fa\/7395253613bde54649dfe1d422c6a322212003bc-2000x2000-1_278109d6fa.jpg?_i=AA","keywords":["Guest Post","Laravel","PHP","Under Review"],"inLanguage":"en-US","copyrightYear":"2022","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/watermarking-images-using-laravel-and-cloudinary\/","url":"https:\/\/cloudinary.com\/blog\/guest_post\/watermarking-images-using-laravel-and-cloudinary\/","name":"Watermarking Images using Laravel &amp; Cloudinary","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/watermarking-images-using-laravel-and-cloudinary\/#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/watermarking-images-using-laravel-and-cloudinary\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681926204\/Web_Assets\/blog\/7395253613bde54649dfe1d422c6a322212003bc-2000x2000-1_278109d6fa\/7395253613bde54649dfe1d422c6a322212003bc-2000x2000-1_278109d6fa.jpg?_i=AA","datePublished":"2022-06-28T09:45:38+00:00","dateModified":"2025-02-19T23:52:59+00:00","description":"In this article, we\u2019ll explore the ways you can build a simple Cloudinary Watermark API using Laravel. The API will allow you to add a watermark to an image using Cloudinary's powerful transformational API. We\u2019ll be using Laravel 8, and all of the code is available for reference on GitHub.","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/watermarking-images-using-laravel-and-cloudinary\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/guest_post\/watermarking-images-using-laravel-and-cloudinary\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/watermarking-images-using-laravel-and-cloudinary\/#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681926204\/Web_Assets\/blog\/7395253613bde54649dfe1d422c6a322212003bc-2000x2000-1_278109d6fa\/7395253613bde54649dfe1d422c6a322212003bc-2000x2000-1_278109d6fa.jpg?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681926204\/Web_Assets\/blog\/7395253613bde54649dfe1d422c6a322212003bc-2000x2000-1_278109d6fa\/7395253613bde54649dfe1d422c6a322212003bc-2000x2000-1_278109d6fa.jpg?_i=AA","width":2000,"height":2000},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/watermarking-images-using-laravel-and-cloudinary\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Watermarking Images using Laravel &amp; Cloudinary"}]},{"@type":"WebSite","@id":"https:\/\/cloudinary.com\/blog\/#website","url":"https:\/\/cloudinary.com\/blog\/","name":"Cloudinary Blog","description":"","publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/cloudinary.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/cloudinary.com\/blog\/#organization","name":"Cloudinary Blog","url":"https:\/\/cloudinary.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","width":312,"height":60,"caption":"Cloudinary Blog"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":""}]}},"jetpack_featured_media_url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681926204\/Web_Assets\/blog\/7395253613bde54649dfe1d422c6a322212003bc-2000x2000-1_278109d6fa\/7395253613bde54649dfe1d422c6a322212003bc-2000x2000-1_278109d6fa.jpg?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/27809","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/users\/41"}],"replies":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/comments?post=27809"}],"version-history":[{"count":1,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/27809\/revisions"}],"predecessor-version":[{"id":36884,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/27809\/revisions\/36884"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/27810"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=27809"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=27809"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=27809"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}