2

I am showing Listrak on site recommend product on my website.

Product images are very big, I need resizes images.

I have images name like 2/0/20mm.jpg and I am appeding it with https://example.com/media/catalog/product

So it will be

https://example.com/media/catalog/product/2/0/20mm.jpg

But i want

https://example.com/media/catalog/product/cache/fc6ca0131474e1299ecedb80f5002264/2/0/20mm.jpg

Note: I do not have product object, So can't load an get resized images that why need to get cache folder path so I will append image name.

Thanks in advance!

5
  • You can search magento code for the hash function which creates that hash and copy parts of it to your code Commented Jul 24, 2020 at 18:53
  • Are you trying to access the Magento images from and external website and don't know the URL? I believe the hash part is the same for same image resize settings, so you could hardcode it Commented Jul 24, 2020 at 19:14
  • @Alex, Yes I thought same to find hash code but could not find. at the moment I have written hard coded hash value but when I flush catalogue cache from admin, will hash value will change ? Commented Jul 25, 2020 at 5:00
  • I think it shouldn't change. Only when you change the image format in the theme I guess Commented Jul 25, 2020 at 7:21
  • 1
    @Alex, Yes you are right, it is not changing hash after flush catalogue cache. we can hard code it. please add your comment as answer :) Commented Aug 5, 2020 at 12:18

3 Answers 3

2

You can hard code the hash as it depends only on the image target format and mostly does not change.

2

If you want to get the cache path (hash) of the small_image on PLP then you can get the following way.

  1. Need to get the size of the small_image from view.xml.
  2. Need to generate the directory hash.
  3. Generate an URL, based on the hash.

1. Step Inject this class into the constructor.

use Magento\Framework\View\ConfigInterface as ViewConfigInterface; 

Then you can retrieve width and height like this. If the sizes are different in the GRID view then need to use category_page_grid instead of category_page_list. (But you can use any other id here.)

$imagesConfig =$this->viewConfig->getViewConfig()->getMediaEntities( 'Magento_Catalog', 'images' ); $width = $imagesConfig['category_page_list']['width']; $height = $imagesConfig['category_page_list']['height']; 

2. step

Inject EncryptorInterface into the constructor.

use Magento\Framework\Encryption\Encryptor; use Magento\Framework\Encryption\EncryptorInterface; 

Then you need this function.

/** * Converting bool into a string representation * * @param array $miscParams * @return array */ private function convertToReadableFormat(array $miscParams) { $miscParams['image_height'] = 'h:' . ($miscParams['image_height'] ?? 'empty'); $miscParams['image_width'] = 'w:' . ($miscParams['image_width'] ?? 'empty'); $miscParams['quality'] = 'q:' . ($miscParams['quality'] ?? 'empty'); $miscParams['angle'] = 'r:' . ($miscParams['angle'] ?? 'empty'); $miscParams['keep_aspect_ratio'] = (!empty($miscParams['keep_aspect_ratio']) ? '' : 'non') . 'proportional'; $miscParams['keep_frame'] = (!empty($miscParams['keep_frame']) ? '' : 'no') . 'frame'; $miscParams['keep_transparency'] = (!empty($miscParams['keep_transparency']) ? '' : 'no') . 'transparency'; $miscParams['constrain_only'] = (!empty($miscParams['constrain_only']) ? 'do' : 'not') . 'constrainonly'; $miscParams['background'] = !empty($miscParams['background']) ? 'rgb' . implode(',', $miscParams['background']) : 'nobackground'; return $miscParams; } 

Finally, you can get the path like this:

$path = $this->encryptor->hash( implode('_', $this->convertToReadableFormat([ 'image_height' => $height, 'image_width' => $width, 'background' => [255, 255, 255], 'angle' => null, 'quality' => 80, 'keep_aspect_ratio' => true, 'keep_frame' => true, 'keep_transparency' => true, 'constrain_only' => true, ])), Encryptor::HASH_VERSION_MD5 ); 

3. step You can use StoreManager to get the media URL and generate the URL.

{MEDIA_URL}/catalog/product/cache/{CACHE_PATH}

