Magento 2: ¿Cómo cambiar el tamaño de la imagen para el Módulo personalizado?

12

Estoy usando Magento 2 CE Versión 2.1.0

Tengo un módulo personalizado con campo de imagen. Cuando se carga, quiero imágenes de diferentes tamaños en cuanto al producto que tenemos Imagen en miniatura, Imagen de lista e Imagen de página de detalles del producto.

Capaz de cargar 1 imagen sin cambiar el tamaño.

Estoy usando el siguiente código para cambiar el tamaño de la imagen, pero proporciona la URL de la imagen del producto. No es mi módulo personalizado.

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

Da a continuación la URL http: //localhost/magento2/pub/static/frontend/Magento/luma/en_US/Magento_Catalog/images/product/placeholder/.jpg

Mi imagen se almacena aquí: \magento2\pub\media\custom_module\posts\image.

¿Cómo puedo cambiar el tamaño de la imagen con esta ruta y cómo puedo guardar / recuperar imágenes de diferentes tamaños?

Ankit Shah
fuente

Respuestas:

15

Puede verificar los detalles haciendo clic en Cambiar tamaño de imagen personalizada en Magento 2

Dentro del archivo de bloqueo, mantenga el siguiente código,

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

Ahora llame dentro del archivo phtml,

$block->resize('test.jpg',500,400);
Rakesh Jesadiya
fuente
Bravo. Funciona perfectamente. Entonces, mientras que Agregar imagen no tenemos que cargar con diferentes tamaños. ¿Solo durante la visualización tenemos que gestionar correctamente @Rakesh?
Ankit Shah
1
Sí, cuando tenemos que mostrar en ese momento administrar.
Rakesh Jesadiya
no funciona cuando intentamos cambiar el tamaño de 1 imagen y ponerla en la misma carpeta con la misma imagen. así: $ 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 /').$ imagen;
Fudu
Como ya se mencionó, esta no debería ser la respuesta aceptada. No necesita hacer todo esto usted mismo, simplemente use el ayudante de imagen ya existente del núcleo de Magento.
fritzmg
@ RakeshJesadiya, me da un texto desconocido como una url
Hitesh Balpande
13

La respuesta aceptada no considera el almacenamiento en caché de la imagen para mejorar el rendimiento. No necesita cambiar el tamaño y sobrescribir la imagen cada vez que se solicita. El siguiente enfoque guarda la imagen redimensionada en una carpeta "caché" para que las llamadas sucesivas devuelvan la imagen del caché. El método está contenido en un asistente (no en un bloque) para que pueda llamarlo desde cualquier plantilla que desee:

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

Ahora desde cualquier plantilla .phtml puedes llamar al método de esta manera:

<!-- 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
fuente
¿Puedo sugerir agregar un cheque para el archivo original, en caso de que no exista? en la función if (!$this->_fileExists($path . $image)) {if (!$this->_fileExists($path . $image) && $this->_fileExists($mediaFolder . $image)) {
resize
Trabaja como un encanto, gracias. Esta debería ser la respuesta aceptada
fudu
También puede simplemente usar el existente \Magento\Catalog\Helper\Image.
fritzmg
1
@fritzmg ¿este ayudante no está destinado solo para imágenes de productos? ¿Cómo puedo usarlo con una imagen personalizada que no es una imagen del producto sino una imagen cargada con un módulo personalizado en la carpeta / pub / media y no tiene relación con el producto?
kovinet
1
@kovinet: funciona con cualquier imagen siempre que la imagen original esté contenida en la carpeta pub / media /. Simplemente pase la ruta de la imagen a $ image-> resize ('image / path / filename.ext');
Daniel Kratohvil
3

Me temo que no necesita crear nuevas clases para cambiar el tamaño de sus imágenes, ya que los ayudantes de Magento ya lo tienen (ver \Magento\Catalog\Helper\Image::resize).

Entonces, solo puedes hacer:

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

También puede ver un ejemplo de este uso en \Magento\VisualMerchandiser\Block\Adminhtml\Category\Merchandiser\Tile::getImageUrl(Magento EE, supongo)

Ricardo Martins
fuente
Pero su ejemplo solo funcionaría con imágenes de productos, ¿verdad? La pregunta es sobre el módulo personalizado con el campo Imagen. Por lo tanto, no hay una $productúnica ruta al archivo de imagen en / media.
kovinet
Tienes razón @kovinet. No lo noté en ese momento. Sin embargo, este hilo me ayudó con imágenes de productos, y parece que está ayudando a otros. Pero gracias por tu comentario. En cuanto tenga algo de tiempo, buscaré una mejor respuesta. ;)
Ricardo Martins
1

Me encontré con un problema en el que el resizemétodo no recortaba la imagen a mis dimensiones, por lo que debe calcular los valores de recorte de arriba a abajo o de izquierda a derecha, según el tamaño de la imagen original. Usé el código de @Rakesh y lo modifiqué para que compruebe si la imagen original es más alta o más ancha y recorta en consecuencia:

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
fuente
0

@Rakesh: he hecho lo mismo pero no funciona, hay un error

Plantilla de filtrado de errores de Blockquote: Advertencia: getimagesize (/var/www/html/sitename/pub/media/onecategory/6/7/671471390.jpg): no se pudo abrir la secuencia: No existe tal archivo o directorio en / var / www / html /sitename/vendor/magento/framework/Image/Adapter/AbstractAdapter.php en la línea 304

Puedes ayudarme en esto.

Gracias.

Sarfaraj Sipai
fuente
¿Encuentras la solución? Porque estoy en tu situación ahora. :(
fudu
por favor verifique el permiso de carpeta o archivo.
Sarfaraj Sipai
no tiene la carpeta Aht_BannerSlider / images / slide_1.jpg en C: /xampp/htdocs/magento/pub/media/Aht_BannerSlider/images/slide_1.jpg, y también acabo de dar permiso para la carpeta pub.
Fudu
Y aún no funciona. :(
fudu
por favor verifique la última respuesta en esta página.
Sarfaraj Sipai