Magento 2: Wie kann ich die Bildgröße für ein benutzerdefiniertes Modul ändern?


12

Ich verwende Magento 2 CE Version 2.1.0

Ich habe ein benutzerdefiniertes Modul mit Bildfeld. Wenn es hochgeladen wird, möchte ich Bilder unterschiedlicher Größe, da wir für das Produkt ein Miniaturbild, ein Listenbild und ein Produktdetailseitenbild haben.

Kann 1 Bild ohne Größenänderung hochladen.

Ich verwende den folgenden Code zum Ändern der Bildgröße, aber er gibt die Produktbild-URL an. Nicht mein benutzerdefiniertes Modul.

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

Es gibt die folgende URL an : http: //localhost/magento2/pub/static/frontend/Magento/luma/en_US/Magento_Catalog/images/product/placeholder/.jpg

Mein Bild ist hier gespeichert : \magento2\pub\media\custom_module\posts\image.

Wie kann ich mit diesem Pfad die Bildgröße ändern und wie kann ich Bilder unterschiedlicher Größe speichern / abrufen?

Antworten:


15

Sie können Details einchecken, indem Sie in Magento 2 auf Größe des benutzerdefinierten Bilds ändern klicken

Innerhalb der Blockdatei unter Code halten,

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

Rufen Sie jetzt in der HTML-Datei auf,

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

Bravo. Funktioniert perfekt. Während wir also Bild hinzufügen, müssen wir nicht mit unterschiedlichen Größen hochladen. Nur während der Anzeige müssen wir korrektes @Rakesh verwalten?
Ankit Shah

1
ja wenn wir zu diesem zeitpunkt verwalten müssen.
Rakesh Jesadiya

funktioniert nicht, wenn wir versuchen, die Größe eines Bildes zu ändern und es in denselben Ordner mit demselben Bild zu legen. wie folgt: $ absolutePath = $ this -> _ Dateisystem-> getDirectoryRead (\ Magento \ Framework \ App \ Dateisystem \ DirectoryList :: MEDIA) -> getRelativePath ('C: / xampp / htdocs / magento / app / code / Aht / BannerSlider /view/frontend/web/').$image; $ imageResized = $ this -> _ Dateisystem-> getDirectoryRead (\ Magento \ Framework \ App \ Dateisystem \ DirectoryList :: MEDIA) -> getRelativePath ('C: / xampp / htdocs / magento / app / code / Aht / BannerSlider / view / Frontend / Web /').$ Bild;
Fudu

Wie bereits erwähnt, sollte dies nicht die akzeptierte Antwort sein. Sie müssen dies nicht alles selbst tun - verwenden Sie einfach den bereits vorhandenen Image-Helfer des Magento-Kerns.
fritzmg

@ RakeshJesadiya, es gibt mir unbekannten Text als URL
Hitesh Balpande

13

Die akzeptierte Antwort berücksichtigt nicht das Zwischenspeichern des Bildes, um die Leistung zu verbessern. Sie müssen die Größe des Bildes nicht jedes Mal ändern und überschreiben, wenn es angefordert wird. Der folgende Ansatz speichert das verkleinerte Bild in einem "Cache" -Ordner, sodass aufeinanderfolgende Aufrufe das Bild aus dem Cache zurückgeben. Die Methode ist in einem Helfer (nicht in einem Block) enthalten, sodass Sie sie aus einer beliebigen Vorlage aufrufen können:

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

Jetzt können Sie aus jeder .phtml-Vorlage die Methode wie folgt aufrufen:

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

Darf ich vorschlagen, eine Prüfung für die Originaldatei hinzuzufügen, falls diese nicht vorhanden ist? in der resize () Funktion: Ich wechselte if (!$this->_fileExists($path . $image)) {zuif (!$this->_fileExists($path . $image) && $this->_fileExists($mediaFolder . $image)) {
Alexandru Bangală

Arbeite wie ein Zauber, danke. Dies sollte die akzeptierte Antwort sein
Fudu

Sie können auch einfach das vorhandene verwenden \Magento\Catalog\Helper\Image.
Fritzmg

1
@fritzmg ist dieser Helfer nicht nur für Produktbilder gedacht? Wie kann ich es mit einem benutzerdefinierten Bild verwenden, das kein Produktbild ist, sondern ein Bild, das mit einem benutzerdefinierten Modul in den Ordner / pub / media hochgeladen wurde und keine Beziehung zum Produkt hat?
Kovinet

1
@kovinet - Funktioniert mit jedem Bild, solange das Originalbild im Ordner pub / media / enthalten ist. Übergeben Sie einfach den Pfad des Bildes an $ image-> resize ('image / path / filename.ext');
Daniel Kratohvil

3

Ich fürchte, Sie müssen keine neuen Klassen erstellen, um die Größe Ihrer Bilder zu ändern, da Magento-Helfer diese bereits haben (siehe \Magento\Catalog\Helper\Image::resize).

Sie können also einfach Folgendes tun:

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

Ein Beispiel für diese Verwendung finden Sie auch unter \Magento\VisualMerchandiser\Block\Adminhtml\Category\Merchandiser\Tile::getImageUrl(Magento EE nur, denke ich)


Aber Ihr Beispiel würde nur mit Produktbildern funktionieren, oder? Die Frage bezieht sich auf ein benutzerdefiniertes Modul mit Bildfeld. Es gibt also keinen, $productsondern nur einen Pfad zur Bilddatei in / media.
Kovinet

Sie haben Recht @kovinet. Ich habe es damals nicht bemerkt. Dieser Thread hat mir jedoch bei Produktbildern geholfen, und er scheint anderen zu helfen. Aber danke für deinen Kommentar. Sobald ich etwas Zeit habe, werde ich nach einer besseren Antwort suchen. ;)
Ricardo Martins

1

Ich habe ein Problem festgestellt, bei dem die resizeMethode das Bild nicht auf meine Abmessungen zuschneidet. Daher müssen Sie die Zuschneidewerte je nach Originalbildgröße von oben und unten oder von links und rechts berechnen. Ich habe den Code von @Rakesh verwendet und ihn so geändert, dass überprüft wird, ob das Originalbild größer oder breiter ist, und entsprechend zugeschnitten wird:

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 - Ich habe das gleiche getan, aber es funktioniert nicht für mich, es liegt ein Fehler vor

Blockquote Fehlerfiltervorlage: Warnung: getimagesize (/var/www/html/sitename/pub/media/onecategory/6/7/671471390.jpg): Stream konnte nicht geöffnet werden: Keine solche Datei oder kein solches Verzeichnis in / var / www / html /sitename/vendor/magento/framework/Image/Adapter/AbstractAdapter.php in Zeile 304

Kannst du mir dabei helfen?

Vielen Dank.


Finden Sie die Lösung? Weil ich jetzt in deiner Situation bin. :(
Fudu

Bitte überprüfen Sie die Ordner- oder Dateiberechtigung.
Sarfaraj Sipai

hat keinen Ordner Aht_BannerSlider / images / slide_1.jpg in C: /xampp/htdocs/magento/pub/media/Aht_BannerSlider/images/slide_1.jpg, und ich habe auch nur die Erlaubnis für den Pub-Ordner gegeben.
Fudu

Und funktioniert immer noch nicht. :(
Fudu

Bitte überprüfen Sie die letzte Antwort auf dieser Seite.
Sarfaraj Sipai
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.