Magento 2:如何为自定义模块获取调整大小的图像?


12

我正在使用Magento 2 CE版本2.1.0

我有带有图像字段的自定义模块。上传后,我想要不同尺寸的产品图像,其中有缩略图图像,列表图像和产品详细信息页面图像。

能够上传1张图片而无需调整大小。

我正在使用以下代码调整图片大小,但是它提供了产品图片的网址。不是我的自定义模块。

\ app \ code \ Custom \ Module \ Block \ MyPosts \ Edit.php

public function getImage($posts, $image) {
    $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
    $_imagehelper = $objectManager->get('Magento\Catalog\Helper\Image');
    echo $postImage = $_imagehelper->init($posts, $image)->constrainOnly(FALSE)->keepAspectRatio(TRUE)->keepFrame(FALSE)->resize(400)->getUrl();
    exit;
}

它在下面的URL http://localhost/magento2/pub/static/frontend/Magento/luma/en_US/Magento_Catalog/images/product/placeholder/.jpg

我的图片存储在这里:\magento2\pub\media\custom_module\posts\image

如何通过此路径获取调整大小的图像以及如何保存/获取其他尺寸的图像?

Answers:


15

您可以通过单击在Magento 2中调整自定义图像的大小来检查详细信息

内部Block文件中保留以下代码,

   protected $_filesystem ;
   protected $_imageFactory;
   public function __construct(            
        \Magento\Framework\Filesystem $filesystem,         
        \Magento\Framework\Image\AdapterFactory $imageFactory         
        ) {         
        $this->_filesystem = $filesystem;               
        $this->_imageFactory = $imageFactory;         
        }

    // pass imagename, width and height
    public function resize($image, $width = null, $height = null)
    {
        $absolutePath = $this->_filesystem->getDirectoryRead(\Magento\Framework\App\Filesystem\DirectoryList::MEDIA)->getAbsolutePath('custom_module/posts/').$image;
        if (!file_exists($absolutePath)) return false;
        $imageResized = $this->_filesystem->getDirectoryRead(\Magento\Framework\App\Filesystem\DirectoryList::MEDIA)->getAbsolutePath('resized/'.$width.'/').$image;
        if (!file_exists($imageResized)) { // Only resize image if not already exists.
            //create image factory...
            $imageResize = $this->_imageFactory->create();         
            $imageResize->open($absolutePath);
            $imageResize->constrainOnly(TRUE);         
            $imageResize->keepTransparency(TRUE);         
            $imageResize->keepFrame(FALSE);         
            $imageResize->keepAspectRatio(TRUE);         
            $imageResize->resize($width,$height);  
            //destination folder                
            $destination = $imageResized ;    
            //save image      
            $imageResize->save($destination);         
        } 
        $resizedURL = $this->_storeManager->getStore()->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA).'resized/'.$width.'/'.$image;
        return $resizedURL;
  } 

现在在phtml文件中调用

$block->resize('test.jpg',500,400);

太棒了 完美运作。因此,在添加图片时,我们不必上传不同大小的图片。仅在显示时,我们必须管理正确的@Rakesh吗?
Ankit Shah

1
是的,当我们当时要展示时要进行管理。
Rakesh Jesadiya'9

当我们尝试调整1张图片的大小并将其放入相同图片的同一文件夹中时,此功能将不起作用。像这样:$ absolutePath = $ this-> _ filesystem-> getDirectoryRead(\ Magento \ Framework \ App \ Filesystem \ DirectoryList :: MEDIA)-> getRelativePath('C:/ xampp / htdocs / magento / app / code / Aht / BannerSlider /view/frontend/web/').$image; $ imageResized = $ this-> _ filesystem-> getDirectoryRead(\ Magento \ Framework \ App \ Filesystem \ DirectoryList :: MEDIA)-> getRelativePath('C:/ xampp / htdocs / magento / app / code / Aht / BannerSlider / view / frontend / web /').$ image;
fudu

如前所述,这不应是公认的答案。您不需要自己做所有这一切-只需使用Magento核心已存在的图像帮助程序即可。
fritzmg

@RakeshJesadiya,它给了我未知的文本作为网址
Hitesh Balpande

