# Magento 2: best practice to add/delete product Images programmatically?

I want to upload images to the existing products. The images are in import_dir. And they need to be added to the product that already exists in the catalog.

I could find only 2 ways how to do it.
1. "Bad practice" way - using product model \Magento\Catalog\Model\Product::addImageToMediaGallery

1. Copy the images from import_dir to pub/media/tmp
2. Add the images to the product
3. Save product


Code

    /* copy files from import_dir to pub/media/tmp */

/** @var \Magento\Catalog\Api\Data\ProductInterface $product */ /* Init media gallery */$mediaGalleryEntries = $product->getMediaGalleryEntries(); if (empty($mediaGalleryEntries) === true){
$product->setMediaGalleryEntries([]); } /* Add an image to the product's gallery */$product->addImageToMediaGallery(
$filePathFromTmpDir, [ "image", "small_image", "thumbnail", "swatch_image" ],$moveImage,
$disableImage ); /* Save */$this->_productRepository->save($product);  2. "Good practice" way - using API \Magento\Catalog\Api\ProductAttributeMediaGalleryManagementInterface::create 1. Create image content object via **\Magento\Framework\Api\Data\ImageContentInterfaceFactory** 2. Create image object via **\Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterfaceFactory** 3. Create an image via API  Code $imageContent = $this->_imageContentInterfaceFactory->create() ->setBase64EncodedData(base64_encode(file_get_contents($filePathImportDir)))
->setType($this->_mime->getMimeType($filePathImportDir))
->setName($file_name);$newImage = $this->_productAttributeMediaGalleryEntryInterfaceFactory->create() ->setMediaType(\Magento\Catalog\Model\Product\Attribute\Backend\Media\ImageEntryConverter::MEDIA_TYPE_CODE) ->setFile($filePathImportDir)
->setDisabled($disableImage) ->setContent($imageContent)
->setLabel('label');

$this->_productAttributeMediaGalleryManagement->create($product->getSku(), $newImage);  Concerns: • In 1 I'm getting an error, which is known issue Undefined index: media_type • In 2 is way too complicated and it should be the easier way Questions: • Is there "best practice" way to manage(add, remove, replace) product's images? • Maybe there is a way with \Magento\CatalogImportExport\Model\Import\Product ## 2 Answers It can be done using your second way, more or less like this: <?php namespace [vendor]\[moduleName]\Model\Adminhtml\Product\MediaGallery; use \Magento\Catalog\Model\Product\Gallery\EntryFactory; use \Magento\Catalog\Model\Product\Gallery\GalleryManagement; use \Magento\Framework\Api\ImageContentFactory; { /** * @var \Magento\Catalog\Model\Product\Gallery\EntryFactory */ private$mediaGalleryEntryFactory;

/**
* @var \Magento\Catalog\Model\Product\Gallery\GalleryManagement
*/
private $mediaGalleryManagement; /** * @var \Magento\Framework\Api\ImageContentFactory */ private$imageContentFactory;

/**
* @param \Magento\Catalog\Model\Product\Gallery\EntryFactory $mediaGalleryEntryFactory * @param \Magento\Catalog\Model\Product\Gallery\GalleryManagement$mediaGalleryManagement
* @param \Magento\Framework\Api\ImageContentFactory $imageContentFactory */ public function __construct ( EntryFactory$mediaGalleryEntryFactory,
GalleryManagement $mediaGalleryManagement, ImageContentFactory$imageContentFactory
)
{
$this->mediaGalleryEntryFactory =$mediaGalleryEntryFactory;
$this->mediaGalleryManagement =$mediaGalleryManagement;
$this->imageContentFactory =$imageContentFactory;
}

/**
* @param string $filePath * @param string$sku
*/
public function processMediaGalleryEntry($filePath,$sku)
{
$entry =$this->mediaGalleryEntryFactory->create();

$entry->setFile($filePath);
$entry->setMediaType('image');$entry->setDisabled(false);
$entry->setTypes(['thumbnail', 'image', 'small_image']);$imageContent = $this->imageContentFactory->create();$imageContent
->setType(mime_content_type($filePath)) ->setName('test') ->setBase64EncodedData(base64_encode(file_get_contents($filePath)));

$entry->setContent($imageContent);

$this->mediaGalleryManagement->create($sku, $entry); } }  $filePath should be an absolute path - maybe you can use constans BP.

• it's sad that there is no more good ways to solve it, cuz as @JakubIlczuk said - it's highly limited. About this \$entry->setMediaType('image'); line i'm not quite sure, cuz as far as i remember it caused me an error something like that it's need a type "png" or "jpg"(so in the end it should be "image/png"). But again, i'm not sure – Olga Zhe Jan 3 '17 at 6:33
• In magento 2.1.1 it is no causing such an error. – Bartosz Kubicki Jan 3 '17 at 7:24
• Neither method addresses remove or replace. Just an observation. – Rooster242 Sep 28 '17 at 5:41

after looking at the same things as You apparently I'm at exactly the same place, and can't find any better way then this 2. And this 2 are highly limited. In functional tests they are using simple product->save() thing which causes other problems (for me personally, url_key already exists error). Seems like only 2nd method can be used, however complicated and confusing it seems. But I wonder if in 2nd method you've found a way to set the uploaded images as thumbnail or small image?