5

I'm currently using $_category->getImageUrl(); to return a category's image. How can I get a smaller thumbnail of the category image? I've tried $_category->getThumbnailUrl();, but that doesn't appear to work. It seems pretty easy to get a product thumbnail, but for some reason categories are a little trickier. Does anyone know how to get a smaller version of the category image?

Thanks in advance...

1 Answer 1

4

There is no native helper that produces thumbnail for category images. You need to create one for the category entity. To do that first create helper class in Helper\Category\Image.php

namespace Vendor\Extension\Helper\Category;

use Magento\Catalog\Model\Category;
use Magento\Catalog\Helper\Image as CatalogImage;
use Vendor\Extension\Model\Category\Image as ImageModel;
use Vendor\Extension\Model\Category\ImageFactory as ImageModelFactory;

class Image extends CatalogImage
{
    /**
     * Current Product
     *
     * @var \Magento\Catalog\Model\Category
     */
    protected $_category;

    /**
     * Product image factory
     *
     * @var \Vendor\Extension\Model\Category\ImageFactory
     */
    protected $_categoryImageFactory;


    /**
     * Current model
     *
     * @var ImageModel
     */
    protected $_model;

    /**
     * Image constructor.
     * @param \Magento\Framework\App\Helper\Context $context
     * @param \Magento\Catalog\Model\Product\ImageFactory $productImageFactory
     * @param \Magento\Framework\View\Asset\Repository $assetRepo
     * @param \Magento\Framework\View\ConfigInterface $viewConfig
     * @param ImageModelFactory $categoryImageFactory
     */
    public function __construct(
        \Magento\Framework\App\Helper\Context $context,
        \Magento\Catalog\Model\Product\ImageFactory $productImageFactory,
        \Magento\Framework\View\Asset\Repository $assetRepo,
        \Magento\Framework\View\ConfigInterface $viewConfig,
        ImageModelFactory $categoryImageFactory
    ) {
        $this->_categoryImageFactory = $categoryImageFactory;
        parent::__construct($context, $productImageFactory, $assetRepo, $viewConfig);
    }

    /**
     * Reset all previous data
     *
     * @return $this
     */
    protected function _reset()
    {
        $this->_category = null;
        return parent::_reset();
    }

    /**
     * Initialize Helper to work with Image
     *
     * @param \Magento\Catalog\Model\Category $category
     * @param string $imageId
     * @param array $attributes
     * @return $this
     */
    public function init($category, $imageId, $attributes = ['type' => 'image'])
    {
        $this->_reset();

        $this->attributes = array_merge(
            $this->getConfigView()->getMediaAttributes('Magento_Catalog', self::MEDIA_TYPE_CONFIG_NODE, $imageId),
            $attributes
        );

        $this->setCategory($category);
        $this->setImageProperties();
        $this->setWatermarkProperties();

        return $this;
    }

    /**
     * Override getProduct method for use in the parent class
     *
     * @return Category
     */
    public function getProduct()
    {
        return $this->getCategory();
    }

    /**
     * Set current Product
     *
     * @param Category $category
     * @return $this
     */
    protected function setCategory($category)
    {
        $this->_category = $category;
        return $this;
    }

    /**
     * Get current Product
     *
     * @return Category
     */
    protected function getCategory()
    {
        return $this->_category;
    }

    /**
     * Get current Image model
     *
     * @return ImageModel
     */
    protected function _getModel()
    {
        if (!$this->_model) {
            $this->_model = $this->_categoryImageFactory->create();
        }
        return $this->_model;
    }
}

Then you need to create Model\Category\Image.php with the following code

namespace Vendor\Extension\Model\Category;

use Magento\Catalog\Model\Product\Image as ProductImage;
use Magento\Framework\Image as MagentoImage;
use Magento\Catalog\Model\Product\Media\Config as MediaConfig;
use Magento\Framework\Model\Context;
use Magento\Framework\Registry;
use Magento\Store\Model\StoreManagerInterface;
use Magento\MediaStorage\Helper\File\Storage\Database;
use Magento\Framework\Filesystem;
use Magento\Framework\View\FileSystem as ViewFileSystem;
use Magento\Framework\View\Asset\Repository;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\Model\ResourceModel\AbstractResource;
use Magento\Framework\Data\Collection\AbstractDb;

