Magento 2: Bagaimana cara mengubah ukuran gambar untuk Modul Kustom?

12

Saya menggunakan Magento 2 CE Versi 2.1.0

Saya memiliki Modul Kustom dengan Bidang Gambar. Ketika diunggah, saya ingin gambar dengan ukuran yang berbeda untuk produk kami memiliki Gambar Thumbnail, Gambar Daftar & Gambar Halaman Detail Produk.

Dapat mengunggah 1 gambar tanpa mengubah ukuran.

Saya menggunakan kode di bawah ini untuk mengubah ukuran gambar, tetapi memberikan URL gambar produk. Bukan modul khusus saya.

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

Ini memberikan URL di bawah ini http: //localhost/magento2/pub/static/frontend/Magento/luma/en_US/Magento_Catalog/images/product/placeholder/.jpg

Gambar saya disimpan di sini: \magento2\pub\media\custom_module\posts\image.

Bagaimana saya bisa mendapatkan ukuran gambar dengan jalur ini & bagaimana saya bisa menyimpan / mengambil gambar ukuran yang berbeda?

Ankit Shah
sumber

Jawaban:

15

Anda dapat memeriksa detail dengan mengklik, Ubah Ukuran Gambar Kustom di Magento 2

Di dalam file Block simpan di bawah kode,

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

Sekarang Panggil di dalam file phtml,

$block->resize('test.jpg',500,400);
Rakesh Jesadiya
sumber
Bravo. Bekerja dengan sempurna. Jadi, sementara Tambah Gambar, kami tidak perlu mengunggah dengan ukuran berbeda. Hanya saat menampilkan kita harus mengelola @Rakesh yang benar?
Ankit Shah
1
ya ketika kita harus menampilkan mengelola waktu itu.
Rakesh Jesadiya
tidak berfungsi ketika kami mencoba untuk mengubah ukuran 1 gambar dan meletakkannya di folder yang sama dengan gambar yang sama seperti ini: $ 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 /').$ gambar;
fudu
Seperti yang sudah disebutkan, ini bukan jawaban yang diterima. Anda tidak perlu melakukan semua ini sendiri - cukup gunakan pembantu gambar yang sudah ada dari inti Magento.
fritzmg
@ RakeshJesadiya, ini memberiku teks tak dikenal sebagai url
Hitesh Balpande
13

Jawaban yang diterima tidak mempertimbangkan caching gambar untuk meningkatkan kinerja. Anda tidak perlu mengubah ukuran dan menimpa gambar setiap kali diminta. Pendekatan berikut menyimpan gambar yang diubah ukurannya ke folder "cache" sehingga panggilan berturut-turut mengembalikan gambar dari cache. Metode ini terkandung pada helper (bukan blok) sehingga Anda dapat memanggilnya dari template yang Anda suka:

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

Sekarang dari sembarang .phtml Anda dapat memanggil metode seperti ini:

<!-- 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); ?>">
Daniel Kratohvil
sumber
Bolehkah saya menyarankan menambahkan cek untuk file asli, jika tidak ada? dalam fungsi resize (): Saya berubah if (!$this->_fileExists($path . $image)) {menjadiif (!$this->_fileExists($path . $image) && $this->_fileExists($mediaFolder . $image)) {
Alexandru Bangal
Bekerja seperti pesona, terima kasih. Ini seharusnya jawaban yang diterima
fudu
Anda juga bisa langsung menggunakan yang sudah ada \Magento\Catalog\Helper\Image.
fritzmg
1
@ fritzmg bukankah pembantu ini hanya ditujukan untuk gambar produk? Bagaimana saya bisa menggunakannya dengan gambar khusus yang bukan gambar produk tetapi gambar yang diunggah dengan modul khusus ke / pub / folder media dan tidak ada hubungannya dengan produk?
kovinet
1
@kovinet - Ini berfungsi dengan gambar apa pun asalkan gambar aslinya terkandung di dalam pub / media / folder. Cukup lewati path gambar ke $ image-> resize ('image / path / filename.ext');
Daniel Kratohvil
3

Saya khawatir Anda tidak perlu membuat kelas baru untuk mengubah ukuran gambar Anda, karena pembantu Magento sudah memilikinya (lihat \Magento\Catalog\Helper\Image::resize).

Jadi, Anda bisa melakukan:

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

Anda juga dapat melihat contoh penggunaan ini di \Magento\VisualMerchandiser\Block\Adminhtml\Category\Merchandiser\Tile::getImageUrl(hanya Magento EE, saya kira)

Ricardo Martins
sumber
Tetapi contoh Anda hanya akan berfungsi dengan gambar produk, kan? Pertanyaannya adalah tentang modul khusus dengan bidang Gambar. Jadi tidak ada $producttapi hanya path ke file gambar di / media.
kovinet
Anda benar @kovinet. Saya tidak menyadarinya saat itu. Namun, utas ini membantu saya dengan gambar produk, dan sepertinya ini membantu orang lain. Tetapi terima kasih atas komentar Anda. Segera setelah saya punya waktu, saya akan mencari jawaban yang lebih baik. ;)
Ricardo Martins
1

Saya mengalami masalah di mana resizemetode ini tidak akan memotong gambar ke dimensi saya sehingga Anda harus menghitung nilai pemotongan dari atas dan bawah atau kiri dan kanan, tergantung pada ukuran gambar asli Anda. Saya menggunakan kode dari @Rakesh dan memodifikasinya sehingga memeriksa apakah gambar asli lebih tinggi atau lebih luas dan memotong sesuai:

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;
}
Zankar
sumber
0

@Rakesh - Saya telah melakukan hal yang sama tetapi tidak berfungsi untuk saya ada kesalahan

Templat pemfilteran Blockquote Error: Peringatan: getimagesize (/var/www/html/sitename/pub/media/onecategory/6/7/671471390.jpg): gagal membuka streaming: Tidak ada file atau direktori di / var / www / html /sitename/vendor/magento/framework/Image/Adapter/AbstractAdapter.php on line 304

dapatkah Anda membantu saya dalam hal ini?

Terima kasih.

Sarfaraj Sipai
sumber
Apakah Anda menemukan solusinya? Karena saya dalam situasi Anda sekarang. :(
fudu
silakan periksa folder atau izin file.
Sarfaraj Sipai
tidak memiliki folder Aht_BannerSlider / images / slide_1.jpg di C: /xampp/htdocs/magento/pub/media/Aht_BannerSlider/images/slide_1.jpg, Dan saya juga baru saja memberikan izin untuk folder pub.
fudu
Dan masih tidak berhasil. :(
fudu
silakan periksa jawaban terakhir di halaman ini.
Sarfaraj Sipai