Magento 2: Làm cách nào để thay đổi kích thước hình ảnh cho Mô-đun tùy chỉnh?


12

Tôi đang sử dụng Magento 2 CE Phiên bản 2.1.0

Tôi có Mô-đun tùy chỉnh với Trường hình ảnh. Khi được tải lên, tôi muốn hình ảnh có kích thước khác nhau như đối với sản phẩm, chúng tôi có Hình ảnh thu nhỏ, Hình ảnh danh sách & Hình ảnh chi tiết sản phẩm.

Có thể tải lên 1 hình ảnh mà không cần thay đổi kích thước.

Tôi đang sử dụng mã dưới đây để thay đổi kích thước hình ảnh, nhưng nó đang cung cấp URL hình ảnh sản phẩm. Không phải mô-đun tùy chỉnh của tôi.

\ 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;
}

Nó cung cấp URL bên dưới http: //localhost/magento2/pub/static/frontend/Magento/luma/en_US/Magento_Catalog/images/product/placeholder/.jpg

Hình ảnh của tôi được lưu trữ ở đây : \magento2\pub\media\custom_module\posts\image.

Làm cách nào tôi có thể thay đổi kích thước hình ảnh với đường dẫn này và làm cách nào tôi có thể lưu / truy xuất hình ảnh kích thước khác nhau?

Câu trả lời:


15

Bạn có thể kiểm tra chi tiết bằng cách nhấp, Thay đổi kích thước hình ảnh tùy chỉnh trong Magento 2

Tập tin Block bên trong giữ mã bên dưới,

   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;
  } 

Bây giờ Gọi bên trong tệp phtml,

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

Bravo. Hoạt động hoàn hảo. Vì vậy, trong khi Thêm hình ảnh, chúng tôi không phải tải lên với các kích cỡ khác nhau. Chỉ trong khi hiển thị, chúng ta phải quản lý chính xác @Rakesh?
Ankit Shah

1
có khi chúng tôi phải hiển thị tại thời điểm đó quản lý.
Rakesh Jesadiya

không hoạt động khi chúng tôi cố gắng thay đổi kích thước 1 hình ảnh và đặt nó vào cùng một thư mục với cùng một hình ảnh. như thế này: $ perfectPath = $ this -> _ filesystem-> getDirectoryRead (\ Magento \ Framework \ App \ Filesystem \ DirectoryList :: MEDIA) -> getRelativePath ('C: / xampp / htdocs / magento / app / code / Aht / BannerS /view/frontend/web/').$image; $ imageResized = $ this -> _ filesystem-> getDirectoryRead (\ Magento \ Framework \ App \ Filesystem \ DirectoryList :: MEDIA) -> getRelativePath ('C: / xampp / htdocs / magento / app / code / Aht / BannerSl hình ảnh frontend / web /').$;
fudu

Như đã đề cập, đây không phải là câu trả lời được chấp nhận. Bạn không cần phải tự làm tất cả những điều này - chỉ cần sử dụng trình trợ giúp hình ảnh đã có của lõi Magento.
fritzmg

@ RakeshJesadiya, nó cung cấp cho tôi văn bản không xác định dưới dạng url
Hitesh Balpande

13

Câu trả lời được chấp nhận không xem xét lưu trữ hình ảnh để cải thiện hiệu suất. Bạn không cần thay đổi kích thước và ghi đè lên hình ảnh mỗi khi nó được yêu cầu. Cách tiếp cận sau đây lưu hình ảnh đã thay đổi kích thước vào thư mục "bộ đệm" để các cuộc gọi liên tiếp trả lại hình ảnh từ bộ đệm. Phương thức này được chứa trên một trình trợ giúp (không phải là một khối) để bạn có thể gọi nó từ bất kỳ mẫu nào bạn muốn:

ứng dụng / mã / Nhà cung cấp / Không gian tên / Người trợ giúp / 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;
    }
}

Bây giờ từ bất kỳ mẫu .phtml nào bạn có thể gọi phương thức như thế này:

<!-- 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); ?>">

