0

I am getting following error in php version 8.1.7 on running catalog resize cmd Deprecated Functionality: Implicit conversion from float 51.5 to int loses precision in /var/www/html/magento2/vendor/magento/framework/Image/Adapter/Gd2.php on line 963

2 Answers 2

3

I have also faced this issue and looks like this issue exists in the default Magento 2.4.4 for running PHP version 8.1, to reproduce this issue, please check the below steps to reproduce the issue:

  • Upload a product watermark logo in the theme configurations on the admin side.

  • Give the opacity as 100 and set the image poistion as center.

  • Flush the cache and make sure you have products with media present.

  • Run the magento command - bin/magento catalog:image:resize

  • You will get the error as Deprecated functionality, this error is mainly due to an in-built PHP function imagecopy() expects the function arguments as int data type and due to some math calculations, we are passing decimal data type.

  • For a temporary fix, please follow the below steps

  • Switch PHP version 7.4 in CLI

  • You may need to comment on some lines in the code for the file - platform_check.php, which is in this path - vendor/composer/platform_check.php

  • Comment lines 7,8,9

  • After that please run this magento command - bin/magento catalog:image:resize, this command will process the product images with the watermark logo and save it in the cache directory inside pub/media/catalog/product.

  • As I said this is a temporary fix, switch back again to PHP 8.1

  • Please check all the screenshots I have faced the error below, thanks!

enter image description here

New Update - Please follow the below steps for permanent solution via preference by over-riding the PHP file - Gd2.php if you are using that as image adapter

Di.xml file for preference

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Magento\Framework\Image\Adapter\Gd2" type="OX\ImageResizeFix\Image\Adapter\Gd2"/>
</config>

Preference for Gd2 Adapter to fix the Deprecated functionality issue

<?php

namespace OX\ImageResizeFix\Image\Adapter;

use BadFunctionCallException;
use InvalidArgumentException;

class Gd2 extends \Magento\Framework\Image\Adapter\Gd2
{

    /**
     * Image output callbacks by type
     *
     * @var array
     */
    private static $_callbacks = [
        IMAGETYPE_GIF => ['output' => 'imagegif', 'create' => 'imagecreatefromgif'],
        IMAGETYPE_JPEG => ['output' => 'imagejpeg', 'create' => 'imagecreatefromjpeg'],
        IMAGETYPE_PNG => ['output' => 'imagepng', 'create' => 'imagecreatefrompng'],
        IMAGETYPE_XBM => ['output' => 'imagexbm', 'create' => 'imagecreatefromxbm'],
        IMAGETYPE_WBMP => ['output' => 'imagewbmp', 'create' => 'imagecreatefromxbm'],
    ];

    /**
     * Obtain function name, basing on image type and callback type
     *
     * @param string $callbackType
     * @param null|int $fileType
     * @param string $unsupportedText
     * @return string
     * @throws InvalidArgumentException
     * @throws BadFunctionCallException
     */
    private function _getCallback($callbackType, $fileType = null, $unsupportedText = 'Unsupported image format.')
    {
        if (null === $fileType) {
            $fileType = $this->_fileType;
        }
        if (empty(self::$_callbacks[$fileType])) {
            throw new InvalidArgumentException($unsupportedText);
        }
        if (empty(self::$_callbacks[$fileType][$callbackType])) {
            throw new BadFunctionCallException('Callback not found.');
        }
        return self::$_callbacks[$fileType][$callbackType];
    }

    /**
     * Add watermark to image
     *
     * @param string $imagePath
     * @param int $positionX
     * @param int $positionY
     * @param int $opacity
     * @param bool $tile
     * @return void
     * @SuppressWarnings(PHPMD.UnusedLocalVariable)
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
     */
    public function watermark($imagePath, $positionX = 0, $positionY = 0, $opacity = 30, $tile = false)
    {
        list($watermarkSrcWidth, $watermarkSrcHeight, $watermarkFileType,) = $this->_getImageOptions($imagePath);
        $this->_getFileAttributes();
        $watermark = call_user_func(
            $this->_getCallback('create', $watermarkFileType, 'Unsupported watermark image format.'),
            $imagePath
        );

        $merged = false;

        $watermark = $this->createWatermarkBasedOnPosition($watermark, $positionX, $positionY, $merged, $tile);

        imagedestroy($watermark);
        $this->refreshImageDimensions();
    }

    /**
     * Create truecolor image copy of current image
     *
     * @return resource
     */
    private function createTruecolorImageCopy()
    {
        $this->_getTransparency($this->_imageHandler, $this->_fileType, $isAlpha);

        $newImage = imagecreatetruecolor($this->_imageSrcWidth, $this->_imageSrcHeight);

        if ($isAlpha) {
            $this->_saveAlpha($newImage);
        }

        imagecopy($newImage, $this->_imageHandler, 0, 0, 0, 0, $this->_imageSrcWidth, $this->_imageSrcHeight);

        return $newImage;
    }

