{"id":36448,"date":"2025-01-15T07:00:00","date_gmt":"2025-01-15T15:00:00","guid":{"rendered":"https:\/\/cloudinary.com\/blog\/?p=36448"},"modified":"2025-04-16T13:13:57","modified_gmt":"2025-04-16T20:13:57","slug":"ai-image-workflows-php","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/ai-image-workflows-php","title":{"rendered":"AI Image Workflow with PHP and Cloudinary \u2013 From Upload to Delivery"},"content":{"rendered":"\n<p>When working on an e-commerce platform, handling image uploads and optimizing visual content can quickly become overwhelming. Cloudinary\u2019s robust platform not only simplifies these tasks but also adds AI-powered features to enhance your workflows. This blog post walks you through building a dynamic e-commerce demo with PHP and Cloudinary, focusing on client-side uploads, AI-driven alt text, and metadata management.<\/p>\n\n\n\n<p>Here&#8217;s a diagram of the image workflow implemented in the PHP Product Catalog app:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img width=\"1024\" height=\"110\" data-public-id=\"Web_Assets\/blog\/IMAGE-42_36543aa406\/IMAGE-42_36543aa406.png\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/w_1024,h_110,c_scale\/f_auto,q_auto\/v1736284419\/Web_Assets\/blog\/IMAGE-42_36543aa406\/IMAGE-42_36543aa406.png?_i=AA\" alt=\"\" class=\"wp-post-36448 wp-image-36543\" data-format=\"png\" data-transformations=\"f_auto,q_auto\" data-version=\"1736284419\" data-seo=\"1\" srcset=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1736284419\/Web_Assets\/blog\/IMAGE-42_36543aa406\/IMAGE-42_36543aa406.png?_i=AA 1528w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1736284419\/Web_Assets\/blog\/IMAGE-42_36543aa406\/IMAGE-42_36543aa406.png?_i=AA 300w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1736284419\/Web_Assets\/blog\/IMAGE-42_36543aa406\/IMAGE-42_36543aa406.png?_i=AA 768w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1736284419\/Web_Assets\/blog\/IMAGE-42_36543aa406\/IMAGE-42_36543aa406.png?_i=AA 1024w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>As you read, think about which aspects this AI image workflows with PHP and Cloudinary might best suit your own app as we explore how it integrates seamlessly into this Product Catalog demo app.<\/p>\n\n\n<div class='c-callout  c-callout--inline-title c-callout--note'><strong class='c-callout__title'>Note:<\/strong> <p>If you\u2019re also interested in video workflows, be sure to check out the <a href=\"https:\/\/cloudinary.com\/blog\/ai-video-workflows-with-php-and-cloudinary-from-upload-to-delivery\">next post<\/a> in this series, where we\u2019ll dive into optimizing video uploads, including asynchronous processes and AI-driven moderation.<\/p>\n<\/div>\n\n\n<h2 class=\"wp-block-heading\"><strong>E-commerce Demo Overview<\/strong><\/h2>\n\n\n\n<p>The PHP Product Catalog app showcases a simulated product catalog with products stored in a database. Each product includes a name, metadata (SKU, price, and category), auto-generated description, image, and video. For details on the video upload-to-delivery workflow, check out the next post in this series.<\/p>\n\n\n\n<p>With this app, you can:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Add new products with images.<\/li>\n\n\n\n<li>View all products or individual product details.<\/li>\n\n\n\n<li>Edit product metadata and media.<\/li>\n<\/ul>\n\n\n\n<p>See the app&#8217;s image features in action:<\/p>\n\n\n<cld-video-player\n      cloud-name='cloudinary'\n      public-id='training\/php_product_catalog_image'\n      js-config='{\"playbackRates\":[0.5,1,1.5,2]}'\n      style='max-width: 700px;'\n      class='c-video-player'\n      poster-timestamp='149'\n      core-version='2.12.3'\n      player-version='1.7.0'\n      >\n      <video\n        id='_video-player69e02f84afdc7'\n        data-cld-big-play-button='init'\n        data-cld-source-types='[\"webm\\\/vp9\",\"mp4\\\/h265\",\"mp4\"]'\n        controls\n        muted\n        class='cld-video-player cld-fluid wp-block-cloudinary-video-player  cld-video-player-skin-dark'\n      ><\/video>\n    <\/cld-video-player>\n\n\n<h2 class=\"wp-block-heading\"><strong>Get Started<\/strong><\/h2>\n\n\n\n<p>To follow along with this post, make sure you:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><a href=\"https:\/\/cloudinary.com\/users\/register_free\">Sign up for a Cloudinary account and try it for free!<\/a><\/li>\n\n\n\n<li>Find the full code for this app on <a href=\"https:\/\/github.com\/cloudinary-devs\/php-product-catalog\">GitHub<\/a> and follow the README for setup instructions.<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Client-Side Image Upload<\/strong><\/h2>\n\n\n\n<p>Cloudinary\u2019s <a href=\"https:\/\/cloudinary.com\/documentation\/upload_widget\">Upload widget<\/a> streamlines image uploads directly from the browser, allowing users to upload images effortlessly.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Integrating the Upload Widget<\/h4>\n\n\n\n<ul start=\"1\" class=\"wp-block-list\">\n<li>Add the Upload widget script to your HTML:<\/li>\n<\/ul>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\"><span class=\"hljs-comment\">&lt;!-- Include the Cloudinary Upload Widget library --&gt;<\/span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">script<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\"https:\/\/upload-widget.cloudinary.com\/global\/all.js\"<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">script<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<ul class=\"wp-block-list\">\n<li>Create a button to trigger the widget and include the JavaScript logic, and hidden inputs to received the data:<\/li>\n<\/ul>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">style<\/span>=<span class=\"hljs-string\">\"display:flex;margin-bottom:10px;\"<\/span>&gt;<\/span>\n     <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span> <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"button\"<\/span> <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"upload_image_button\"<\/span>&gt;<\/span>Upload Image<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>\n     <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">input<\/span> <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"hidden\"<\/span> <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"image_url\"<\/span> <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"image_url\"<\/span>&gt;<\/span>\n     <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">input<\/span> <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"hidden\"<\/span> <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"image_id\"<\/span> <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"image_id\"<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<ul class=\"wp-block-list\">\n<li>Javascript logic:\n<ul class=\"wp-block-list\">\n<li>Specify the <code>cloudName<\/code> of your product environment (found on your <a href=\"https:\/\/console.cloudinary.com\/pm\/developer-dashboard\">Cloudinary dashboard<\/a>).<\/li>\n\n\n\n<li>Specify an unsigned <a href=\"https:\/\/cloudinary.com\/documentation\/upload_presets\">upload preset<\/a> \u2014 a collection of predefined settings applied during uploads \u2014 configured in your environment. (We&#8217;ll take a closer look at our <code>php_demo_preset<\/code>upload preset in the next section.)<\/li>\n\n\n\n<li>Display a preview of the uploaded image, enhancing user experience.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">script<\/span>&gt;<\/span><span class=\"javascript\">\n    <span class=\"hljs-comment\">\/\/ Configure the upload widget for images<\/span>\n    <span class=\"hljs-keyword\">const<\/span> imageWidget = cloudinary.createUploadWidget({\n        <span class=\"hljs-attr\">cloudName<\/span>: <span class=\"hljs-string\">'&lt;?php echo $_ENV&#91;'<\/span>CLOUDINARY_CLOUD_NAME<span class=\"hljs-string\">']; ?&gt;'<\/span>, <span class=\"hljs-comment\">\/\/ Replace with your Cloudinary cloud name<\/span>\n        <span class=\"hljs-attr\">uploadPreset<\/span>: <span class=\"hljs-string\">'php_demo_preset'<\/span>, <span class=\"hljs-comment\">\/\/ Replace with your upload preset<\/span>\n        <span class=\"hljs-attr\">sources<\/span>: &#91;<span class=\"hljs-string\">'local'<\/span>, <span class=\"hljs-string\">'url'<\/span>], <span class=\"hljs-comment\">\/\/ Allow uploads from local files and URLs<\/span>\n        <span class=\"hljs-attr\">resourceType<\/span>: <span class=\"hljs-string\">'image'<\/span>, <span class=\"hljs-comment\">\/\/ Specify resource type as image<\/span>\n        <span class=\"hljs-attr\">maxFileSize<\/span>: <span class=\"hljs-number\">5000000<\/span>, <span class=\"hljs-comment\">\/\/ Set a max file size (optional)<\/span>\n        <span class=\"hljs-attr\">folder<\/span>: <span class=\"hljs-string\">'products\/images'<\/span>, <span class=\"hljs-comment\">\/\/ Optional folder path<\/span>\n    }, (error, result) =&gt; {\n        <span class=\"hljs-keyword\">if<\/span> (!error &amp;&amp; result &amp;&amp; result.event === <span class=\"hljs-string\">\"success\"<\/span>) {\n            <span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">'Image uploaded successfully:'<\/span>, result.info.secure_url);\n            <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">'image_url'<\/span>).value = result.info.secure_url;\n            <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">'image_id'<\/span>).value = result.info.public_id;\n            <span class=\"hljs-comment\">\/\/ Display the image preview<\/span>\n            <span class=\"hljs-keyword\">const<\/span> imageSection = <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">\"image_section\"<\/span>);\n            imageSection.innerHTML = <span class=\"hljs-string\">`\n                &lt;label&gt;Image:&lt;\/label&gt;\n                &lt;div&gt;\n                    &lt;img src=\"<span class=\"hljs-subst\">${result.info.secure_url}<\/span>\" alt=\"New Product Image\" style=\"max-width: 200px; height: auto; margin-bottom: 15px;\"&gt;\n                &lt;\/div&gt;\n            `<\/span>;\n        }\n    });\n    <span class=\"hljs-comment\">\/\/ Open the image upload widget<\/span>\n    <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">'upload_image_button'<\/span>).addEventListener(<span class=\"hljs-string\">'click'<\/span>, () =&gt; {\n        imageWidget.open();\n    });\n<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">script<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\"><strong>AI-Generated Alt Text<\/strong><\/h2>\n\n\n\n<p>Alt text enhances both accessibility and SEO, making your website more inclusive and discoverable by search engines. With <a href=\"https:\/\/cloudinary.com\/documentation\/cloudinary_ai_content_analysis_addon\">Cloudinary&#8217;s AI Content Analysis<\/a> add-on, you can automatically generate descriptive alt text for uploaded images.  <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Setting Up the AI Content Analysis Add-on<\/h3>\n\n\n\n<p>To enable this feature with the Upload widget, configure a preset to include the AI Content Analysis add-on. For example, when creating an upload preset (e.g., <code>php_demo_preset<\/code>), add <code>\"detection\" =&gt; \"captioning\"<\/code> to the preset settings. This activates the add-on for all uploads using this preset. In our app, the script to configure the <code>php_demo_preset<\/code> is triggered when clicking the first-time setup button from the main page or the app.<\/p>\n\n\n\n<p>Here\u2019s the code to create the upload preset:<\/p>\n\n\n<pre class=\"wp-block-code\" 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\">try<\/span> {\n    <span class=\"hljs-comment\">\/\/ Create upload preset if it doesn't yet exist.<\/span>\n    $result = $api\n    -&gt;createUploadPreset(&#91;\n        <span class=\"hljs-string\">\"name\"<\/span> =&gt; <span class=\"hljs-string\">\"php_demo_preset\"<\/span>, \n        <span class=\"hljs-string\">\"unsigned\"<\/span> =&gt; <span class=\"hljs-keyword\">true<\/span>, \n        <span class=\"hljs-string\">\"tags\"<\/span> =&gt; <span class=\"hljs-string\">\"php_demo\"<\/span>,\n        <span class=\"hljs-string\">\"detection\"<\/span> =&gt; <span class=\"hljs-string\">\"captioning\"<\/span>\n    ]);\n} <span class=\"hljs-keyword\">catch<\/span> (ApiError $e) {\n    <span class=\"hljs-keyword\">echo<\/span> <span class=\"hljs-string\">'API Error : '<\/span> . $e-&gt;getMessage();\n} <span class=\"hljs-keyword\">catch<\/span> (<span class=\"hljs-keyword\">Exception<\/span> $e) {\n    <span class=\"hljs-keyword\">echo<\/span> <span class=\"hljs-string\">'Error: '<\/span> . $e-&gt;getMessage();\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\n\n<h2 class=\"wp-block-heading\"><strong>Metadata Updates and Alt Text Capture<\/strong><\/h2>\n\n\n\n<p>Structured metadata enhances asset management, allowing quick searches, categorization, and handling by attributes like SKU or license restrictions. In the PHP Product Catalog app, metadata is added to each image.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>First, when you click the first-time setup button, the app creates your metadata fields (<strong>Description<\/strong>, <strong>Price<\/strong>, <strong>SKU<\/strong>, and <strong>Category<\/strong>), if they don&#8217;t already exist in your app. Save the external IDs for all these fields in an array for later use.<\/li>\n<\/ul>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\">$allFieldsResponse = $api-&gt;listMetadataFields();\n$allFields = $allFieldsResponse&#91;<span class=\"hljs-string\">'metadata_fields'<\/span>] ?? &#91;];\n\n$externalIds=&#91;];\n$exists=<span class=\"hljs-keyword\">false<\/span>;\n<span class=\"hljs-keyword\">try<\/span> {\n    $newLabel = <span class=\"hljs-string\">\"Description\"<\/span>;\n    <span class=\"hljs-comment\">\/\/ Check if the field already exists. If so, save its external_id in an array.<\/span>\n    $exists = checkAndAppendExternalId($allFields, $newLabel, $externalIds);\n\n    <span class=\"hljs-comment\">\/\/ If the field doesn't exist, create it. Save its external_id in an array.<\/span>\n    <span class=\"hljs-keyword\">if<\/span> (!$exists) {\n        <span class=\"hljs-comment\">\/\/ Prepare and add a \"String\" metadata field (e.g., Description)<\/span>\n        $stringMetadataField = <span class=\"hljs-keyword\">new<\/span> StringMetadataField($noExternalId);\n        $stringMetadataField-&gt;setLabel($newLabel);\n        $stringMetadataField-&gt;setMandatory(<span class=\"hljs-keyword\">true<\/span>); <span class=\"hljs-comment\">\/\/ Makes this field required<\/span>\n        $stringMetadataField-&gt;setDefaultValue(<span class=\"hljs-string\">'Product description'<\/span>); <span class=\"hljs-comment\">\/\/ Sets a default value<\/span>\n        $newField = $api-&gt;addMetadataField($stringMetadataField);\n        $externalIds&#91;] = &#91;$newLabel =&gt; $newField&#91;<span class=\"hljs-string\">'external_id'<\/span>]]; <span class=\"hljs-comment\">\/\/ Append key-value pair<\/span>\n        <span class=\"hljs-keyword\">echo<\/span> <span class=\"hljs-string\">\"String metadata field added successfully.\\n\"<\/span>;\n    }<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><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\n\n<ul class=\"wp-block-list\">\n<li>Then, when submitting a product, the app adds user-provided metadata to <a href=\"https:\/\/cloudinary.com\/products\/image\">Cloudinary image<\/a>, using the <a href=\"https:\/\/cloudinary.com\/documentation\/image_upload_api_reference#explicit\">explicit<\/a> method. Capture the generated alt text and metadata from the response:<\/li>\n<\/ul>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\">&lt;code&gt;$cloudinary_result = $cld-&gt;uploadApi()-&gt;explicit($image_public_id, &#91;<span class=\"hljs-string\">\"type\"<\/span>=&gt;<span class=\"hljs-string\">\"upload\"<\/span>,<span class=\"hljs-string\">\"metadata\"<\/span> =&gt; $metadata]);&lt;\/code&gt;\n$image_caption = $cloudinary_result&#91;<span class=\"hljs-string\">'info'<\/span>]&#91;<span class=\"hljs-string\">'detection'<\/span>]&#91;<span class=\"hljs-string\">'captioning'<\/span>]&#91;<span class=\"hljs-string\">'data'<\/span>]&#91;<span class=\"hljs-string\">'caption'<\/span>] ?? <span class=\"hljs-keyword\">null<\/span>; <span class=\"hljs-comment\">\/\/ Save the image alt text from the response<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><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\n\n<p>Here&#8217;s the full code snippet:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\"><span class=\"hljs-keyword\">if<\/span> ($_SERVER&#91;<span class=\"hljs-string\">'REQUEST_METHOD'<\/span>] == <span class=\"hljs-string\">'POST'<\/span>) {\n    <span class=\"hljs-comment\">\/\/ Capture metadata values entered in the form.<\/span>\n    $description = $_POST&#91;<span class=\"hljs-string\">'description'<\/span>];\n    $name = $_POST&#91;<span class=\"hljs-string\">'name'<\/span>];\n    $sku = $_POST&#91;<span class=\"hljs-string\">'sku'<\/span>];\n    $price = $_POST&#91;<span class=\"hljs-string\">'price'<\/span>];\n    $category = $_POST&#91;<span class=\"hljs-string\">'category'<\/span>];\n\n    <span class=\"hljs-comment\">\/\/ Get external ids for metadata fields.<\/span>\n    $allFieldsResponse = $api-&gt;listMetadataFields();\n    $allFields = $allFieldsResponse&#91;<span class=\"hljs-string\">'metadata_fields'<\/span>] ?? &#91;];    \n    $externalIds=&#91;];\n    checkAndAppendExternalId($allFields, <span class=\"hljs-string\">\"Description\"<\/span>, $externalIds);\n    checkAndAppendExternalId($allFields, <span class=\"hljs-string\">\"SKU\"<\/span>, $externalIds);\n    checkAndAppendExternalId($allFields, <span class=\"hljs-string\">\"Price\"<\/span>, $externalIds);\n    checkAndAppendExternalId($allFields, <span class=\"hljs-string\">\"Category\"<\/span>, $externalIds);\n\n    <span class=\"hljs-comment\">\/\/ Set up metadata entries for submission to cloudinary<\/span>\n    $metadata = \n    $externalIds&#91;<span class=\"hljs-string\">'SKU'<\/span>] . <span class=\"hljs-string\">'='<\/span> . $sku . <span class=\"hljs-string\">'|'<\/span> .\n    $externalIds&#91;<span class=\"hljs-string\">'Category'<\/span>] . <span class=\"hljs-string\">'=&#91;\"'<\/span> . $category . <span class=\"hljs-string\">'\"]|'<\/span> .\n    $externalIds&#91;<span class=\"hljs-string\">'Price'<\/span>] . <span class=\"hljs-string\">'='<\/span> . $price . <span class=\"hljs-string\">'|'<\/span> .\n    $externalIds&#91;<span class=\"hljs-string\">'Description'<\/span>] . <span class=\"hljs-string\">'='<\/span> . $description;\n    \n    <span class=\"hljs-keyword\">if<\/span> (!<span class=\"hljs-keyword\">empty<\/span>($_POST&#91;<span class=\"hljs-string\">'image_url'<\/span>])) {\n        $product_image_url = $_POST&#91;<span class=\"hljs-string\">'image_url'<\/span>]; <span class=\"hljs-comment\">\/\/ Retrieve the secure URL from the form submission<\/span>\n        $image_public_id = $_POST&#91;<span class=\"hljs-string\">'image_id'<\/span>]; <span class=\"hljs-comment\">\/\/ Retrieve the public ID from the form submission<\/span>\n        <span class=\"hljs-comment\">\/\/ Update metadata<\/span>\n        $cloudinary_result = $cld-&gt;uploadApi()-&gt;explicit($image_public_id, &#91;<span class=\"hljs-string\">\"type\"<\/span>=&gt;<span class=\"hljs-string\">\"upload\"<\/span>,<span class=\"hljs-string\">\"metadata\"<\/span> =&gt; $metadata]);\n        $image_caption = $cloudinary_result&#91;<span class=\"hljs-string\">'info'<\/span>]&#91;<span class=\"hljs-string\">'detection'<\/span>]&#91;<span class=\"hljs-string\">'captioning'<\/span>]&#91;<span class=\"hljs-string\">'data'<\/span>]&#91;<span class=\"hljs-string\">'caption'<\/span>] ?? <span class=\"hljs-keyword\">null<\/span>; <span class=\"hljs-comment\">\/\/ Save the image alt text from the response<\/span>\n    } <span class=\"hljs-keyword\">else<\/span> {\n        <span class=\"hljs-comment\">\/\/ If there's no image, set values to null.<\/span>\n        $product_image_url = <span class=\"hljs-keyword\">null<\/span>;\n        $image_public_id = <span class=\"hljs-keyword\">null<\/span>;\n        $image_caption = <span class=\"hljs-keyword\">null<\/span>;\n    }\n\n    <span class=\"hljs-comment\">\/\/ Save the values in the database.<\/span>\n    $product_id = saveProduct($pdo, $name, $product_image_url, $product_video_url, $image_public_id,  $video_public_id, $video_moderation_status, $image_caption, $video_public_id_temp);\n    header(<span class=\"hljs-string\">\"Location: products.php\"<\/span>);\n    <span class=\"hljs-keyword\">exit<\/span>;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><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\n\n<p>Here&#8217;s how the metadata and alt text look rendered on our product:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large is-resized\"><img width=\"988\" height=\"1024\" data-public-id=\"Web_Assets\/blog\/Screen-Shot-2024-12-22-at-20.19.55\/Screen-Shot-2024-12-22-at-20.19.55.png\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/w_988,h_1024,c_scale\/f_auto,q_auto\/v1734892829\/Web_Assets\/blog\/Screen-Shot-2024-12-22-at-20.19.55\/Screen-Shot-2024-12-22-at-20.19.55.png?_i=AA\" alt=\"\" class=\"wp-post-36448 wp-image-36495\" style=\"width:785px;height:auto\" data-format=\"png\" data-transformations=\"f_auto,q_auto\" data-version=\"1734892829\" data-seo=\"1\" srcset=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1734892829\/Web_Assets\/blog\/Screen-Shot-2024-12-22-at-20.19.55\/Screen-Shot-2024-12-22-at-20.19.55.png?_i=AA 1092w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1734892829\/Web_Assets\/blog\/Screen-Shot-2024-12-22-at-20.19.55\/Screen-Shot-2024-12-22-at-20.19.55.png?_i=AA 289w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1734892829\/Web_Assets\/blog\/Screen-Shot-2024-12-22-at-20.19.55\/Screen-Shot-2024-12-22-at-20.19.55.png?_i=AA 768w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1734892829\/Web_Assets\/blog\/Screen-Shot-2024-12-22-at-20.19.55\/Screen-Shot-2024-12-22-at-20.19.55.png?_i=AA 988w\" sizes=\"auto, (max-width: 988px) 100vw, 988px\" \/><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\"><strong>Database Integration<\/strong><\/h2>\n\n\n\n<p>When the product is submitted, store the image details in your database for seamless integration with your application\u2019s backend:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\">    <span class=\"hljs-comment\">\/\/ Save product information to the database<\/span>\n    $product_id = saveProduct(\n        $pdo, $name, $product_image_url, $product_video_url, \n        $image_public_id, $video_public_id, $video_moderation_status, \n        $image_caption, $video_public_id_temp\n    );\n    header(<span class=\"hljs-string\">\"Location: products.php\"<\/span>);\n    <span class=\"hljs-keyword\">exit<\/span>;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><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\n\n<p>In the <code>saveProduct<\/code> function, all relevant data \u2014 like <code>$image_url<\/code>, <code>$image_public_id<\/code>, and <code>$image_caption<\/code> (alt text) \u2014 are saved to the database for easy retrieval later on.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">saveProduct<\/span><span class=\"hljs-params\">(\n    $pdo, $name, $image_url, $video_url, $image_public_id, \n    $video_public_id, $video_moderation_status, $image_caption, $video_public_id_temp\n)<\/span> <\/span>{\n    $stmt = $pdo-&gt;prepare(\n        <span class=\"hljs-string\">\"INSERT INTO products (name, product_image_url, product_video_url, \n        image_public_id, video_public_id, video_moderation_status, image_caption, video_public_id_temp)\n        VALUES (:name, :product_image_url, :product_video_url, :image_public_id, \n        :video_public_id, :video_moderation_status, :image_caption, :video_public_id_temp)\"<\/span>\n    );\n    $stmt-&gt;execute(&#91;\n        <span class=\"hljs-string\">':name'<\/span> =&gt; $name,\n        <span class=\"hljs-string\">':product_image_url'<\/span> =&gt; $image_url,\n        <span class=\"hljs-string\">':product_video_url'<\/span> =&gt; $video_url,\n        <span class=\"hljs-string\">':image_public_id'<\/span> =&gt; $image_public_id,\n        <span class=\"hljs-string\">':video_public_id'<\/span> =&gt; $video_public_id,\n        <span class=\"hljs-string\">':video_moderation_status'<\/span> =&gt; $video_moderation_status,\n        <span class=\"hljs-string\">':image_caption'<\/span> =&gt; $image_caption,\n        <span class=\"hljs-string\">':video_public_id_temp'<\/span> =&gt; $video_public_id_temp\n    ]);\n    <span class=\"hljs-keyword\">return<\/span> $pdo-&gt;lastInsertId();\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><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\n\n<h2 class=\"wp-block-heading\"><strong>Dynamic Transformations<\/strong><\/h2>\n\n\n\n<p>So far, in our AI image workflows with PHP and Cloudinary, we\u2019ve uploaded an image, stored its metadata, generated alt text, and saved everything in Cloudinary with a database reference for easy access. Now, let\u2019s move to the next stage: delivering optimized and impactful images.<\/p>\n\n\n\n<p>Cloudinary\u2019s dynamic image transformations let you resize, crop, overlay logos, and more \u2014 all in real time. With AI-powered smart cropping, Cloudinary automatically adjusts focus to preserve essential details, even when resizing or cropping for different devices and formats.<\/p>\n\n\n\n<p>Here\u2019s an example from our PHP Product Catalog demo app. It showcases the original image alongside a smart-cropped version (500&#215;500, focused on key details) with an added overlay.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large is-resized\"><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/demo\/image\/upload\/ufdosggjndms4nn3zrif?_a=BAAAV6DQ\" alt=\"\" style=\"width:309px;height:auto\"\/><figcaption class=\"wp-element-caption\">Original Image<br>https:\/\/res.cloudinary.com\/demo\/image\/upload\/<br>ufdosggjndms4nn3zrif?_a=BAAAV6DQ<\/figcaption><\/figure><\/div>\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large is-resized\"><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/demo\/image\/upload\/c_fill,g_auto,h_700,w_700\/l_cloudinary_logo1\/c_scale,w_100\/fl_layer_apply,g_north_east,x_10,y_10\/ufdosggjndms4nn3zrif?_a=BAAAV6DQ\" alt=\"\" style=\"width:342px;height:auto\"\/><figcaption class=\"wp-element-caption\">Transformed image<br>https:\/\/res.cloudinary.com\/demo\/image\/upload\/<br>c_fill,g_auto,h_700,w_700\/<br>l_cloudinary_logo1\/c_scale,w_100\/<br>fl_layer_apply,g_north_east,x_10,y_10\/<br>ufdosggjndms4nn3zrif?_a=BAAAV6DQ<\/figcaption><\/figure><\/div>\n\n\n<p>These transformations highlight the flexibility of Cloudinary. Other possibilities include adjusting aspect ratios, applying filters, or using generative AI features like restoration and recoloring. Let\u2019s break down the steps to apply these transformations.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Retrieving the Public ID from the Database<\/strong><\/h3>\n\n\n\n<p>First, fetch the product data, including the image\u2019s public ID, from the database:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\"><span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">Cloudinary<\/span>\\<span class=\"hljs-title\">Api<\/span>\\<span class=\"hljs-title\">Upload<\/span>\\<span class=\"hljs-title\">UploadApi<\/span>;\n<span class=\"hljs-comment\">\/\/ Fetch all products from the database<\/span>\n$products = getAllProducts($pdo);\n<span class=\"hljs-meta\">&lt;?php<\/span> <span class=\"hljs-keyword\">foreach<\/span> ($products <span class=\"hljs-keyword\">as<\/span> $product): <span class=\"hljs-meta\">?&gt;<\/span>\n       <span class=\"hljs-meta\">&lt;?php<\/span>\n       <span class=\"hljs-comment\">\/\/ Process image and video URLs for each product<\/span>\n       <span class=\"hljs-keyword\">if<\/span> ($product&#91;<span class=\"hljs-string\">'image_public_id'<\/span>]) {<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><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\n\n<h3 class=\"wp-block-heading\"><strong>Resizing and Cropping<\/strong><\/h3>\n\n\n\n<p>Next, use the public ID to identify the current image, and use <code>Resize::fill()<\/code> to dynamically resize and crop it. Save the delivery URL to the modified image in the variable <code>$image_url<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\">           $image_url = $cld-&gt;image($product&#91;<span class=\"hljs-string\">'image_public_id'<\/span>])\n               -&gt;resize(\n                   Resize::fill()\n                       -&gt;width(<span class=\"hljs-number\">500<\/span>)\n                       -&gt;height(<span class=\"hljs-number\">500<\/span>)\n                       -&gt;gravity(Gravity::autoGravity())<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><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\n\n<p><strong>Explanation: <\/strong><code>Resize::fill()<\/code> resizes the image to 500&#215;500 pixels, and <code>Gravity::autoGravity()<\/code> ensures Cloudinary focuses on the most important area of the image, keeping the subject front and center.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Applying a watermark<\/strong><\/h3>\n\n\n\n<p>Add an overlay to product images, such as a logo, watermark, or promotional text. Here\u2019s how to overlay the Cloudinary logo:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-12\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\">               -&gt;overlay(\n                   Overlay::source(Source::image(<span class=\"hljs-string\">\"cloudinary_logo\"<\/span>)-&gt;resize(Resize::scale()-&gt;width(<span class=\"hljs-number\">50<\/span>)))\n                       -&gt;position(\n                           (<span class=\"hljs-keyword\">new<\/span> Position())\n                               -&gt;gravity(Gravity::compass(Compass::northEast()))\n                               -&gt;offsetX(<span class=\"hljs-number\">10<\/span>)\n                               -&gt;offsetY(<span class=\"hljs-number\">10<\/span>)\n                       )\n               )\n               -&gt;toUrl();\n      \n       } <span class=\"hljs-keyword\">else<\/span> {\n           $image_url = <span class=\"hljs-keyword\">null<\/span>;  <span class=\"hljs-comment\">\/\/ No image if not set<\/span>\n       }\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-12\"><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\n\n<p><strong>Explanation:<\/strong> This transformation overlays the Cloudinary logo (with the public ID <code>cloudinary_logo<\/code>), resized to 50px wide, positioned 10px from the top-right corner. You can replace the logo with another image or text overlay.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Deliver via Fast CDN<\/strong> and Render Data<\/h2>\n\n\n\n<p>Cloudinary automatically delivers your images through a fast CDN, boosting load times and enhancing performance. Further enhance the user experience with auto-generated alt text and metadata, which can be easily retrieved to enrich your application&#8217;s functionality.<\/p>\n\n\n\n<p>Here\u2019s the code snippet to fetch metadata from an image stored in Cloudinary:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-13\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ Get external ids for the Description metadata field in Cloudinary.<\/span>\n$allFieldsResponse = $api-&gt;listMetadataFields();\n$allFields = $allFieldsResponse&#91;<span class=\"hljs-string\">'metadata_fields'<\/span>] ?? &#91;];    \n$externalIds=&#91;];\ncheckAndAppendExternalId($allFields, <span class=\"hljs-string\">\"Description\"<\/span>, $externalIds);\n\n<span class=\"hljs-comment\">\/\/ Get metadata information from Cloudinary for the specific image.<\/span>\n$metadata_result = $api-&gt;asset($product&#91;<span class=\"hljs-string\">'image_public_id'<\/span>]);\n\n<span class=\"hljs-comment\">\/\/ Use the 'Description' external ID to pick out the 'Description' value for the image<\/span>\n$description = <span class=\"hljs-keyword\">isset<\/span>($externalIds&#91;<span class=\"hljs-string\">'Description'<\/span>]) &amp;&amp; <span class=\"hljs-keyword\">isset<\/span>($metadata_result&#91;<span class=\"hljs-string\">'metadata'<\/span>]&#91;$externalIds&#91;<span class=\"hljs-string\">'Description'<\/span>]]) \n? $metadata_result&#91;<span class=\"hljs-string\">'metadata'<\/span>]&#91;$externalIds&#91;<span class=\"hljs-string\">'Description'<\/span>]] \n: <span class=\"hljs-string\">'No description available'<\/span>;\n\n<span class=\"hljs-comment\">\/\/ Repeat for the other metadata fields.<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-13\"><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\n\n<p>Here&#8217;s the HTML to deliver the alt text, metadata. Use the delivery URL you just stored in the variable <code>$image_url<\/code> to render the resized, cropped, and watermarked version of the image:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-14\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">&lt;div <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span><\/span>=<span class=\"hljs-string\">\"product-card\"<\/span>&gt;\n            <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h2<\/span>&gt;<\/span><span class=\"php\"><span class=\"hljs-meta\">&lt;?php<\/span> <span class=\"hljs-keyword\">echo<\/span> htmlspecialchars($product&#91;<span class=\"hljs-string\">'name'<\/span>]); <span class=\"hljs-meta\">?&gt;<\/span><\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h2<\/span>&gt;<\/span><\/span>\n            <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n                <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span>Description: <span class=\"php\"><span class=\"hljs-meta\">&lt;?php<\/span> <span class=\"hljs-keyword\">echo<\/span> htmlspecialchars($description); <span class=\"hljs-meta\">?&gt;<\/span><\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n                <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span>SKU: <span class=\"php\"><span class=\"hljs-meta\">&lt;?php<\/span> <span class=\"hljs-keyword\">echo<\/span> htmlspecialchars($sku); <span class=\"hljs-meta\">?&gt;<\/span><\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n                <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span>Price: $<span class=\"php\"><span class=\"hljs-meta\">&lt;?php<\/span> <span class=\"hljs-keyword\">echo<\/span> htmlspecialchars($price); <span class=\"hljs-meta\">?&gt;<\/span><\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n                <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span>Category: <span class=\"php\"><span class=\"hljs-meta\">&lt;?php<\/span> <span class=\"hljs-keyword\">echo<\/span> htmlspecialchars($category_display); <span class=\"hljs-meta\">?&gt;<\/span><\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n            <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"product-image\"<\/span> <span class=\"hljs-attr\">style<\/span>=<span class=\"hljs-string\">\"position:relative;margin:10px auto;max-width:99%;border:1px solid grey;\"<\/span>&gt;<\/span>\n                <span class=\"hljs-comment\">&lt;!-- Display product image if available --&gt;<\/span>\n                <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n                    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">b<\/span>&gt;<\/span>Image<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">b<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n                <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n                <span class=\"php\"><span class=\"hljs-meta\">&lt;?php<\/span> <span class=\"hljs-keyword\">if<\/span> ($image_url): <span class=\"hljs-meta\">?&gt;<\/span><\/span>\n                    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"product-image\"<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\"&lt;?php echo $image_url; ?&gt;\"<\/span> <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">\"&lt;?php echo $product&#91;'image_caption']; ?&gt;\"<\/span>&gt;<\/span>\n                <span class=\"php\"><span class=\"hljs-meta\">&lt;?php<\/span> <span class=\"hljs-keyword\">else<\/span>: <span class=\"hljs-meta\">?&gt;<\/span><\/span>\n                    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span>No image available.<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n                <span class=\"php\"><span class=\"hljs-meta\">&lt;?php<\/span> <span class=\"hljs-keyword\">endif<\/span>; <span class=\"hljs-meta\">?&gt;<\/span><\/span>\n                <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"product-image\"<\/span> <span class=\"hljs-attr\">style<\/span>=<span class=\"hljs-string\">\"position:relative;max-width:230px;margin:0 auto;\"<\/span>&gt;<\/span>\n                    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">b<\/span>&gt;<\/span>Alt text:<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">b<\/span>&gt;<\/span> <span class=\"php\"><span class=\"hljs-meta\">&lt;?php<\/span> <span class=\"hljs-keyword\">echo<\/span> $product&#91;<span class=\"hljs-string\">'image_caption'<\/span>]; <span class=\"hljs-meta\">?&gt;<\/span><\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n                <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-14\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Here&#8217;s how the full product listing looks:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large is-resized\"><img width=\"654\" height=\"1024\" data-public-id=\"Web_Assets\/blog\/Screen-Shot-2024-12-22-at-20.38.20\/Screen-Shot-2024-12-22-at-20.38.20.png\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/w_654,h_1024,c_scale\/f_auto,q_auto\/v1734892824\/Web_Assets\/blog\/Screen-Shot-2024-12-22-at-20.38.20\/Screen-Shot-2024-12-22-at-20.38.20.png?_i=AA\" alt=\"\" class=\"wp-post-36448 wp-image-36497\" style=\"width:707px;height:auto\" data-format=\"png\" data-transformations=\"f_auto,q_auto\" data-version=\"1734892824\" data-seo=\"1\" srcset=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1734892824\/Web_Assets\/blog\/Screen-Shot-2024-12-22-at-20.38.20\/Screen-Shot-2024-12-22-at-20.38.20.png?_i=AA 700w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1734892824\/Web_Assets\/blog\/Screen-Shot-2024-12-22-at-20.38.20\/Screen-Shot-2024-12-22-at-20.38.20.png?_i=AA 192w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1734892824\/Web_Assets\/blog\/Screen-Shot-2024-12-22-at-20.38.20\/Screen-Shot-2024-12-22-at-20.38.20.png?_i=AA 654w\" sizes=\"auto, (max-width: 654px) 100vw, 654px\" \/><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\"><strong>Unlock the Power of Seamless Image Workflows with Cloudinary<\/strong><\/h2>\n\n\n\n<p>With Cloudinary&#8217;s robust suite of features, you can manage AI image workflows with PHP and Cloudinary, from upload to delivery. The ability to leverage AI for automation, apply dynamic transformations like smart cropping, and deliver optimized media through Cloudinary&#8217;s fast CDN can drastically enhance your app&#8217;s media experience.<\/p>\n\n\n\n<p>Now that you\u2019ve seen how Cloudinary streamlines the process for images, don\u2019t miss the next post in this series, where we&#8217;ll explore how to handle video uploads and moderation seamlessly within the same PHP product catalog app. Be sure to<a href=\"https:\/\/cloudinary.com\/users\/register_free\"> sign up for a free Cloudinary account<\/a> and start building powerful media workflows for your app today!<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>When working on an e-commerce platform, handling image uploads and optimizing visual content can quickly become overwhelming. Cloudinary\u2019s robust platform not only simplifies these tasks but also adds AI-powered features to enhance your workflows. This blog post walks you through building a dynamic e-commerce demo with PHP and Cloudinary, focusing on client-side uploads, AI-driven alt [&hellip;]<\/p>\n","protected":false},"author":52,"featured_media":36572,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[336,98,370],"class_list":["post-36448","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-ai","tag-e-commerce","tag-image"],"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>AI Image Workflows with PHP and Cloudinary - Upload to Delivery<\/title>\n<meta name=\"description\" content=\"Discover AI image workflows with PHP and Cloudinary for AI-driven captioning, metadata management, and dynamic transformations in your apps.\" \/>\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\/ai-image-workflows-php\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"AI Image Workflow with PHP and Cloudinary \u2013 From Upload to Delivery\" \/>\n<meta property=\"og:description\" content=\"Discover AI image workflows with PHP and Cloudinary for AI-driven captioning, metadata management, and dynamic transformations in your apps.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/ai-image-workflows-php\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2025-01-15T15:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-04-16T20:13:57+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1736808332\/AI_Image_Workflow_with_PHP_and_Cloudinary_From_Upload_to_Delivery\/AI_Image_Workflow_with_PHP_and_Cloudinary_From_Upload_to_Delivery-jpg?_i=AA\" \/>\n\t<meta property=\"og:image:width\" content=\"2000\" \/>\n\t<meta property=\"og:image:height\" content=\"1100\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"sharonyelenik\" \/>\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\/ai-image-workflows-php#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/ai-image-workflows-php\"},\"author\":{\"name\":\"sharonyelenik\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/dc4e70df8d22a9cfdad676a82fa92a73\"},\"headline\":\"AI Image Workflow with PHP and Cloudinary \u2013 From Upload to Delivery\",\"datePublished\":\"2025-01-15T15:00:00+00:00\",\"dateModified\":\"2025-04-16T20:13:57+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/ai-image-workflows-php\"},\"wordCount\":1177,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/ai-image-workflows-php#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1736808332\/AI_Image_Workflow_with_PHP_and_Cloudinary_From_Upload_to_Delivery\/AI_Image_Workflow_with_PHP_and_Cloudinary_From_Upload_to_Delivery.jpg?_i=AA\",\"keywords\":[\"AI\",\"E-commerce\",\"Image\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/ai-image-workflows-php\",\"url\":\"https:\/\/cloudinary.com\/blog\/ai-image-workflows-php\",\"name\":\"AI Image Workflows with PHP and Cloudinary - Upload to Delivery\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/ai-image-workflows-php#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/ai-image-workflows-php#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1736808332\/AI_Image_Workflow_with_PHP_and_Cloudinary_From_Upload_to_Delivery\/AI_Image_Workflow_with_PHP_and_Cloudinary_From_Upload_to_Delivery.jpg?_i=AA\",\"datePublished\":\"2025-01-15T15:00:00+00:00\",\"dateModified\":\"2025-04-16T20:13:57+00:00\",\"description\":\"Discover AI image workflows with PHP and Cloudinary for AI-driven captioning, metadata management, and dynamic transformations in your apps.\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/ai-image-workflows-php#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/ai-image-workflows-php\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/ai-image-workflows-php#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1736808332\/AI_Image_Workflow_with_PHP_and_Cloudinary_From_Upload_to_Delivery\/AI_Image_Workflow_with_PHP_and_Cloudinary_From_Upload_to_Delivery.jpg?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1736808332\/AI_Image_Workflow_with_PHP_and_Cloudinary_From_Upload_to_Delivery\/AI_Image_Workflow_with_PHP_and_Cloudinary_From_Upload_to_Delivery.jpg?_i=AA\",\"width\":2000,\"height\":1100},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/ai-image-workflows-php#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"AI Image Workflow with PHP and Cloudinary \u2013 From Upload to Delivery\"}]},{\"@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\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/dc4e70df8d22a9cfdad676a82fa92a73\",\"name\":\"sharonyelenik\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/6565cdd768a04e9b6ea3932764886209dd9de8baeeef1504eaad8fe776677f92?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/6565cdd768a04e9b6ea3932764886209dd9de8baeeef1504eaad8fe776677f92?s=96&d=mm&r=g\",\"caption\":\"sharonyelenik\"}}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"AI Image Workflows with PHP and Cloudinary - Upload to Delivery","description":"Discover AI image workflows with PHP and Cloudinary for AI-driven captioning, metadata management, and dynamic transformations in your apps.","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\/ai-image-workflows-php","og_locale":"en_US","og_type":"article","og_title":"AI Image Workflow with PHP and Cloudinary \u2013 From Upload to Delivery","og_description":"Discover AI image workflows with PHP and Cloudinary for AI-driven captioning, metadata management, and dynamic transformations in your apps.","og_url":"https:\/\/cloudinary.com\/blog\/ai-image-workflows-php","og_site_name":"Cloudinary Blog","article_published_time":"2025-01-15T15:00:00+00:00","article_modified_time":"2025-04-16T20:13:57+00:00","og_image":[{"width":2000,"height":1100,"url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1736808332\/AI_Image_Workflow_with_PHP_and_Cloudinary_From_Upload_to_Delivery\/AI_Image_Workflow_with_PHP_and_Cloudinary_From_Upload_to_Delivery-jpg?_i=AA","type":"image\/jpeg"}],"author":"sharonyelenik","twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/cloudinary.com\/blog\/ai-image-workflows-php#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/ai-image-workflows-php"},"author":{"name":"sharonyelenik","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/dc4e70df8d22a9cfdad676a82fa92a73"},"headline":"AI Image Workflow with PHP and Cloudinary \u2013 From Upload to Delivery","datePublished":"2025-01-15T15:00:00+00:00","dateModified":"2025-04-16T20:13:57+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/ai-image-workflows-php"},"wordCount":1177,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/ai-image-workflows-php#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1736808332\/AI_Image_Workflow_with_PHP_and_Cloudinary_From_Upload_to_Delivery\/AI_Image_Workflow_with_PHP_and_Cloudinary_From_Upload_to_Delivery.jpg?_i=AA","keywords":["AI","E-commerce","Image"],"inLanguage":"en-US","copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/ai-image-workflows-php","url":"https:\/\/cloudinary.com\/blog\/ai-image-workflows-php","name":"AI Image Workflows with PHP and Cloudinary - Upload to Delivery","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/ai-image-workflows-php#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/ai-image-workflows-php#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1736808332\/AI_Image_Workflow_with_PHP_and_Cloudinary_From_Upload_to_Delivery\/AI_Image_Workflow_with_PHP_and_Cloudinary_From_Upload_to_Delivery.jpg?_i=AA","datePublished":"2025-01-15T15:00:00+00:00","dateModified":"2025-04-16T20:13:57+00:00","description":"Discover AI image workflows with PHP and Cloudinary for AI-driven captioning, metadata management, and dynamic transformations in your apps.","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/ai-image-workflows-php#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/ai-image-workflows-php"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/ai-image-workflows-php#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1736808332\/AI_Image_Workflow_with_PHP_and_Cloudinary_From_Upload_to_Delivery\/AI_Image_Workflow_with_PHP_and_Cloudinary_From_Upload_to_Delivery.jpg?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1736808332\/AI_Image_Workflow_with_PHP_and_Cloudinary_From_Upload_to_Delivery\/AI_Image_Workflow_with_PHP_and_Cloudinary_From_Upload_to_Delivery.jpg?_i=AA","width":2000,"height":1100},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/ai-image-workflows-php#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"AI Image Workflow with PHP and Cloudinary \u2013 From Upload to Delivery"}]},{"@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":"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/dc4e70df8d22a9cfdad676a82fa92a73","name":"sharonyelenik","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/6565cdd768a04e9b6ea3932764886209dd9de8baeeef1504eaad8fe776677f92?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/6565cdd768a04e9b6ea3932764886209dd9de8baeeef1504eaad8fe776677f92?s=96&d=mm&r=g","caption":"sharonyelenik"}}]}},"jetpack_featured_media_url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1736808332\/AI_Image_Workflow_with_PHP_and_Cloudinary_From_Upload_to_Delivery\/AI_Image_Workflow_with_PHP_and_Cloudinary_From_Upload_to_Delivery.jpg?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/36448","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\/52"}],"replies":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/comments?post=36448"}],"version-history":[{"count":35,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/36448\/revisions"}],"predecessor-version":[{"id":37445,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/36448\/revisions\/37445"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/36572"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=36448"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=36448"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=36448"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}