Tôi có thể đề nghị thêm một kiểm tra cho tập tin gốc, trong trường hợp nó không tồn tại? trong hàm resize (): Tôi đã đổi if (!$this->_fileExists($path . $image)) {thànhif (!$this->_fileExists($path . $image) && $this->_fileExists($mediaFolder . $image)) {
Alexandru Bangală

Làm việc như một cơ duyên, cảm ơn bạn. Đây phải là câu trả lời được chấp nhận
fudu

Bạn cũng có thể chỉ cần sử dụng hiện có \Magento\Catalog\Helper\Image.
fritzmg

1
@fritzmg không phải người trợ giúp này chỉ dành cho hình ảnh sản phẩm? Làm cách nào tôi có thể sử dụng nó với hình ảnh tùy chỉnh không phải là hình ảnh sản phẩm nhưng hình ảnh được tải lên với mô-đun tùy chỉnh vào thư mục / pub / media và không liên quan đến sản phẩm?
kovinet

1
@kovinet - Nó hoạt động với bất kỳ hình ảnh nào miễn là hình ảnh gốc được chứa trong thư mục pub / media /. Chỉ cần chuyển đường dẫn của hình ảnh đến $ image-> thay đổi kích thước ('image / path / filename.ext');
Daniel Kratohvil

3

Tôi e rằng bạn không cần phải tạo các lớp mới để thay đổi kích thước hình ảnh của mình, vì những người trợ giúp Magento đã có nó (xem \Magento\Catalog\Helper\Image::resize).

Vì vậy, bạn chỉ có thể làm:

$_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();

Bạn cũng có thể xem một ví dụ về cách sử dụng này tại \Magento\VisualMerchandiser\Block\Adminhtml\Category\Merchandiser\Tile::getImageUrl(Magento EE chỉ tôi đoán)


Nhưng ví dụ của bạn sẽ chỉ làm việc với hình ảnh sản phẩm, phải không? Câu hỏi là về mô-đun tùy chỉnh với trường Hình ảnh. Vì vậy, không có $productnhưng chỉ có đường dẫn đến tệp hình ảnh trong / media.
kovinet

Bạn nói đúng @kovinet. Tôi đã không nhận thấy nó tại thời điểm đó. Tuy nhiên, chủ đề này đã giúp tôi với hình ảnh sản phẩm, và có vẻ như nó giúp người khác. Nhưng cảm ơn bạn đã bình luận của bạn. Ngay sau khi tôi có thời gian, tôi sẽ tìm kiếm một câu trả lời tốt hơn. ;)
Ricardo Martins

1

Tôi đã gặp phải một vấn đề trong đó resizephương pháp sẽ không cắt hình ảnh theo kích thước của tôi, do đó bạn cần tính toán các giá trị cắt từ trên xuống và dưới cùng hoặc bên trái và bên phải, tùy thuộc vào kích thước hình ảnh ban đầu của bạn. Tôi đã sử dụng mã từ @Rakesh và sửa đổi nó để nó kiểm tra xem ảnh gốc cao hơn hay rộng hơn và phù hợp với cây trồng:

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 - Tôi đã làm tương tự nhưng nó không hoạt động đối với tôi có lỗi

Mẫu lọc lỗi Blockquote: Cảnh báo: getimagesize (/var/www/html/sitename/pub/media/onecarget/6/7/671471390.jpg): không thể mở luồng: Không có tệp hoặc thư mục như vậy trong / var / www / html /sitename/vendor/magento/framework/Image/Ad Module / Ab AbAdAd.php trên dòng 304

bạn có thể giúp tôi trong việc này

Cảm ơn bạn.


Bạn có tìm ra giải pháp không? Bởi vì tôi đang ở trong hoàn cảnh của bạn. :(
fudu

vui lòng kiểm tra thư mục hoặc cho phép tập tin.
Sarfaraj Sipai

không có thư mục Aht_BannerSlider / hình ảnh / slide_1.jpg trong C: /xampp/htdocs/magento/pub/media/Aht_BannerSlider/images/slide_1.jpg, và tôi cũng vừa cấp quyền cho thư mục pub.
fudu

Và vẫn không hoạt động. :(
fudu

vui lòng kiểm tra câu trả lời cuối cùng trên trang này.
Sarfaraj Sipai
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.