마 젠토 2 : 커스텀 모듈의 이미지 크기를 조정하는 방법?


12

Magento 2 CE 버전 2.1.0을 사용하고 있습니다.

이미지 필드가있는 사용자 지정 모듈이 있습니다. 업로드 할 때 썸네일 이미지, 목록 이미지 및 제품 세부 정보 페이지 이미지가있는 제품과 다른 크기의 이미지를 원합니다.

크기를 조정하지 않고 1 개의 이미지를 업로드 할 수 있습니다.

이미지 크기를 조정하기 위해 아래 코드를 사용하고 있지만 제품 이미지 URL을 제공합니다. 내 맞춤 모듈이 아닙니다.

\ 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.

이 경로로 이미지 크기를 조정하고 다른 크기의 이미지를 저장 / 검색하려면 어떻게해야합니까?

답변:


15

Magento 2에서 사용자 정의 이미지 크기 조정 을 클릭하여 세부 정보를 확인할 수 있습니다

내부 블록 파일은 코드 아래에 보관하십시오.

   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

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 / 프론트 엔드 / 웹 /').$image;
fudu

이미 언급했듯이, 이것은 대답이 받아 들여서는 안됩니다. 이 모든 것을 직접 할 필요는 없습니다. 이미 존재하는 Magento 코어의 이미지 도우미를 사용하십시오.
fritzmg

@RakeshJesadiya, URL로 알 수없는 텍스트를 제공
Hitesh Balpande

13

허용되는 답변은 성능을 향상시키기 위해 이미지를 캐싱하는 것을 고려하지 않습니다. 요청 될 때마다 이미지 크기를 조정하고 덮어 쓸 필요는 없습니다. 다음 방법은 크기가 조정 된 이미지를 "캐시"폴더에 저장하므로 연속적인 호출은 캐시에서 이미지를 반환합니다. 이 메소드는 블록이 아닌 도우미에 포함되어 있으므로 원하는 템플릿에서 호출 할 수 있습니다.

app / code / Vendor / Namespace / 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)) {
Alexandru Bangală

고마워요, 고마워요 이것은 대답이 될 것입니다
fudu

기존의을 간단히 사용할 수도 있습니다 \Magento\Catalog\Helper\Image.
fritzmg

2
@fritzmg이 도우미는 제품 이미지만을위한 것이 아닙니까? 제품 이미지가 아닌 사용자 정의 모듈로 / pub / media 폴더에 업로드 된 이미지이며 제품과 관련이없는 사용자 정의 이미지와 함께 사용하려면 어떻게해야합니까?
kovinet

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

당신은 맞습니다 @kovinet. 그때는 눈치 채지 못했습니다. 그러나이 스레드는 제품 이미지에 도움이되었으며 다른 사람들에게 도움이되는 것 같습니다. 그러나 귀하의 의견에 감사드립니다. 시간이 생기면 더 나은 답변을 찾도록하겠습니다. ;)
Ricardo Martins

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-같은 작업을 수행했지만 작동하지 않습니다. 오류가 있습니다.

인용구 오류 필터링 템플릿 : 경고 : getimagesize (/var/www/html/sitename/pub/media/onecategory/6/7/671471390.jpg) : 스트림을 열지 못했습니다 : / var / www / html에 해당 파일 또는 디렉토리가 없습니다. 304 행의 /sitename/vendor/magento/framework/Image/Adapter/AbstractAdapter.php

이것 좀 도와 주실 래요?

감사합니다.


해결책을 찾으십니까? 내가 지금 당신의 상황에 있기 때문에. :(
fudu

폴더 또는 파일 권한을 확인하십시오.
Sarfaraj Sipai

C : /xampp/htdocs/magento/pub/media/Aht_BannerSlider/images/slide_1.jpg에 Aht_BannerSlider / images / slide_1.jpg 폴더가 없으며 pub 폴더에 대한 권한을 부여했습니다.
fudu

그리고 여전히 작동하지 않습니다. :(
fudu

이 페이지에서 마지막 답변을 확인하십시오.
Sarfaraj Sipai
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.