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/placeholder/.jpg'