13

可接受的答案不考虑缓存图像以提高性能。您无需每次请求图像时都调整大小和覆盖图像。以下方法将调整大小后的图像保存到“缓存”文件夹中,因此连续的调用会从缓存中返回该图像。该方法包含在一个助手(不是块)中,因此您可以从任何喜欢的模板中调用它:

应用程序/代码/供应商/命名空间/Helper/Image.php

<?php

namespace Vendor\Namespace\Helper;

use Magento\Framework\App\Filesystem\DirectoryList;

class Image extends \Magento\Framework\App\Helper\AbstractHelper
{
    /**
     * Custom directory relative to the "media" folder
     */
    const DIRECTORY = 'custom_module/posts';

    /**
     * @var \Magento\Framework\Filesystem\Directory\WriteInterface
     */
    protected $_mediaDirectory;

    /**
     * @var \Magento\Framework\Image\Factory
     */
    protected $_imageFactory;

    /**
     * Store manager
     *
     * @var \Magento\Store\Model\StoreManagerInterface
     */
    protected $_storeManager;

    /**
     * @param \Magento\Framework\App\Helper\Context $context
     * @param \Magento\Framework\Filesystem $filesystem
     * @param \Magento\Framework\Image\Factory $imageFactory
     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
     */
    public function __construct(
        \Magento\Framework\App\Helper\Context $context,
        \Magento\Framework\Filesystem $filesystem,
        \Magento\Framework\Image\AdapterFactory $imageFactory,
        \Magento\Store\Model\StoreManagerInterface $storeManager
    ) {
        $this->_mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA);
        $this->_imageFactory = $imageFactory;
        $this->_storeManager = $storeManager;
        parent::__construct($context);
    }

    /**
     * First check this file on FS
     *
     * @param string $filename
     * @return bool
     */
    protected function _fileExists($filename)
    {
        if ($this->_mediaDirectory->isFile($filename)) {
            return true;
        }
        return false;
    }

    /**
     * Resize image
     * @return string
     */
    public function resize($image, $width = null, $height = null)
    {
        $mediaFolder = self::DIRECTORY;

        $path = $mediaFolder . '/cache';
        if ($width !== null) {
            $path .= '/' . $width . 'x';
            if ($height !== null) {
                $path .= $height ;
            }
        }

        $absolutePath = $this->_mediaDirectory->getAbsolutePath($mediaFolder) . $image;
        $imageResized = $this->_mediaDirectory->getAbsolutePath($path) . $image;

        if (!$this->_fileExists($path . $image)) {
            $imageFactory = $this->_imageFactory->create();
            $imageFactory->open($absolutePath);
            $imageFactory->constrainOnly(true);
            $imageFactory->keepTransparency(true);
            $imageFactory->keepFrame(true);
            $imageFactory->keepAspectRatio(true);
            $imageFactory->resize($width, $height);
            $imageFactory->save($imageResized);
        }

        return $this->_storeManager->getStore()->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA) . $path . $image;
    }
}

现在,您可以从任何.phtml模板调用如下方法:

<!-- Get a reference to the Image helper -->
<?php $image = $this->helper('Vendor\Namespace\Helper\Image'); ?>
.
.
.
<!-- Resize the image by specifying width only -->
<img src="<?php echo $image->resize('/my-picture.jpg', 1200); ?>">

<!-- Resize the image by specifying width and height -->
<img src="<?php echo $image->resize('/my-picture.jpg', 640, 480); ?>">

