I come up with running below script on pub directory to achieve this task. This may help some one in future.
image_swap.php file
<?php
use \Magento\Framework\App\Bootstrap;
require __DIR__ . '/../app/bootstrap.php';
$params = $_SERVER;
$bootstrap = Bootstrap::create(BP, $params);
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$state = $objectManager->get('Magento\Framework\App\State');
$state->setAreaCode('frontend');
$productRepository = $objectManager->get('Magento\Catalog\Model\ProductRepository');
$csv = "sku_vs_image.csv";
if (!empty($argv) && sizeof($argv) > 1) {
$csv = $argv[1];
}
if (($handle = fopen($csv, "r")) !== FALSE) {
while (($data = fgetcsv($handle, 2000, "\t")) !== FALSE) {
$num = count($data);
if ($num < 1) {
continue;
}
$sku = explode(',',trim($data[0]));
$imagePath = $sku[1];
try {
$product = $productRepository->get($sku[0]);
$productId = $product->getId();
$productRepository = $objectManager->create('Magento\Catalog\Api\ProductRepositoryInterface');
$product->addImageToMediaGallery('catalog/product'.$imagePath, array('image', 'small_image', 'thumbnail'), false, false);
$product->save();
//Get existing image
$existingMediaGalleryEntries = $product->getMediaGalleryEntries();
foreach ($existingMediaGalleryEntries as $key => $entry) {
//Remove the duplicate image after assigning roles
if($entry->getFile() === $imagePath ){
unset($existingMediaGalleryEntries[$key]);
}
}
$product->setMediaGalleryEntries($existingMediaGalleryEntries);
$productRepository->save($product);
} catch (\Exception $e) {
echo $sku[0].$e->getMessage()."</br>";
continue;
}
}
fclose($handle);
}
sku_vs_image.csv file sample
sku_1,/1/6/16-02-08651_1.jpeg
sku_2,/1/6/16-02-05659_1.jpeg
sku_3,/1/6/16-02-08651_1_1.jpeg
Update the csv and run the script from root. script first update the image role and create the image, and remove the existing image which assigned the role after.