1

On the products grid in the category view I need to display additional image for some products. When I have a gallery of product images:

$images = $product->getMediaGalleryImages();
foreach ($images as $item)
{
    //...
}

how to retrieve an image by its role in the gallery? For example, I'd like to get the image which is marked with the Thumbnail role (or with some other custom role).

Is there any way to do that?

enter image description here enter image description here

3 Answers 3

3

You can get products image by Type by following Code :

  $baseImage  = $product->getImage();
  $smallImage = $product->getSmallImage();
  $thumbnail  = $product->getThumbnail();

OR You can get types of gallery images of a product by following code:

  $existingMediaGalleryEntries = $product->getMediaGalleryEntries();

  foreach ($existingMediaGalleryEntries as $entry) {
      $entry->getTypes();
  }

OR If you have custom media role then :

  $customIcon = $product->getResource()->getAttribute('custom_media_attribute')->getFrontend()->getValue($product);
2
  • And what if I have a custom role (when I created a custom attribute with Input Type Media Image)? How to get image of custom role?
    – zitix
    Mar 21, 2018 at 13:18
  • @zitix See my updated answer. Mar 22, 2018 at 5:13
0

If you need to get image URL like on frontend then you can use this code. I'm not sure that is a best solution but it works for me.))

use Magento\Store\Model\App\Emulation;
use Magento\Catalog\Model\ResourceModel\Product as ProductResource;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Catalog\Helper\ImageFactory as ImageHelper;

...

public function __construct(
    StoreManagerInterface     $storeManager,        
    ProductResource           $productResource,
    Emulation                 $appEmulation,
    ImageHelper               $imageHelper,
)
{
    $this->storeManager = $storeManager;        
    $this->productResource = $productResource;
    $this->appEmulation = $appEmulation;
    $this->imageHelper = $imageHelper;
}

/**
 * @param $product
 * @param $imageCustomRole
 * @return string
 * @throws \Magento\Framework\Exception\LocalizedException
 * @throws \Magento\Framework\Exception\NoSuchEntityException
 */
public function getCustomRoleImageUrl($product, $imageCustomRole)
{
    //Start frontend emulation for avoiding wrong path
    $this->appEmulation->startEnvironmentEmulation($this->storeManager->getStore()->getId(), Area::AREA_FRONTEND, true);
    
    //getting image relative path if it is needed
    $img = $product->getResource()->getAttribute($imageCustomRole)->getFrontend()->getValue($product);

    $result = '';
 
    if($img) {
        $productImageAttr = $product->getCustomAttribute($imageCustomRole);
        $productImage = $this->imageHelper->create()->init($product, $imageCustomRole)
            ->setImageFile($productImageAttr->getValue());
        $result = $productImage->getUrl();
    }
    
    //Stop frontend emulation
    $this->appEmulation->stopEnvironmentEmulation();
  
    return $result;
}
0

On magento 2.4.6, the following code worked for me:

use Magento\Catalog\Model\Product\Gallery\Processor;
.....
/** @var Processor */
protected Processor $processor;
.....
public function __construct(
.....
Processor $processor,
.....
){
.....
$this->processor = $processor;
.....
}

public function myCustomFancyMethod($sku)
{
    $product = $this->productRepository->get($sku);
    $fullPath = $this->getMyImages();
    for ($i=0;$i < count($fullPath); $i++){
        $this->processor->addImage($product, $fullPath[$i], null, false, false);
    }

    $existingMediaGalleryEntries = $product->getMediaGalleryEntries();

    $i = 0;
        foreach ($existingMediaGalleryEntries as $entry) {
            $file = $entry->getFile();
            $product->setStoreId(0);
            if ($i === 0){
                $product->setImage($file);
                $product->setSmallImage($file)->setThumbnail($file);
            }
            $product->setData(
                'media_gallery',
                [
                    'images' => [
                        [
                            'file' => $file,
                            'position' => $i,
                            'label' => 'LabelName-'.$i,
                            'disabled' => 0,
                            'media_type' => 'image'
                        ],
                    ]
                ]
            )->setCanSaveCustomOptions(true);
            $product->save();

            $i++;
        }
}

This will set the thumbnail and base image for the first image iterated. Of course the method: $this->getMyImages(); , I will let you to get from whereever you want the image paths.

I hope my post helped someone!

Good luck !

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.