1
  • I had to pass ["area"=>"frontend"] to getViewConfig() to get all formats. Commented Aug 22, 2023 at 17:34
0

I've made a bash command to get the cache image file and delete it (optionally). I leave the source code below, maybe it will help someone.

In my di.xml file:

<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <type name="Magento\Framework\Console\CommandList"> <arguments> <argument name="commands" xsi:type="array"> <item name="regenarate_image" xsi:type="object">Vendor\Base\Console\RegenerateImages</item> </argument> </arguments> </type> </config> 

and my Command:

 namespace Vendor\Base\Console; use Magento\Framework\App\Area; use Magento\Framework\App\State; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Exception; use Magento\Catalog\Model\View\Asset\ImageFactory; use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\Filesystem; use Magento\Framework\Filesystem\Driver\File; use Magento\Framework\Exception\LocalizedException; class RegenerateImages extends Command { const IMAGE_ID = 'category_page_grid'; const NAME_ARGUMENT = 'sku'; /** * @var State */ private $state; /** * @var ImageFactory */ private $imageFactory; /** * @var ProductRepositoryInterface */ private $productRepository; /** * @var Filesystem */ private $filesystem; /** * @var File */ private $file; /** * @param State $state * @param ImageFactory $imageFactory * @param ProductRepositoryInterface $productRepository * @param Filesystem $filesystem * @param File $file * @param string|null $name */ public function __construct( State $state, ImageFactory $imageFactory, ProductRepositoryInterface $productRepository, Filesystem $filesystem, File $file, string $name = null ) { $this->state = $state; $this->imageFactory = $imageFactory; $this->productRepository = $productRepository; $this->filesystem = $filesystem; $this->file = $file; parent::__construct($name); } /** * @usage bin/magento vendor:regenarate_image {product sku} * @return void */ protected function configure() { $this->setName('vendor:regenarate_image'); $this->setDescription('Regenarate product image using the SKU'); $this->addArgument( self::NAME_ARGUMENT, InputArgument::REQUIRED, 'Product Sku' ); parent::configure(); } /** * @param InputInterface $input * @param OutputInterface $output * @return int|void * @throws LocalizedException */ protected function execute(InputInterface $input, OutputInterface $output) { $this->state->setAreaCode(Area::AREA_FRONTEND); $sku = (string) $input->getArgument(self::NAME_ARGUMENT); try { $product = $this->productRepository->get($sku); }catch (Exception $error){ $output->writeln("Cannot find product with SKU: {$sku} . More details". $error->getMessage()); return; } $imageUrl = $this->imageFactory->create([ 'miscParams' => $this->getImageMiscParams(), 'filePath' => $product->getData('small_image'), ]); try{ $imageUrl = $imageUrl->getUrl(); }catch (Exception $error){ $output->writeln($error->getMessage()); return; } $output->writeln("Cache Image Url: {$imageUrl} "); $afterCacheFolder = explode('cache/', $imageUrl); $afterCacheFolder = $afterCacheFolder[1]; $output->writeln("Getting hash: {$afterCacheFolder} "); $mediaPath = $this->filesystem->getDirectoryRead(DirectoryList::MEDIA)->getAbsolutePath(); $catalogMediaImageCacheFolder = $mediaPath.'catalog/product/cache/'.$afterCacheFolder; $output->writeln("Full cache image file path: {$catalogMediaImageCacheFolder} "); //optionally, if you want you can remove it ! try { if ($this->file->isExists($catalogMediaImageCacheFolder)) { $this->file->deleteFile($catalogMediaImageCacheFolder); } }catch (Exception $error){ $output->writeln($error->getMessage()); } $output->writeln("Finished!"); } /** * @return array */ public function getImageMiscParams() : array { return [ 'image_type' => 'small_image', 'image_height' => 500, 'image_width' => 500, 'background' => [ 0 => 255, 1 => 255, 2 => 255, ], 'angle' => null, 'quality' => 80, 'keep_aspect_ratio' => true, 'keep_frame' => false, 'keep_transparency' => true, 'constrain_only' => true, ]; } } 

Now if you run vendor:regenarate_image {product sku}, you will get the cache image patch and it will remove it. Good luck !

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.