    /**
     * Fixes saving PNG alpha channel
     *
     * @param resource $imageHandler
     * @return void
     */
    private function _saveAlpha($imageHandler)
    {
        $background = imagecolorallocate($imageHandler, 0, 0, 0);
        imagecolortransparent($imageHandler, $background);
        imagealphablending($imageHandler, false);
        imagesavealpha($imageHandler, true);
    }

    /**
     * Checks if image has alpha transparency
     *
     * @param resource $imageResource
     * @param int $fileType
     * @param bool $isAlpha
     * @param bool $isTrueColor
     *
     * @return boolean
     *
     * @SuppressWarnings(PHPMD.BooleanGetMethodName)
     */
    private function _getTransparency($imageResource, $fileType, &$isAlpha = false, &$isTrueColor = false)
    {
        $isAlpha = false;
        $isTrueColor = false;
        // assume that transparency is supported by gif/png only
        if (IMAGETYPE_GIF === $fileType || IMAGETYPE_PNG === $fileType) {
            // check for specific transparent color
            $transparentIndex = imagecolortransparent($imageResource);
            if ($transparentIndex >= 0) {
                return $transparentIndex;
            } elseif (IMAGETYPE_PNG === $fileType) {
                // assume that truecolor PNG has transparency
                $isAlpha = $this->checkAlpha($this->_fileName);
                $isTrueColor = true;
                // -1
                return $transparentIndex;
            }
        }
        if (IMAGETYPE_JPEG === $fileType) {
            $isTrueColor = true;
        }
        return false;
    }

    /**
     * Helper function to free up memory associated with _imageHandler resource
     *
     * @return void
     */
    private function imageDestroy()
    {
        if (is_resource($this->_imageHandler)) {
            imagedestroy($this->_imageHandler);
        }
    }

    /**
     * Fix an issue with the usage of imagecopymerge where the alpha channel is lost
     *
     * @param resource $dst_im
     * @param resource $src_im
     * @param int $dst_x
     * @param int $dst_y
     * @param int $src_x
     * @param int $src_y
     * @param int $src_w
     * @param int $src_h
     * @param int $pct
     * @return bool
     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
     * @SuppressWarnings(PHPMD.NPathComplexity)
     */
    private function imagecopymergeWithAlphaFix(
        $dst_im,
        $src_im,
        $dst_x,
        $dst_y,
        $src_x,
        $src_y,
        $src_w,
        $src_h,
        $pct
    ) {
        if ($pct >= 100) {
            if (false === imagealphablending($dst_im, true)) {
                return false;
            }
            return imagecopy($dst_im, $src_im, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h);
        }

        if ($pct < 0) {
            return false;
        }

        $sizeX = imagesx($src_im);
        $sizeY = imagesy($src_im);
        if (false === $sizeX || false === $sizeY) {
            return false;
        }

        $tmpImg = imagecreatetruecolor($src_w, $src_h);
        if (false === $tmpImg) {
            return false;
        }

        if (false === imagealphablending($tmpImg, false)) {
            return false;
        }

        if (false === imagesavealpha($tmpImg, true)) {
            return false;
        }

        if (false === imagecopy($tmpImg, $src_im, 0, 0, 0, 0, $sizeX, $sizeY)) {
            return false;
        }

        $transparency = (int) (127 - (($pct * 127) / 100));
        if (false === imagefilter($tmpImg, IMG_FILTER_COLORIZE, 0, 0, 0, $transparency)) {
            return false;
        }

        if (false === imagealphablending($dst_im, true)) {
            return false;
        }

        if (false === imagesavealpha($dst_im, true)) {
            return false;
        }

        $result = imagecopy($dst_im, $tmpImg, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h);
        imagedestroy($tmpImg);

        return $result;
    }

