Сжатие изображения во время загрузки дает черный фон в PHP ООП

Я уже упоминал ниже, что есть ответ в stackoverflow, но это не сработало для меня, потому что этот ответ похож на imagecreatetruecolor($width, $height), но в моем коде у меня нет ширины и высоты. Мой код совершенно другой. Пожалуйста, удалите этот повторяющийся тег.
Я пытаюсь сжать изображение во время загрузки, оно отлично сжимается для jpg изображений, но когда я загружаю png transparent изображение, оно сохраняется с черным фоном, я много гуглил но не нашел идеального решения по моему коду. Был ответ imagecreatetruecolor($width, $height), но в моем коде нет width and height variables, я полностью запутался и застрял.
Вот мой код функции:

public function updateProfilePic($file, $userid) {
    $filename = $file['user_img']['name'];
    $filetmp = $file['user_img']['tmp_name'];
    $valid_ext = array('png', 'jpeg', 'jpg');
    $location = "user/profilepic/" . $filename;
    $file_extension = pathinfo($location, PATHINFO_EXTENSION);
    $file_extensionstr = strtolower($file_extension);

    if(!empty($filename)){
        if (in_array($file_extensionstr, $valid_ext)) {
            $this->compressImage($filetmp, $location, 50);
            // Here I am trying to compress image

            return $this->updateProfilePicture($filename, $userid);
        } else {
            $msg = 'Invalid file type. You can upload only:-' . implode(', ', $valid_ext) . '';
            return $msg;
        }
    } else {
        $msg = 'Please upload your profile picture.';
        return $msg;
    }
}

public function compressImage($source, $destination, $quality) {
    $info = getimagesize($source);

    if ($info['mime'] == 'image/jpeg'){
        $image = imagecreatefromjpeg($source);
    } elseif ($info['mime'] == 'image/png'){
        $image = imagecreatefrompng($source);
    }

    imagejpeg($image, $destination, $quality);

}

Обновленный код того, что вы говорили:

public function compressImage($source, $destination, $quality) {
        $info = getimagesize($source);
        $width_new = $info[0];
        $height_new = $info[1];

        $dimg = imagecreatetruecolor($width_new, $height_new);
        $background = imagecolorallocate($dimg , 0, 0, 0);
        imagecolortransparent($dimg, $background);
        imagealphablending($dimg, false);
        imagesavealpha($dimg, true);

        if ($info['mime'] == 'image/jpeg'){
            $image = imagecreatefromjpeg($source);
        } elseif ($info['mime'] == 'image/png'){
            $image = imagecreatefrompng($source);
        }

        imagejpeg($image, $destination, $quality);

    }

Пожалуйста, сначала проверьте мой код, а затем сообщите мне решение. Пожалуйста, помогите мне


person Zain Shabir    schedule 21.10.2019    source источник


Ответы (1)


Мне кажется, это работает - метод compressImage просто был обернут в фиктивный класс для тестирования. Вызов метода, как показано, создает красивое прозрачное изображение PNG в выходном каталоге.

class fudd{

    public function __construct(){

    }

    public function compressImage( $source, $destination, $quality ) {
        list( $width, $height, $type, $attr ) = getimagesize( $source );
        $target=sprintf('%s/%s',$destination, pathinfo( $source, PATHINFO_BASENAME ) );
        $quality=$quality > 9 ? 5 : $quality;

        switch( image_type_to_mime_type( $type ) ){
            case 'image/jpeg':
                $image = imagecreatefromjpeg( $source );
                imagejpeg( $image, $target, $quality );
            break;
            case 'image/png':
                $image = imagecreatefrompng( $source );
                $bck   = imagecolorallocate( $image , 0, 0, 0 );
                imagecolortransparent( $image, $bck );
                imagealphablending( $image, false );
                imagesavealpha( $image, true );
                imagepng( $image, $target, $quality );
            break;
            default:
                exit( $type );
            break;              
        }
        imagedestroy( $image );
    }
}//end fudd



$img='c:/wwwroot/images/ict_cmyk_jigsaw_1.png';
$destination='c:/temp/fileuploads/stack/';
$quality=50;

