PHP проблемы с форматом webp

sanu0074

Новичок
Здравствуйте. написал класс который сохраняет на сервер картинки в формате webp.
Проблема в том что функции imagecreatefromwebp() и imagewebp() почему-то у меня криво сохраняют результат.
Есть несколько случаев в которых возникает проблема:
1. если исходное изображение в формате webp, то после того как мы его пере сохраним на сервере ( imagecreatefromwebp() ) появляются проблемы с цветами (например если изображение было с синими оттенками, они превращаются в зеленые)
2. если исходное изображение в формате jpg, в классе мы из оригинала делаем несколько миниатюр и сохраняем их в webp, т.е. получаем 4 перекодированных в webp картинки (оригинал и 3 миниатюры), и обычно не все картинки открываются, получается то 2 webp миниатюры работают а остальных две битые, или одна битая а три нормально открываются. и так по разному с одними и теми же картинками и всеми данными.
3. то же самое что и в п.2 касается всех остальных исходных форматов (png, gif, jpeg)
4. на некоторые исходные картинки webp может так ругаться: imagecreatefromwebp(): WebP decode: fail to decode input data (брал их с PlayGoogle)
5. иногда при исходном формате webp, возникают проблемы что описаны в п.2

Тестил на разных системах и разных компьютерах с разным железом. Конфиг везде был: PHP 5.5.3, Apache 2.4
Ниже с кодом, выкладываю архив с выходными изображениями перекодированные из разных исходных форматов.
PHP:
	public function upload($mini=TRUE)	//загружаем изображения
	{
		if(preg_match('/[.](JPG)|(jpg)|(jpeg)|(JPEG)|(gif)|(GIF)|(png)|(PNG)|(webp)|(WEBP)$/',$this->name)){ //проверка формата                     
            $target = $this->uploadFolder.$this->name;
            move_uploaded_file($this->tmpName, $target);//загрузка оригинала в папку $path_to_90_directory 
			  if(preg_match('/[.](GIF)|(gif)$/', $this->name)){
				 $src = imagecreatefromgif($target) ; //если оригинал был в формате gif, то создаем    изображение в этом же формате 
			  }
			  if(preg_match('/[.](PNG)|(png)$/', $this->name)){
				 $src = imagecreatefrompng($target) ;//если    оригинал был в формате png, то создаем изображение в этом же формате
			  }
			  if(preg_match('/[.](JPG)|(jpg)|(jpeg)|(JPEG)$/', $this->name)){
				 $src = imagecreatefromjpeg($target); //если оригинал был в формате jpg, то создаем изображение в этом же формате 
			  }
			  if(preg_match('/[.](webp)|(WEBP)$/', $this->name)){
				 $src = imagecreatefromwebp($target); //если оригинал был в формате webp, то создаем изображение в этом же формате 
			  }
		}

		$w_src = imagesx($src); 	//ширина и высота исходника
		$h_src = imagesy($src);
		
		$dest = imagecreatetruecolor($w_src,$h_src); //новое изображение
		imagealphablending($dest, TRUE);
		imagesavealpha($dest, TRUE);
		imagecopyresized($dest, $src, 0, 0, 0, 0, $w_src, $h_src, $w_src, $h_src);		
		if($this->logo==TRUE){ 	//если нужно наложить логотип
		  $logo_im=imagecreatefrompng('img/logo_nakl.png');
		  $w_logo_im = imagesx($logo_im); 
		  $h_logo_im = imagesy($logo_im);
		  imagecopyresized($dest, $logo_im, $w_src-$w_logo_im-5, $h_src-$h_logo_im-5, 0, 0, $w_logo_im, $h_logo_im, $w_logo_im, $h_logo_im);
	    }
		 
		$this->save($dest,"_ORIG");	//сохраняем в нужном формате
		imagedestroy($dest);		//удаляем образ
		
		if($mini==TRUE){	//создаем миниатюры
		  $this->createMini($src,"_MINI_230",$w_src,$h_src,230);
		  $this->createMini($src,"_MINI_400",$w_src,$h_src,400);
		  $this->createMini($src,"_MINI_550",$w_src,$h_src,550);
		}
		
		imagedestroy($src); //удаляем осн
		unlink($target);	//удаляем оригинал
	 
	}
	
	private function createMini($src,$name,$w,$h,$fix_w){	//создает миниатюры
		$k=$h/$fix_w;								//вычисляем коэф
		$new_w=ceil ($w/$k);						//вычисляем новую ширину на основе заданной
		$dst=imagecreatetruecolor($new_w,$fix_w);	//создаем изображение и переносим с масштабом
		imagecopyresampled($dst, $src, 0, 0, 0, 0, $new_w, $fix_w, $w, $h);
		$this->save($dst,$name);					//сохраняем результат
		imagedestroy($dst);							 
	}
	
	private function save($dest,$name){			//сохраняет изображение в заданном формате
		switch($this->format){
		  case ".webp": imagewebp($dest,$this->uploadFolder.$this->newName.$name.$this->format); break;
		  case ".png":  imagepng($dest,$this->uploadFolder.$this->newName.$name.$this->format); break;
		  case ".jpg":  imagejpeg($dest,$this->uploadFolder.$this->newName.$name.$this->format); break;
		  case ".gif":  imagegif($dest,$this->uploadFolder.$this->newName.$name.$this->format); break;
		}
	}
 

Вложения

WMix

герр M:)ller
Партнер клуба
1. непонимаю я тягу к такой эххзотике

но возможно причина кроется тут
http://ru.wikipedia.org/wiki/WebP
Как и VP8, поддерживает только формат 8-bit YUV 4:2:0[15], что может быть причиной потери цвета на изображениях с 1-пиксельными контрастными переходами, например в пиксельарте и компьютерной графике.
2. '/[.](JPG)|(jpg)|(jpeg)|(JPEG)|(gif)|(GIF)|(png)|(PNG)|(webp)|(WEBP)$/'
существует i модификатор
http://www.php.net/manual/ru/reference.pcre.pattern.modifiers.php

if(preg_match('/[.](GIF)|(gif)$/', $this->name)){...}
if(preg_match('/[.](PNG)|(png)$/', $this->name)){...}
...
3. читать http://de1.php.net/manual/ru/function.pathinfo.php

4. нет смысла готовый формат конвентировать в тотже формат - не забывай про постоянную потерю

5. пользуйся готовыми библиотеками (к примеру http://imagine.readthedocs.org/en/latest/), если нет понятия как работают с изображениями для чего используются те или иные комманды
 
Последнее редактирование:

sanu0074

Новичок
4. нет смысла готовый формат конвентировать в тотже формат - не забывай про постоянную потерю
Смысл в том чтобы сделать ресайз.
5. пользуйся готовыми библиотеками (к примеру http://imagine.readthedocs.org/en/latest/), если нет понятия как работают с изображениями для чего используются те или иные комманды
Разве imagine поддерживает WEBP ??
 

WMix

герр M:)ller
Партнер клуба
не, не поддерживает, но можно же добавить ;) или подглядеть сложные моменты
я к тому что такие ошибки можно уже самому решать, как-то гуповато с одной стороны тема специфична с другой стороны вопросы логики и дебага плюс кусок кучи говнокода без начала и конца с просьбой почитать
локализируй ошибку уже и с конкретным вопросом обращайся
 
Сверху