    /**
     * Create watermark based on it's image position.
     *
     * @param resource $watermark
     * @param int $positionX
     * @param int $positionY
     * @param bool $merged
     * @param bool $tile
     * @return false|resource
     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
     * @SuppressWarnings(PHPMD.NPathComplexity)
     */
    private function createWatermarkBasedOnPosition(
        $watermark,
        int $positionX,
        int $positionY,
        bool $merged,
        bool $tile
    )
    {
        if ($this->getWatermarkWidth() &&
            $this->getWatermarkHeight() &&
            $this->getWatermarkPosition() != self::POSITION_STRETCH
        ) {
            $watermark = $this->createWaterMark($watermark, $this->getWatermarkWidth(), $this->getWatermarkHeight());
        }

        /**
         * Fixes issue with watermark with transparent background and an image that is not truecolor (e.g GIF).
         * blending mode is allowed for truecolor images only.
         * @see imagealphablending()
         */
        if (!imageistruecolor($this->_imageHandler)) {
            $newImage = $this->createTruecolorImageCopy();
            $this->imageDestroy();
            $this->_imageHandler = $newImage;
        }

        if ($this->getWatermarkPosition() == self::POSITION_TILE) {
            $tile = true;
        } elseif ($this->getWatermarkPosition() == self::POSITION_STRETCH) {
            $watermark = $this->createWaterMark($watermark, $this->_imageSrcWidth, $this->_imageSrcHeight);
        } elseif ($this->getWatermarkPosition() == self::POSITION_CENTER) {
            $positionX = (int)($this->_imageSrcWidth / 2 - imagesx($watermark) / 2);
            $positionY = (int)($this->_imageSrcHeight / 2 - imagesy($watermark) / 2);
            $this->imagecopymergeWithAlphaFix(
                $this->_imageHandler,
                $watermark,
                $positionX,
                $positionY,
                0,
                0,
                imagesx($watermark),
                imagesy($watermark),
                $this->getWatermarkImageOpacity()
            );
        } elseif ($this->getWatermarkPosition() == self::POSITION_TOP_RIGHT) {
            $positionX = $this->_imageSrcWidth - imagesx($watermark);
            $this->imagecopymergeWithAlphaFix(
                $this->_imageHandler,
                $watermark,
                $positionX,
                $positionY,
                0,
                0,
                imagesx($watermark),
                imagesy($watermark),
                $this->getWatermarkImageOpacity()
            );
        } elseif ($this->getWatermarkPosition() == self::POSITION_TOP_LEFT) {
            $this->imagecopymergeWithAlphaFix(
                $this->_imageHandler,
                $watermark,
                $positionX,
                $positionY,
                0,
                0,
                imagesx($watermark),
                imagesy($watermark),
                $this->getWatermarkImageOpacity()
            );
        } elseif ($this->getWatermarkPosition() == self::POSITION_BOTTOM_RIGHT) {
            $positionX = $this->_imageSrcWidth - imagesx($watermark);
            $positionY = $this->_imageSrcHeight - imagesy($watermark);
            $this->imagecopymergeWithAlphaFix(
                $this->_imageHandler,
                $watermark,
                $positionX,
                $positionY,
                0,
                0,
                imagesx($watermark),
                imagesy($watermark),
                $this->getWatermarkImageOpacity()
            );
        } elseif ($this->getWatermarkPosition() == self::POSITION_BOTTOM_LEFT) {
            $positionY = $this->_imageSrcHeight - imagesy($watermark);
            $this->imagecopymergeWithAlphaFix(
                $this->_imageHandler,
                $watermark,
                $positionX,
                $positionY,
                0,
                0,
                imagesx($watermark),
                imagesy($watermark),
                $this->getWatermarkImageOpacity()
            );
        }

        if ($tile === false && $merged === false) {
            $this->imagecopymergeWithAlphaFix(
                $this->_imageHandler,
                $watermark,
                $positionX,
                $positionY,
                0,
                0,
                imagesx($watermark),
                imagesy($watermark),
                $this->getWatermarkImageOpacity()
            );
        } else {
            $offsetX = $positionX;
            $offsetY = $positionY;
            while ($offsetY <= $this->_imageSrcHeight + imagesy($watermark)) {
                while ($offsetX <= $this->_imageSrcWidth + imagesx($watermark)) {
                    $this->imagecopymergeWithAlphaFix(
                        $this->_imageHandler,
                        $watermark,
                        $offsetX,
                        $offsetY,
                        0,
                        0,
                        imagesx($watermark),
                        imagesy($watermark),
                        $this->getWatermarkImageOpacity()
                    );
                    $offsetX += imagesx($watermark);
                }
                $offsetX = $positionX;
                $offsetY += imagesy($watermark);
            }
        }

        return $watermark;
    }

    /**
     * Create watermark.
     *
     * @param resource $watermark
     * @param string $width
     * @param string $height
     * @return false|resource
     */
    private function createWaterMark($watermark, string $width, string $height)
    {
        $newWatermark = imagecreatetruecolor($width, $height);
        imagealphablending($newWatermark, false);
        $col = imagecolorallocate($newWatermark, 255, 255, 255);
        imagecolortransparent($newWatermark, $col);
        imagefilledrectangle($newWatermark, 0, 0, $width, $height, $col);
        imagesavealpha($newWatermark, true);
        imagecopyresampled(
            $newWatermark,
            $watermark,
            0,
            0,
            0,
            0,
            $width,
            $height,
            imagesx($watermark),
            imagesy($watermark)
        );

        return $newWatermark;
    }


}
2
  • I faced the same issue, images were not showing up on the detail page. I ran the resize command and got this same error. I have applied these changes and ran again the resize command. Given solutions work for me. Thank You @Bharath Kumar J Commented Dec 8, 2022 at 21:41
  • Glad it worked @SureshChikani. Commented Dec 9, 2022 at 8:45
0

Basically Had the same issue and the solution was

Whatever is giving you the long number

ie;

$dims['frame']['width']

change to

intval($dims['frame']['width'])

Mine was Magento 2.4.4

Problem:

$newImage = imagecreatetruecolor($dims['frame']['width'], $dims['frame']['height']);

Solution:

$newImage = imagecreatetruecolor(intval($dims['frame']['width']), >intval($dims['frame']['height']));

......

1
  • above code try but it's not working @Dennies van Schaik Commented Dec 28, 2023 at 10:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.