$foo=new fudd;
$foo->compressImage( $img, $destination, $quality );

Результирующее изображение

Попробуйте так (используйте для изображения заранее заданное имя):

public function compressImage( $source, $destination, $quality ) {
    list( $width, $height, $type, $attr ) = getimagesize( $source );
    $quality=$quality > 9 ? 5 : $quality;

    switch( image_type_to_mime_type( $type ) ){
        case 'image/jpeg':
            $image = imagecreatefromjpeg( $source );
            imagejpeg( $image, $destination, $quality );
        break;
        case 'image/png':
            $image = imagecreatefrompng( $source );
            $bck   = imagecolorallocate( $image , 0, 0, 0 );
            imagecolortransparent( $image, $bck );
            imagealphablending( $image, false );
            imagesavealpha( $image, true );
            imagepng( $image, $destination, $quality );
        break;
        default:
            exit( $type );
        break;              
    }
    imagedestroy( $image );
}

Я быстро написал webp изображение, возможно, это будет интересно. ($destination необходимо отредактировать для вашего использования) ~ в основном подайте изображение одного из типов, показанных в теле метода (jpg, png, gif, webp), и установите сжатие / качество ~ далеко не полностью протестировано, хотя

public function createwebpimage( $source=false, $destination=null, $quality=50 ){
    if( $source ){

        list( $width, $height, $type, $attr ) = getimagesize( $source );
        $destination=sprintf( '%s/%s.webp', $destination, pathinfo( $source, PATHINFO_FILENAME ) );

        switch( image_type_to_mime_type( $type ) ){
            case 'image/jpeg':
                $image = imagecreatefromjpeg( $source );
            break;
            case 'image/png':
                $image = imagecreatefrompng( $source );
                $bck   = imagecolorallocate( $image , 0, 0, 0 );
                imagecolortransparent( $image, $bck );
                imagealphablending( $image, false );
                imagesavealpha( $image, true );
            break;
            case 'image/gif':
                $image = imagecreatefromgif( $source );
            break;
            case 'image/webp':
                $image=imagecreatefromwebp( $source );
            break;
            default:exit('invalid image type');
        }

        imagewebp( $image, $destination, $quality );
    }
}
person Professor Abronsius    schedule 21.10.2019
comment
Брат, у меня возникает ошибка после загрузки изображения Warning: imagepng(user/profilepic/executive-package.png/php1B94.tmp): failed to open stream: No such file or directory in E:\xampp\htdocs\zain\lunch\classes\User.php on line 402 --- executive_package.png - это мое изображение, но я не знаю, что это php1B94.tmp - person Zain Shabir; 21.10.2019
comment
Вам нужно будет отредактировать $target=sprintf('%s/%s',$destination, pathinfo( $source, PATHINFO_BASENAME ) ); в соответствии с моей системой. Предположительно ваша переменная destination user/profilepic/executive-package.png ??? - person Professor Abronsius; 21.10.2019
comment
что такое $destination? это user/profilepic/executive-package.png ?? - person Professor Abronsius; 21.10.2019
comment
да Это так: $location = "user/profilepic/" . $filename; и полный адрес http://localhost/zain/lunch/user/profilepic/$filename - person Zain Shabir; 21.10.2019
comment
PNG - это формат Lossless, и степень сжатия изображений / фотографий невысока. Не рекомендуется использовать PNG для больших изображений. Я пытался повторить то, что вы говорите, и наблюдал подобное поведение. Возможно, вы захотите изучить webp изображения - см. developers.google.com/speed/webp/gallery2 для сравнения размеров - person Professor Abronsius; 21.10.2019
comment
Аммммм. Работает нормально, чем раньше. На PNG изображении Увеличивается размер изображения не уменьшается / сжимается - person Zain Shabir; 21.10.2019
comment
да, это нормально. Пока он не дает черный фон. Это хорошо для меня - person Zain Shabir; 21.10.2019
comment
webp - это путь вперед - файлы гораздо меньшего размера и прозрачность - person Professor Abronsius; 21.10.2019