News:

Looking for documentation? Take a look on our wiki

Main Menu

support for AVIF

Started by hazael, January 10, 2025, 14:14:51 PM

Previous topic - Next topic

hazael

Does the new VM version support AVIF photos?
if not, in which files can I add support for this type of files and generating thumbnails?

hazael

#1
I added support for AVIF files – thumbnails are now generated, and everything works perfectly. I also improved the detection of WEBP files when uploading from a computer – previously, WEBP files were not displayed by default on the disk.
I'm currently working on handling SVG files - beta version. Of course, SVG already works and is displayed on the front page - you just need to create a replacement for the thumbnails in the admin panel😉

replace all code in file /administrator/components/com_virtuemart/helpers/img2thumb.php
<?php
defined
('_JEXEC') or die();

class 
Img2Thumb {

    var 
$bg_red;
    var 
$bg_green;
    var 
$bg_blue;
    var 
$maxSize;
    var 
$fileout;

    function 
__construct($filename$newxsize 60$newysize 60$fileout '',
        
$thumbMaxSize 0$bgred 0$bggreen 0$bgblue 0) {

        
VmConfig::ensureMemoryLimit(128);

        
$this->maxSize $thumbMaxSize true false;
        
$this->bg_red = ($bgred >= && $bgred <= 255) ? $bgred 0;
        
$this->bg_green = ($bggreen >= && $bggreen <= 255) ? $bggreen 0;
        
$this->bg_blue = ($bgblue >= && $bgblue <= 255) ? $bgblue 0;

        
$this->NewImgCreate($filename$newxsize$newysize$fileout);
    }

    private function 
NewImgCreate($filename$newxsize$newysize$fileout) {
        if (!
file_exists($filename)) {
            
vmError("The file does not exist: $filename");
            return 
false;
        }

        
$type $this->GetImgType($filename);
        if (!
$type) {
            
vmError("Unsupported image format: $filename");
            return 
false;
        }

        switch (
$type) {
            case 
"svg":
                return 
true;
            case 
"gif":
                
$orig_img function_exists("imagecreatefromgif") ? imagecreatefromgif($filename) : false;
                break;
            case 
"jpg":
                
$orig_img function_exists("imagecreatefromjpeg") ? imagecreatefromjpeg($filename) : false;
                break;
            case 
"png":
                
$orig_img function_exists("imagecreatefrompng") ? imagecreatefrompng($filename) : false;
                break;
            case 
"webp":
                
$orig_img function_exists("imagecreatefromwebp") ? imagecreatefromwebp($filename) : false;
                break;
            case 
"avif":
                if (
function_exists("imagecreatefromavif")) {
                    
$orig_img imagecreatefromavif($filename);
                } else {
                    
vmError("AVIF is not supported by GD");
                    return 
false;
                }
                break;

            default:
                
vmError("Unsupported format: $type");
                return 
false;
        }

        if (!
$orig_img) {
            
vmError("Unable to create image from file: $filename");
            return 
false;
        }

        
$new_img $this->NewImgResize($orig_img$newxsize$newysize$filename);
        if (!empty(
$fileout)) {
            
$this->NewImgSave($new_img$fileout$type);
        } else {
            
$this->NewImgShow($new_img$type);
        }

        
imagedestroy($new_img);
        
imagedestroy($orig_img);
    }

    private function 
NewImgResize($orig_img$newxsize$newysize$filename) {
        
$orig_size getimagesize($filename);
        if (!
$orig_size) return false;

        if (
$orig_size[0] < $orig_size[1]) {
            
$newxsize intval($newysize $orig_size[0] / $orig_size[1]);
        } else {
            
$newysize intval($newxsize $orig_size[1] / $orig_size[0]);
        }

        
$im_out imagecreatetruecolor($newxsize$newysize);

        if (
in_array($this->GetImgType($filename), ['png''webp''avif'])) {
            
imagealphablending($im_outfalse);
            
imagesavealpha($im_outtrue);
        }

        
imagecopyresampled($im_out$orig_img0000$newxsize$newysize$orig_size[0], $orig_size[1]);

        return 
$im_out;
    }

private function 
NewImgSave($new_img$fileout$type) {
    
$dir dirname($fileout);
    if (!
is_dir($dir) && !mkdir($dir0755true)) {
        
vmError("The directory could not be created: $dir");
        return 
false;
    }

    switch (
$type) {
        case 
"gif":
            if (
strtolower(substr($fileout, -4)) !== ".gif"$fileout .= ".gif";
            return 
imagegif($new_img$fileout);
        case 
"jpg":
        case 
"jpeg":
            if (
strtolower(substr($fileout, -4)) !== ".jpg"$fileout .= ".jpg";
            return 
imagejpeg($new_img$fileout70);
        case 
"png":
            if (
strtolower(substr($fileout, -4)) !== ".png"$fileout .= ".png";
            return 
imagepng($new_img$fileout);
        case 
"webp":
            if (
strtolower(substr($fileout, -5)) !== ".webp"$fileout .= ".webp";
            return 
imagewebp($new_img$fileout60);
        case 
"avif":
            if (!
function_exists("imageavif")) {
                
vmError("imageavif() is not supported by this server.");
                return 
false;
            }
            if (
strtolower(substr($fileout, -5)) !== ".avif"$fileout .= ".avif";
            return 
imageavif($new_img$fileout40);
    }

    
vmError("Unsupported file type: $type");
    return 
false;
}


    private function 
NewImgShow($new_img$type) {
        switch (
$type) {
            case 
"gif":
                
header("Content-type: image/gif");
                return 
imagegif($new_img);
            case 
"jpg":
                
header("Content-type: image/jpeg");
                return 
imagejpeg($new_img);
            case 
"png":
                
header("Content-type: image/png");
                return 
imagepng($new_img);
            case 
"webp":
                
header("Content-type: image/webp");
                return 
imagewebp($new_img);
            case 
"avif":
                
header("Content-type: image/avif");
                return 
imageavif($new_img);
        }

        
vmError("Unsupported output format: $type");
        return 
false;
    }

    private function 
GetImgType($filename) {
        
$imageExtensionsArray = [
            
IMAGETYPE_GIF => 'gif',
            
IMAGETYPE_JPEG => 'jpg',
            
IMAGETYPE_PNG => 'png',
            
IMAGETYPE_WEBP => 'webp',
            
IMAGETYPE_AVIF => 'avif'
        
];

        
$info getimagesize($filename);
        if (isset(
$imageExtensionsArray[$info[2]])) {
            return 
$imageExtensionsArray[$info[2]];
        }

      
$extension strtolower(pathinfo($filenamePATHINFO_EXTENSION));
        if (
$extension === "avif") {
            return 
"avif";
        }
        if (
$extension === "svg") {
            return 
"svg";
        }

        return 
false;
    }

    private function 
SaveDefaultSVG($fileout) {
        
$default_svg VmConfig::get('default_svg_thumbnail''images/no-thumbnail.svg');
        if (!
file_exists($default_svg)) {
            
vmError("The default SVG file does not exist: $default_svg");
            return 
false;
        }
        return 
copy($default_svg$fileout ".svg");
    }
}

In the file /administrator/components/com_virtuemart/helpers/mediahandler.php replace or modify functions:

isImage($file_url)
static private function isImage($file_url){
    $file_extension = strtolower(JFile::getExt($file_url));

    if(in_array($file_extension, ['jpg', 'jpeg', 'png', 'gif', 'webp', 'avif', 'svg'])) {
        return true;
    } else {
        vmTrace('is no image '.$file_url);
        return false;
    }
}
displaySupportedImageTypes
    function displaySupportedImageTypes() {
        $aSupportedTypes = array();

        $aPossibleImageTypeBits = array();

        if(defined('IMG_GIF')) {
            $aPossibleImageTypeBits[IMG_GIF] = 'GIF';
        }
        if(defined('IMG_JPG')) {
            $aPossibleImageTypeBits[IMG_JPG] = 'JPG';
        }
        if(defined('IMG_PNG')) {
            $aPossibleImageTypeBits[IMG_PNG] = 'PNG';
        }
        if(defined('IMG_WBMP')) {
            $aPossibleImageTypeBits[IMG_WBMP] = 'WBMP';
        }
        if(defined('IMG_WEBP')) {
            $aPossibleImageTypeBits[IMG_WEBP] = 'WEBP';
        }
        if(defined('IMG_AVIF')) {
            $aPossibleImageTypeBits[IMG_AVIF] = 'AVIF';
        }
        if(defined('IMG_SVG')) {
            $aPossibleImageTypeBits[IMG_SVG] = 'SVG';
        }
        foreach ($aPossibleImageTypeBits as $iImageTypeBits => $sImageTypeString) {

            if(function_exists('imagetypes')){
                if (imagetypes() & $iImageTypeBits) {
                    $aSupportedTypes[] = $sImageTypeString;
                }
            }
        }

        $supportedTypes = '';
        if(function_exists('mime_content_type')){
            $supportedTypes .= vmText::_('COM_VIRTUEMART_FILES_FORM_MIME_CONTENT_TYPE_SUPPORTED').'<br />';
        } else {
            $supportedTypes .= vmText::_('COM_VIRTUEMART_FILES_FORM_MIME_CONTENT_TYPE_NOT_SUPPORTED').'<br />';
        }

        $supportedTypes .= vmText::_('COM_VIRTUEMART_FILES_FORM_IMAGETYPES_SUPPORTED'). implode(', ', $aSupportedTypes);

        return $supportedTypes;
    }


In the file template /administrator/templates/vmadmin/html/com_virtuemart/sublayouts/image_upload.php

in line 50:
<input name="upload" accept="image/png, image/jpeg" type="file" id="vmuikit-js-upload-file">change to:
<input name="upload" accept="image/png, image/jpeg, image/webp, image/avif, image/svg+xml" type="file" id="vmuikit-js-upload-file">
in line 138:
allowedTypes:'jpg,png,gif,doc,pdf,zip',change to:
allowedTypes:'jpg,png,gif,doc,pdf,zip,avif,webp,svg',