This is my observer:

public function execute(\Magento\Framework\Event\Observer $observer)
    $orderIds = $observer->getEvent()->getOrderIds();
    $order = $this->_orderRepositoryInterface->get($orderIds[0]);
    $items =$order->getAllVisibleItems();
    $productQuantity = array();
    $productPrice = array();
    $productName = array();
    $productIds = array();
    foreach($items as $item) {
        $productIds[]= $item->getProductId();
        $productName[]= $item->getSku(); 
        $productPrice[] = $item->getPrice();
        $productQuantity[]= floor($item->getQtyOrdered());

How can I get the product image and product URL from the item?


This way may not the best way to get a product image.

Inject \Magento\Catalog\Api\ProductRepositoryInterfaceFactory in the constructor.

protected $_productRepositoryFactory;

public function __construct(
 \Magento\Catalog\Api\ProductRepositoryInterfaceFactory $productRepositoryFactory
) {            
    $this->_productRepositoryFactory = $productRepositoryFactory;

We can get the image:

$product = $this->_productRepositoryFactory->create()
| improve this answer | |
  • your answer is right but what shoild i do if i have more than one product in cart how can i show more than one product image – Ramkishan Suthar Sep 20 '16 at 4:17
  • ok i got it @khoa. if i have more than one produc image. thanks alot – Ramkishan Suthar Sep 20 '16 at 4:22
  • This is not working. Value returned is some kind of string like this "/w/s/wsh10-orange_main.jpg" – Hoang Trinh Oct 17 '16 at 1:37
  • 2
    @piavgh it's the path to image: pub/media/catalog/product – Khoa TruongDinh Oct 17 '16 at 2:17
  • 1
    so how do i use /w/s/wsh10-orange_main.jpg in <img src="" /> attribute so i can load the actual image – Lachezar Raychev Nov 8 '17 at 11:06

If you need to return a product URL it should look like this:

//todo get product object $product 

$objectManager =\Magento\Framework\App\ObjectManager::getInstance();
$helperImport = $objectManager->get('\Magento\Catalog\Helper\Image');

$imageUrl = $helperImport->init($product, 'product_page_image_small')
                ->setImageFile($product->getSmallImage()) // image,small_image,thumbnail
echo $imageUrl;
| improve this answer | |
  • Best, simple answer – AKKAweb Aug 4 at 22:19
  • This answer is exactly what am I looking for. Thanks – huykon225 Oct 19 at 13:52

If you want the published/cache frontend URL of an image for a specific store view (like I did) this is working for me:

 * @var \Magento\Store\Model\App\Emulation
protected $appEmulation;

 * @var \Magento\Store\Model\StoreManagerInterface
protected $storeManager;

 * @var \Magento\Catalog\Api\ProductRepositoryInterfaceFactory
protected $productRepositoryFactory;

 * @var \Magento\Catalog\Helper\ImageFactory
protected $imageHelperFactory;

 * @param \Magento\Store\Model\StoreManagerInterface $storeManager
 * @param \Magento\Store\Model\App\Emulation $appEmulation
 * @param \Magento\Catalog\Api\ProductRepositoryInterfaceFactory $productRepositoryFactory
 * @param \Magento\Catalog\Helper\ImageFactory $helperFactory
public function __construct(
    \Magento\Store\Model\StoreManagerInterface $storeManager,
    \Magento\Store\Model\App\Emulation $appEmulation,
    \Magento\Catalog\Api\ProductRepositoryInterfaceFactory $productRepositoryFactory,
    \Magento\Catalog\Helper\ImageFactory $imageHelperFactory
    $this->storeManager = $storeManager;
    $this->appEmulation = $appEmulation;
    $this->productRepositoryFactory = $productRepositoryFactory;
    $this->imageHelperFactory = $imageHelperFactory;

Then, wherever you need to get the image frontend URL:

$sku = "my-sku";
// get the store ID from somewhere (maybe a specific store?)
$storeId = $this->storeManager->getStore()->getId();
// emulate the frontend environment
$this->appEmulation->startEnvironmentEmulation($storeId, \Magento\Framework\App\Area::AREA_FRONTEND, true);
// load the product however you want
$product = $this->productRepositoryFactory->create()->get($sku);
// now the image helper will get the correct URL with the frontend environment emulated
$imageUrl = $this->imageHelperFactory->create()
  ->init($product, 'product_thumbnail_image')->getUrl();
// end emulation

You can select other images types besides product_thumbnail_image: see magento/theme-frontend-luma/etc/view.xml for a list of available product images, or create your own in a view.xml file.

| improve this answer | |
  • 2
    WTF? that is just sick :D – Lachezar Raychev Nov 2 '17 at 9:13
  • Just tried this solution and I'm not getting any errors, though the returned URL doesn't exist and the string is empty. I've tried with 'product_base_image', 'product_small_image' and 'product_thumbnail_image', none of which work. Can you advise please? Or is there an efficient way to do this using the product repository? As I am already loading that elsewhere in my block. – Joshua Flood Apr 24 '18 at 15:57

That's the way I did. it's quite efficient and clean:

1) First, you need to inject the following classes:

protected $_storeManager;
protected $_appEmulation;
protected $_blockFactory;

public function __construct(
    \Magento\Store\Model\StoreManagerInterface $storeManager,
    \Magento\Framework\View\Element\BlockFactory $blockFactory,
    \Magento\Store\Model\App\Emulation $appEmulation)
    $this->_storeManager = $storeManager;
    $this->_blockFactory = $blockFactory;
    $this->_appEmulation = $appEmulation;

2) Then, create a getImageUrl method with the code below:

protected function getImageUrl($product, string $imageType = '')
    $storeId = $this->_storeManager->getStore()->getId();

    $this->_appEmulation->startEnvironmentEmulation($storeId, \Magento\Framework\App\Area::AREA_FRONTEND, true);

    $imageBlock =  $this->_blockFactory->createBlock('Magento\Catalog\Block\Product\ListProduct');
    $productImage = $imageBlock->getImage($product, $imageType);
    $imageUrl = $productImage->getImageUrl();


    return $imageUrl;

Note: The "appEmulation" code is only necessary when you making this call from the admin or for an API. Otherwise, you will get the error below (or similar):

Unable to resolve the source file for 'webapi_rest/_view/en_AU/Magento_Catalog/images/product/placeholder/.jpg'

3) Call the getImageUrl passing the product object and the type of image you want (based on your view.xml file)

$smallImage = $this->getImageUrl($productObject, 'product_page_image_small');
| improve this answer | |

For gettting custom image url I used this code. So if the image does not exits it will load the default theme image.

$product = $block->getProduct();

$productImageAttr = $product->getCustomAttribute('product_banner_image');

if ($productImageAttr && $productImageAttr->getValue() != 'no_selection') {

    $productImage = $this->helper('Magento\Catalog\Helper\Image')
    ->init($product, 'product_banner_image')

    $imageUrl = $productImage->getUrl();

} else {

    $imageUrl = $this->getViewFileUrl('images/cat-img1.jpg'); // Theme/web/images

| improve this answer | |

You Can direct use this on .phtml

| improve this answer | |

My way works with watermarks and is same as magento using.


/** @var \Magento\Catalog\Block\Product\ImageBuilder */
private $imageBuilder;

Method returns string (placeholder):

private function getProductImageUrl(Product $product): string
    $image = $this->imageBuilder

    return $image->getImageUrl();

Method returns null or string:

private function getProductImageUrlOrNull(Product $product): ?string
    if (empty($product->getImage()) || $product->getImage() === SitemapResourceProduct::NOT_SELECTED_IMAGE) {
        return null;

    return $this->getProductImageUrl($product);
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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