Magento 2:カスタムモジュールのサイズ変更画像を取得する方法?


12

Magento 2 CEバージョン2.1.0を使用しています

画像フィールド付きのカスタムモジュールがあります。アップロードしたとき、サムネイル画像、リスト画像、製品詳細ページの画像がある製品とは異なるサイズの画像が必要です。

サイズを変更せずに1つの画像をアップロードできます。

以下のコードを使用して画像のサイズを変更していますが、製品の画像のURLを提供しています。私のカスタムモジュールではありません。

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

以下の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でカスタムイメージのサイズを変更するをクリックして詳細を確認できます。

ブロックファイル内はコードの下に保持し、

   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 2016

1つの画像のサイズを変更して同じフォルダに同じ画像を入れようとすると、機能しません。このように:$ 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 /').$ image;
fudu 2018

すでに述べたように、これは受け入れられる答えではありません。これらすべてを自分で行う必要はありません。Magentoコアの既存のイメージヘルパーを使用するだけです。
fritzmg 2018

@ RakeshJesadiya、URLとして不明なテキストが表示される
Hitesh Balpande

13

受け入れられた答えは、パフォーマンスを向上させるために画像をキャッシュすることを考慮していません。要求されるたびに画像のサイズを変更して上書きする必要はありません。次のアプローチでは、サイズ変更された画像を「キャッシュ」フォルダーに保存するため、連続して呼び出すとキャッシュから画像が返されます。メソッドはヘルパー(ブロックではなく)に含まれているため、好きなテンプレートから呼び出すことができます。

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

これで、任意の.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); ?>">

元のファイルが存在しない場合に備えて、チェックを追加することを提案できますか?resize()関数内:私は次のif (!$this->_fileExists($path . $image)) {ように変更しましたif (!$this->_fileExists($path . $image) && $this->_fileExists($mediaFolder . $image)) {
AlexandruBangală2017

ありがとうございます。これが受け入れ答えなければなりません
富都

既存のをそのまま使用することもでき\Magento\Catalog\Helper\Imageます。
fritzmg 2018

1
@fritzmgは、このヘルパーが製品の画像のみを対象としているのではないですか?製品イメージではなく、カスタムモジュールを使用して/ pub / mediaフォルダーにアップロードされ、製品とは関係のないカスタムイメージでどのように使用できますか?
コヴィネット

1
@kovinet-元の画像がpub / media /フォルダーに含まれている限り、どの画像でも機能します。画像のパスを$ image-> resize( 'image / path / filename.ext');に渡すだけです。
ダニエル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のみだと思います)でも確認できます。


しかし、あなたの例は製品画像でしか機能しませんよね?問題は、Imageフィールドを持つカスタムモジュールに関するものです。したがって$product、/ media内のイメージファイルへのパスはありません。
kovinet 2018年

あなたは正しい@kovinetです。気づかなかった。しかし、このスレッドは私に製品の画像を助け、それは他の人を助けるようです。でもコメントありがとうございます。時間があるとすぐに、もっと良い答えを探します。;)
リカルドマルティンス

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エラーフィルタリングテンプレート:警告: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

C:/xampp/htdocs/magento/pub/media/Aht_BannerSlider/images/slide_1.jpgにAht_BannerSlider / images / slide_1.jpgフォルダーがありません。また、pubフォルダーのアクセス許可を与えています。
fudu '14

そして、それでも動作しません。:(
fudu 2018

このページの最後の回答を確認してください。
Sarfaraj Sipai
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.