How A Product Image Is Generated In Magento
For a commerce site, it’s normal to assume all the products have to serve product images in various forms and sizes when requested in a different context. Be it small size, swatch_image, thumbnail, watermark, etc. Magento doesn’t sit and watch a store owner tediously upload each individual file for various size of same product image required. Magento handles by itself complex process of product image generation using GD library and ImageMagick. Since Magento has already put them well in an abstract design, you really need not bother to implement those libraries yourself.
Image generation process flow
However, you still need to know which classes are in charge of generating images or their blocks to place them within when an image is requested for a product in various contexts just in case of the process not working as expected.
These 4 classes are what works hard when a catalog needs a product image and request as such. They all reside in the Catalog module. Normally the gateway for image request is
Gateway for the process
What this snippet of code does is literally using the ImageBuilder to create an image tailored for a product in a certain context. You can understand what it does just by reading the code. Particularly the setImageId method configures in which context the image is going to be used. For example, it can be category_page_grid or category_page_list which informs the ImageBuilder of the target image context so that they are dressed as fit in the layout as possible.
Image builder class
Then the ImageBuilder creates an Image block because ImageBuilder class is basically a block class that returns an Image block class as follows :
Basically this snippet does creating an image helper to configure all the details of the image that needs creation. You may find this helper class is where all the magics happen if you take a look into the class’s methods. When the helper is created, it also chains the init method to prepare the whole configuration for the image. Then, template is set as per the configuration for its frame, then it configures the size for the image by using getResizedImageInfo method.
Looking further into Magento\Catalog\Helper\Image::init method as follows :
The protected _reset method literally reset all the data for the Image model configured previously including rotation, angle, watermark, position, size and other attributes. Next, it takes attributes from view.xml configuration and from method argument then merge them to prepare image properties.
view.xml for media type attributes
What is supposed to exist in view.xml for a theme with respect to image generation?
For a theme to work properly, there must be an image node defined in view.xml with id attribute identical to the ones used in getImage method across the whole theme (in this case, it’s category_page_grid). For a demonstration, they are defined in /etc/view.xml of default themes out of the box, so if you expand your theme based on Magento default blank theme or luma theme, you really don’t need to elaborate this. In contrast, when you work on starting a new theme from scratch without inheriting a parent theme whose view.xml is already robustly defined, you must create view.xml with all the definitions that are used across the whole Magento templates in your theme. Otherwise you would see strange errors with a trace as follows :
Magento\Framework\View\Asset\File->getSourceFile() : Unable to resolve the source file for ‘<Area>/<Vendor>/<Theme>/<Locale>/Magento_Catalog/images/product/placeholder/.jpg’
which is almost useless to track the real issue where Magento\Framework\Config\View::getMediaAttributes method failed to fetch media attributes required in view.xml to process a certain imageId passed along with getImage method. I wish Magento core team could provide more robust solution to this with fallback configurations for default media types. Or, at least, a proper conditional statement to point to the caveat scenario where merged attributes for image are empty so that debug trace can give a good hint for addressing the real issue.
Wrapping-up the initialization
Going forward, product is set for the model to reference, and then image properties are configured in setImageProperties method where the type of image(i.e. thumbnail, small size or normal size, swatch and so on), width, height, ratio constrain, transparency and background color is set by attributes merged above. Finally it configures the watermark whose properties include opacity, position and size, then returns the Image model class.
So, everything is up and ready now to create the image passing data configured so far to ImageFactory class in the Magento\Catalog\Block\Product\ImageBuilder::create method.
Now we’ve wrapped up how an image is processed in Magento, to finish this post off, let’s see a real example of how the method is evoked in the catalog/product/list.phtml as follows :
Look for my comments in the code above that starts with “//// Degi : …” to get the idea of how it’s implemented.
Thanks for the reading, please leave any comment for your thoughts!