如果原始文件不存在,我是否建议添加检查?在resize()函数中:我更改if (!$this->_fileExists($path . $image)) {if (!$this->_fileExists($path . $image) && $this->_fileExists($mediaFolder . $image)) {
AlexandruBangală17年

像魅力一样工作,谢谢。这应该是公认的答案
fudu

您也可以简单地使用现有的\Magento\Catalog\Helper\Image
fritzmg

1
@fritzmg这个助手不是仅用于产品图像吗?如何将它与不是产品图片而是通过自定义模块上传到/ pub / media文件夹且与产品无关的自定义图片一起使用?
kovinet '18 -10-10

1
@kovinet-它适用于任何图像,只要原始图像包含在pub / media /文件夹中即可。只需将图像的路径传递到$ image-> resize('image / path / filename.ext');
Daniel Kratohvil

3

恐怕您不需要创建新类来调整图像大小,因为Magento帮助者已经拥有了它(请参阅参考资料\Magento\Catalog\Helper\Image::resize)。

因此,您可以执行以下操作:

$_imageHelper = \Magento\Framework\App\ObjectManager::getInstance()->get('Magento\Catalog\Helper\Image');

echo $_imageHelper->init($product, 'small_image', ['type'=>'small_image'])->keepAspectRatio(true)->resize('65','65')->getUrl();

您还可以在\Magento\VisualMerchandiser\Block\Adminhtml\Category\Merchandiser\Tile::getImageUrl(我想只有Magento EE)上看到这种用法的示例。


但是您的示例仅适用于产品图片,对吗?问题是关于带有“图像”字段的自定义模块。因此$product,/ media中仅存在图像文件的路径。
kovinet '18 -10-10

你是对的@kovinet。当时我没有注意到。但是,该线程帮助我提供了产品图像,似乎对其他人有所帮助。但是,谢谢您的评论。一有时间,我会寻找更好的答案。;)
里卡多·马丁斯

1

我遇到了一个问题,该resize方法无法将图像裁剪到我的尺寸,因此您需要根据原始图像的大小从顶部和底部或从左侧和右侧计算裁剪值。我使用@Rakesh中的代码并对其进行了修改,因此它检查原始图像是更高还是更高,并相应地进行裁剪:

public function resize($image, $width = null, $height = null)
{
    $mediaFolder = self::DIRECTORY;

    $path = $mediaFolder . 'cache';
    if ($width !== null) {
        $path .= '/' . $width . 'x';
        if ($height !== null) {
            $path .= $height ;
        }
    }

    $absolutePath = $this->_mediaDirectory->getAbsolutePath($mediaFolder) . $image;
    $imageResized = $this->_mediaDirectory->getAbsolutePath($path) . $image;

    if (!$this->_fileExists($path . $image) && $this->_fileExists($mediaFolder . $image)) {
        $imageFactory = $this->_imageFactory->create();
        $imageFactory->open($absolutePath);
        $imageFactory->constrainOnly(true);
        $imageFactory->keepAspectRatio(true);
        $imageFactory->keepFrame(false);

        $originalWidth = $imageFactory->getOriginalWidth();
        $originalHeight = $imageFactory->getOriginalHeight();

        $oldAspectRatio = $originalWidth / $originalHeight;
        $newAspectRatio = $width / $height;

        if ($oldAspectRatio > $newAspectRatio) {
            // original image is wider than the desired dimensions
            $imageFactory->resize(null, $height);
            $crop = ($imageFactory->getOriginalWidth() - $width) / 2;
            $imageFactory->crop(0, $crop, $crop, 0);
        } else {
            // it's taller...
            $imageFactory->resize($width, null);
            $crop = ($imageFactory->getOriginalHeight() - $height) / 2;
            $imageFactory->crop($crop, 0, 0, $crop);
        }

        $imageFactory->save($imageResized);

    }

    return $this->_storeManager
            ->getStore()
            ->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA) . $path . $image;
}

0

@Rakesh-我做过同样的事情,但是对我不起作用,有一个错误

Blockquote错误筛选模板:警告:getimagesize(/var/www/html/sitename/pub/media/onecategory/6/7/671471390.jpg):无法打开流:/ var / www / html中没有此类文件或目录/sitename/vendor/magento/framework/Image/Adapter/AbstractAdapter.php,第304行

你能帮我吗

谢谢。


找到解决方案了吗?因为我现在处于你的状况。:(
Fudu

请检查文件夹或文件的权限。
Sarfaraj Sipai '18年

在C:/xampp/htdocs/magento/pub/media/Aht_BannerSlider/images/slide_1.jpg中没有文件夹Aht_BannerSlider / images / slide_1.jpg,而且我也只授予pub文件夹许可。
富都

仍然不起作用。:(
fudu

请检查此页面上的最后一个答案。
Sarfaraj Sipai
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.