Adding and Removing Media Images Programmatically in Magento 2

This post will describe the process of adding and removing media images programmatically in Magento 2 using the Magento_Catalog module classes. Usually when developers need to programmatically add and remove product images, it requires a one-off script to be run. Therefore the code shown will reside in a single file that externally bootstraps the Magento 2 application

The code below has been tested as of Magento Open Source version 2.2.5 and will remove all existing gallery images from a product, then add a single image, assigning the image to the base, small_image and thumbnail.

There are a few requirements as pointed out in the code comments.

  • The document root of the Magento 2 application must be set to ROOT/pub.
  • The directory containing the images should be place within ROOT/pub/media.
  • The images are named identical to the SKU of the product which images need to be updated.
  • Ensure that [image_dir] is replaced by the name of the directory which contains the images.

Add a file within the ROOT/pub directory containing the code below and run the code either within the browser or via CLI. You can modify various aspects of the file (such as the glob’d image file types) to suit your needs.

<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

/*
 * Assumes doc root is set to ROOT/pub
 */
require_once dirname(__DIR__) . '/app/bootstrap.php';
$bootstrap = \Magento\Framework\App\Bootstrap::create(BP, $_SERVER);

class AssignImages extends \Magento\Framework\App\Http implements \Magento\Framework\AppInterface
{
    public function launch()
    {
        $state = $this->_objectManager->get('Magento\Framework\App\State');
        $state->setAreaCode('adminhtml');

        $galleryReadHandler = $this->_objectManager->create('Magento\Catalog\Model\Product\Gallery\ReadHandler');
        $imageProcessor = $this->_objectManager->create('Magento\Catalog\Model\Product\Gallery\Processor');
        $productGallery = $this->_objectManager->create('Magento\Catalog\Model\ResourceModel\Product\Gallery');

        /**
         * Assumed images are named [sku].[ext] and reside in ROOT/pub/media/[image_dir]
         */
        foreach (glob(__DIR__ . "/media/[image_dir]/*.{jpg,png,gif}", GLOB_BRACE) as $image) {
            $imageFileName = trim(pathinfo($image)['filename']);
            $sku = $imageFileName;
            try {
                $product = $this->_objectManager->create('Magento\Catalog\Model\Product')->loadByAttribute('sku', $sku);
                if ($product) {
                    $galleryReadHandler->execute($product);

                    // Unset existing images
                    $images = $product->getMediaGalleryImages();
                    foreach($images as $child) {
                        $productGallery->deleteGallery($child->getValueId());
                        $imageProcessor->removeImage($product, $child->getFile());
                    }

                    /**
                     * Add image. Image directory must be in ROOT/pub/media for addImageToMediaGallery() method to work
                     */
                    $product->addImageToMediaGallery('[image_dir]' . DIRECTORY_SEPARATOR . pathinfo($image)['basename'], array('image', 'small_image', 'thumbnail'), false, false);
                    $product->save();
                    echo "Added media image for {$sku}" . "\n";
                }
            } catch (\Exception $e) {
                echo $e->getMessage();
            }
        }
        return $this->_response;
    }

    public function catchException(\Magento\Framework\App\Bootstrap $bootstrap, \Exception $exception)
    {
        echo $exception->getMessage();
        return false;
    }
}

/** @var \Magento\Framework\App\Http $app */
$app = $bootstrap->createApplication('AssignImages');
$bootstrap->run($app);

Note: This article is based on Magento Open Source version 2.2.5.