Sometimes, when an image is retrieving from outside the frontend scope (sending emails via cron, etc) - make sure you are loading design area configs. E.g.:
in .phtml:
<?= $block->getImage($_product, 'product_thumbnail_image', ['class' => 'photo image'])->toHtml() ?>
in block:
/**
* @var \Magento\Catalog\Block\Product\ImageBuilder
*/
private $imageBuilder;
/**
* @var \Magento\Framework\App\AreaList
*/
private $areaList;
/**
* ImageProvider constructor.
* @param \Magento\Catalog\Block\Product\ImageBuilder $imageBuilder
* @param \Magento\Framework\App\AreaList $areaList
*/
public function __construct(
\Magento\Catalog\Block\Product\ImageBuilder $imageBuilder,
\Magento\Framework\App\AreaList $areaList
) {
$this->imageBuilder = $imageBuilder;
$this->areaList = $areaList;
}
public function getImage(
\Magento\Catalog\Model\Product $product,
$imageId,
$attributes = []
) {
//make sure to load the design part of configuration.
$this->areaList->getArea(Area::AREA_FRONTEND)
->load(Area::PART_DESIGN);
//when the design part is loaded - simply call native image builder -
return $this->imageBuilder->create($product, $imageId, $attributes);
}