class Image extends ProductImage
{
    /**
     * Catalog product media config
     *
     * @var \Magento\Catalog\Model\Product\Media\Config
     */
    protected $_catalogProductMediaConfig;

    /**
     * Image constructor.
     * @param Media\Config $mediaConfig
     * @param Context $context
     * @param Registry $registry
     * @param StoreManagerInterface $storeManager
     * @param MediaConfig $catalogProductMediaConfig
     * @param Database $coreFileStorageDatabase
     * @param Filesystem $filesystem
     * @param MagentoImage\Factory $imageFactory
     * @param Repository $assetRepo
     * @param ViewFileSystem $viewFileSystem
     * @param ScopeConfigInterface $scopeConfig
     * @param AbstractResource|null $resource
     * @param AbstractDb|null $resourceCollection
     * @param array $data
     */
    public function __construct(
        Media\Config $mediaConfig,
        Context $context,
        Registry $registry,
        StoreManagerInterface $storeManager,
        MediaConfig $catalogProductMediaConfig,
        Database $coreFileStorageDatabase,
        Filesystem $filesystem,
        MagentoImage\Factory $imageFactory,
        Repository $assetRepo,
        ViewFileSystem $viewFileSystem,
        ScopeConfigInterface $scopeConfig,
        AbstractResource $resource = null,
        AbstractDb $resourceCollection = null,
        array $data = []
    ) {
        parent::__construct($context, $registry, $storeManager, $catalogProductMediaConfig, $coreFileStorageDatabase, $filesystem, $imageFactory, $assetRepo, $viewFileSystem, $scopeConfig, $resource, $resourceCollection, $data);

        //override models for product image with our custom ones
        $this->_catalogProductMediaConfig = $mediaConfig;
        $this->_mediaDirectory->create($this->_catalogProductMediaConfig->getBaseMediaPath());
    }

    /**
     * @return string
     */
    public function getUrl()
    {
        if ($this->_newFile === true) {
            $url = $this->_assetRepo->getUrl(
                "Magento_Catalog::images/product/placeholder/{$this->getDestinationSubdir()}.jpg"
            );
        }
        else {
            $url = $this->_storeManager->getStore()->getBaseUrl(
                    \Magento\Framework\UrlInterface::URL_TYPE_MEDIA
                ) . $this->_newFile;
        }

        return $url;
    }
}

and finally model for configuration in Model\Category\Media\Config.php

namespace Vendor\Extension\Model\Category\Media;

use Magento\Catalog\Model\Product\Media\Config as MediaConfig;

class Config extends MediaConfig
{
    /**
     * @return string
     */
    public function getBaseMediaUrl()
    {
        return $this->storeManager->getStore()->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA) . 'catalog/category';
    }

    /**
     * Filesystem directory path of product images
     * relatively to media folder
     *
     * @return string
     */
    public function getBaseMediaPathAddition()
    {
        return 'catalog/category';
    }

    /**
     * Web-based directory path of product images
     * relatively to media folder
     *
     * @return string
     */
    public function getBaseMediaUrlAddition()
    {
        return 'catalog/category';
    }

    /**
     * @return string
     */
    public function getBaseMediaPath()
    {
        return 'catalog/category';
    }
}

Now in the template file you can inject Vendor\Extension\Helper\Category\Image and resize category image using:

echo $categoryHelperImage->init($categoryModel, 'image')->resize(100,100)->getUrl();
6
  • Bummer, that's what I figured. Thanks for the code snippets @Zefiryn Commented Mar 9, 2017 at 23:02
  • 2
    How work : use Vendor\Extension\Model\Category\ImageFactory as ImageModelFactory ?
    – Patryk
    Commented May 2, 2018 at 8:49
  • I'm sorry but I do not understand this your comment.
    – Zefiryn
    Commented May 2, 2018 at 15:37
  • easy! magento2 always the best :)
    – LucScu
    Commented Mar 7, 2019 at 14:55
  • @Zefiryn Thanks for the solution. but Vendor\Extension\Model\Category\ImageFactory seems undefined? Commented Sep 17, 2019 at 5:27

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.