Getting full image URL of product in template

I'm trying to create a static block for showing dynamic products. This is code that is supposed to get every child category and print the image for each product in each category.

<?php
    $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
    $category = $objectManager->get('Magento\Framework\Registry')->registry('current_category');
    ?><ol><?php
    foreach ($category->getChildrenCategories() as $child_category) {
        ?><li>
            <ul><?php
                foreach ($child_category->getProductCollection() as $product) {
                    ?><li><img src="<?php echo $product->getImage();?>"/><li><?php
                }
            ?></ul>
        </li><?php
    }
    ?></ol>

It is almost working except for the img srcs are only "/a/b/ab001.jpg" as an example and not the full path e.g. "/pub/media/catalog/product/cache/1/small_image/240x300/abc123def456/a/b/001.jpg" so the images cannot be found. What is the correct way of getting product images?

Solutions

If you need to resize the product image and use the default Magento image cache system and you are not in the frontend area, you can use this workaround.

Use case : It may be useful if you need image URLs resized on your custom API for an external application.

Function code :

/**
 * @var \Magento\Catalog\Model\ProductFactory
 */
protected $productFactory;

/**
 * @var \Magento\Catalog\Helper\ImageFactory
 */
protected $helperFactory;

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

/**
 * Constructor.
 *
 * @param \Magento\Catalog\Model\ProductFactory $productFactory
 * @param \Magento\Store\Model\App\Emulation $appEmulation
 * @param \Magento\Catalog\Helper\ImageFactory $helperFactory
 * @param \Magento\Store\Model\StoreManagerInterface $storeManager
 */
public function __construct(
    \Magento\Catalog\Model\ProductFactory $productFactory,
    \Magento\Store\Model\App\Emulation $appEmulation,
    \Magento\Catalog\Helper\ImageFactory $helperFactory,
    \Magento\Store\Model\StoreManagerInterface $storeManager,
) {
    $this->productFactory                   = $productFactory;
    $this->imageBuilder                     = $imageBuilder;
    $this->helperFactory                    = $helperFactory;
    $this->appEmulation                     = $appEmulation;
    $this->storeManager                     = $storeManager;
}

/**
 * Retrieve product image
 *
 * @param \Magento\Catalog\Model\Product $product
 * @param string $imageId
 * @param array $attributes
 * @return \Magento\Catalog\Block\Product\Image
 */
public function getImage($product, $imageId, $attributes = [])
{
    $image = $this->helperFactory->create()->init($product, $imageId)
        ->constrainOnly(true)
        ->keepAspectRatio(true)
        ->keepTransparency(true)
        ->keepFrame(false)
        ->resize(200, 300);

    return $image;
}

public function customFunction()
{
    // some stuff here

    $storeId = $this->storeManager->getStore()->getId();

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

    $product = $this->productFactory->create()->loadByAttribute('sku', 'productSKU');
    $imageUrl = $this->getImage($product, 'product_base_image')->getUrl();

    echo $imageUrl;

    $this->appEmulation->stopEnvironmentEmulation();

    // some stuff here
}

The output example :

http://{domain}/media/catalog/product/cache/1/image/200x300/e9c3970ab036de70892d86c6d221abfe/s/r/{imageName}.jpg

Comments :

The third parameter of the function startEnvironmentEmulation is used to force the use of frontend area if you are already on the same storeId. (usefull for API area)

This workaround avoid you to have this kind of errors :

http://XXXX.com/pub/static/webapi_rest/_view/en_US/Magento_Catalog/images/product/placeholder/.jpg

Uncaught Magento\Framework\View\Asset\File\NotFoundException: Unable to resolve the source file for 'adminhtml/_view/en_US/Magento_Catalog/images/product/placeh‌​older/.jpg'

If your block extends Magento\Catalog\Block\Product\AbstractProduct, you can use:

$imageType = 'category_page_list'; // choose which image
$image = $block->getImage($product, $imageType);

Then either get the image URL with

$image->getImageUrl();

or if you want to output it as <img> element:

echo $image->toHtml();

If your block does not / cannot extend the abstract product block, you can create a getImage() method on your own:

public function getImage($product, $imageId)
{
    return $this->imageBuilder->setProduct($product)
        ->setImageId($imageId)
        ->create();
}

$this->imageBuilder has to be injected as Magento\Catalog\Block\Product\ImageBuilder


The $imageType or $imageId variables should be one of the image types defined in the theme, for example category_page_list.

See app/design/frontend/Magento/luma/etc/view.xml for all image types in the Luma theme, for example.

In Magento 2 these image types are used instead of defining width and height directly in the template.

Try it

$store = $objectManager->get('Magento\Store\Model\StoreManagerInterface')->getStore();
$imageUrl = $store->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA) . 'catalog/product' . $product->getImage();

Similar questions

Where Do I Put a Template To Add Using {{block type="core/template" template="template.phtml"}}
I am new to Magento and so sorry for the noddy question. I am trying to add php to a CMS page and the way to do this appears to be to put the php (including Mage calls) to a phtml template and then add it to the CMS page with {{block type="core/template" template="template.phtml"}}. But, in all the examples that I can find saying that this is the w...
Construct full image URL as REST API Client (for products and categories)
I've looked at the following post and a few others, and the methods for constructing the image URL are failing for me: Getting full image url for products via REST API How can I construct the full image URL paths for the images returned for a category and a product? For a category the image information is provided in the custom_attributes array lik...
How can I get full path URL for configuration image field?
Check below code which I have used for upload image in configuration. But when I try to retrieve image URL based on below code, It's getting only default/image_name.ext How can I get full path of image URL?
How to get full Gallery Image URL Path using Magento?
I have a code, it diplays product sku, product name, product image full path, but not showing gallery images full path, only display the gallery images file names, but i want to display gallery full path also, so how can i solve this one, can any one tell me this answer?
Search Term Redirect URL. Relative Path instead of Full URL Path?
When editing a Search Query, why doesn't Magento allow the Redirect URL to be Relative Paths like /section/subsection or /best-product. It enforces the full URL which is kind of pain. How would you change this and is there any reasons to consider not changing this? Magento Documents its Search Term Redirect Functionality.
Full base url appended after base url when reaching page
For a demo environment, I had to upload my Magento project to a server, without a domain name. My Magento base URL is http://62.221.209.128/plesk-site-preview/rodrigootazu.com/62.221.209.128/, but as you can see when I reach it the full URL is appended behind it. What is causing this problem?

Also ask

We use cookies to deliver the best possible experience on our website. By continuing to use this site, accepting or closing this box, you consent to our use of cookies. To learn more, visit our privacy policy.