Magento 2: วิธีปรับขนาดอิมเมจสำหรับ Custom Module


12

ฉันใช้ Magento 2 CE เวอร์ชั่น 2.1.0

ฉันมีโมดูลที่กำหนดเองพร้อมฟิลด์ภาพ เมื่ออัปโหลดแล้วฉันต้องการภาพขนาดแตกต่างกันสำหรับผลิตภัณฑ์ที่เรามีภาพขนาดย่อ, ภาพรายการและภาพหน้ารายละเอียดสินค้า

สามารถอัพโหลดได้ 1 ภาพโดยไม่ต้องปรับขนาด

ฉันใช้โค้ดด้านล่างเพื่อปรับขนาดภาพ แต่มันให้ URL ภาพผลิตภัณฑ์ ไม่ใช่โมดูลที่กำหนดเองของฉัน

\ แอป \ รหัส \ กำหนดเอง \ โมดูล \ บล็อก \ 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

ไฟล์ Inside 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

ไม่ทำงานเมื่อเราพยายามปรับขนาด 1 ภาพและวางไว้ในโฟลเดอร์เดียวกันที่มีภาพเดียวกัน เช่นนี้: $ absolutePath = $ this -> _ filesystem-> getDirectoryRead (\ Magento \ Framework \ App \ Filesystem \ DirectoryList :: MEDIA) -> getRelativePath ('C: / xampp / htdocs / magento / app / รหัส / Aht / BannerSlider /view/frontend/web/').$image; $ imageResized = $ this -> _ filesystem-> getDirectoryRead (\ Magento \ Framework \ App \ Filesystem \ DirectoryList :: MEDIA) -> getRelativePath ('C: / xampp / htdocs / magento / แอพ / รหัส / Aht / BannerSlider / ดู / ส่วนหน้า / เว็บ /').$ ภาพ;
fudu

ดังที่ได้กล่าวไปแล้วนี่ไม่ควรเป็นคำตอบที่ยอมรับได้ คุณไม่จำเป็นต้องทำทั้งหมดนี้ด้วยตัวเองเพียงใช้ตัวช่วยสร้างรูปที่มีอยู่แล้วของ Magento core
fritzmg

@ RakeshJesadiya มันทำให้ฉันไม่รู้จักข้อความเป็น url
Hitesh Balpande

13

คำตอบที่ยอมรับไม่ได้พิจารณาการแคชรูปภาพเพื่อปรับปรุงประสิทธิภาพ คุณไม่จำเป็นต้องปรับขนาดและเขียนทับรูปภาพทุกครั้งที่มีการร้องขอ วิธีการต่อไปนี้บันทึกภาพที่ปรับขนาดแล้วลงในโฟลเดอร์ "แคช" เพื่อให้การโทรติดต่อกลับมาส่งคืนรูปภาพจากแคช วิธีการมีอยู่ในผู้ช่วย (ไม่ใช่บล็อก) เพื่อให้คุณสามารถโทรหาได้จากเทมเพลตที่คุณต้องการ:

app / รหัส / ผู้ขาย / Namespace / ผู้ช่วย / 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); ?>">

ฉันขอแนะนำให้เพิ่มการตรวจสอบไฟล์ต้นฉบับในกรณีที่ไม่มีอยู่หรือไม่? ในฟังก์ชั่นปรับขนาด (): ฉันเปลี่ยน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 / folder เพียงผ่านเส้นทางของภาพไปที่ $ 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แต่เส้นทางไปยังไฟล์ภาพใน / สื่อ
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 - ฉันได้ทำเหมือนกัน แต่มันไม่ทำงานสำหรับฉันมีข้อผิดพลาด

แม่แบบการกรอง Blockquote Error: คำเตือน: 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

ไม่มีโฟลเดอร์ Aht_BannerSlider / images / slide_1.jpg ใน C: /xampp/htdocs/magento/pub/media/Aht_BannerSlider/images/slide_1.jpg และฉันเพิ่งให้สิทธิ์กับโฟลเดอร์ pub
fudu

และยังไม่ทำงาน :(
fudu

โปรดตรวจสอบคำตอบล่าสุดในหน้านี้
Sarfaraj Sipai
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.