Юрий П.
70 сообщений
#12 лет назад
Уважаемые программисты, помогите решить вопрос.
Изображения форматов PNG и GIF после загруки на сайт отображаются черном фоне.

Здесь видно:

Как можно решить эту проблему? Кто-нибудь сталкивался с подобным?
Роман Беляев
16382 сообщения
#12 лет назад
yurec2073, чем ресайзите? GD? Используйте imagemagick.
Юрий П.
70 сообщений
#12 лет назад
frig, К сожалению не могу быть уверен чем ресайз делается, потому как скрипт писал не я.
Наверное GD.

Спаисбо. Буду искать информацию по ImageMagick, разбираться.
Владимир Коваль
65 сообщений
#12 лет назад
Если серверная часть написана на php, то для обработки png изображений с прозрачностью используйте

imagealphablending($tmb, false);
imagesavealpha($tmb, true);

$tmb - временное изображение

С gif - есть по сути один вариант - не изменять сам файл (да и зачем изменять изображение в формате gif?)
Юрий П.
70 сообщений
#12 лет назад
vovikov84, Спасибо за совет, но это есть и к сожалению не работает...
Здесь код функции.

//пропорциональное измнение размера
function resize($img, $new_img, $nw, $nh, $quality){
$width = $nw;
$height = $nh;

$extension=$this->findexts($img);
$pic=$this->create($img, $extension);
list($width_orig, $height_orig) = getimagesize($img);
$ratio_orig = $width_orig/$height_orig;
if ($width/$height > $ratio_orig){
$width = $height*$ratio_orig;
} else {
$height = $width/$ratio_orig;
}

$image_p = imagecreatetruecolor($width, $height);
imagealphablending($image_p, false);
imagesavealpha($image_p, true);
$transparent = imagecolorallocatealpha($image_p, 255, 255, 255, 127);
imagecopyresampled($image_p, $pic, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);
$this->save($extension, $image_p, $new_img, $quality);
}
Роман Беляев
16382 сообщения
#12 лет назад
Цитата ("yurec2073"):
Наверное GD.

Так и есть. Imagick таких проблем не имеет, качество выше, вес меньше.
Владимир Коваль
65 сообщений
#12 лет назад
Я вам откровенно поражаюсь. Вы что вообще делаете. $image_p - это разве изображение, которое приходит в виде файла от клиента. Это только ширина и высота, как вы собираетесь присваивать прозрачность высоте и ширине ?????????? О_О

$pic - это скорее всего изображение.
Юрий П.
70 сообщений
#12 лет назад
vovikov84,

//пропорциональное измнение размера
function resize($img, $new_img, $nw, $nh, $quality){
$width = $nw;
$height = $nh;

$extension=$this->findexts($img);
$pic=$this->create($img, $extension);
list($width_orig, $height_orig) = getimagesize($img);
$ratio_orig = $width_orig/$height_orig;
if ($width/$height > $ratio_orig){
$width = $height*$ratio_orig;
} else {
$height = $width/$ratio_orig;
}

$image_p = imagecreatetruecolor($width, $height);
imagealphablending($pic, false);
imagesavealpha($pic, true);
$transparent = imagecolorallocatealpha($pic, 255, 255, 255, 127);
imagecopyresampled($image_p, $pic, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);
$this->save($extension, $image_p, $new_img, $quality);
}


поменял
ничего не менялось

$img - тут то что приходит от пользователя
Владимир Коваль
65 сообщений
#12 лет назад
$image_p = imagecreatetruecolor($width, $height);
imageinterlace($image_p, true);
imagecopyresampled($image_p, $pic, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);
if($extension == 'png' {
imagealphablending($image_p, false);
imagesavealpha($image_p, true);
if(imagepng($image_p, $uploadfile)) {
...
}
}

$uploadfile - это полный путь к создаваемому файлу (путь + имя изображения + расширение)
Юрий П.
70 сообщений
#12 лет назад
vovikov84,
//пропорциональное измнение размера
function resize($img, $new_img, $nw, $nh, $quality){
$width = $nw;
$height = $nh;

$extension=$this->findexts($img);
$pic=$this->create($img, $extension);
list($width_orig, $height_orig) = getimagesize($img);
$ratio_orig = $width_orig/$height_orig;
if ($width/$height > $ratio_orig){
$width = $height*$ratio_orig;
} else {
$height = $width/$ratio_orig;
}

$image_p = imagecreatetruecolor($width, $height);
imageinterlace($image_p, true);
imagecopyresampled($image_p, $pic, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);
imagealphablending($image_p, false);
imagesavealpha($image_p, true);
$this->save($extension, $image_p, $new_img, $quality);
}

так?
Не работает. Всё-равно черный фон...
Владимир Коваль
65 сообщений
#12 лет назад
If(imagepng($image_p, $uploadfile)) {
...
}

Сохраняйте именно так

$this->save($extension, $image_p, $new_img, $quality);

а не так
Юрий П.
70 сообщений
#12 лет назад
vovikov84,
код функции сохранения

//сохранение рисунка
function save($extension, $pic, $new_img, $quality=100){
switch($extension){
case "gif":
imagegif($pic,$new_img); // GIF
break;
case "jpg":
imagejpeg($pic,$new_img,$quality); // JPEG
break;
case "jpeg":
imagejpeg($pic,$new_img,$quality); // JPEG
break;
case "png":
imagepng($pic,$new_img); // PNG
break;
}
}
Владимир Коваль
65 сообщений
#12 лет назад
$img - это имя временного файла?

$pic=$this->create($img, $extension); это:

if($extension == 'jpg' {
return imagecreatefromjpeg($img);
} elseif ($extension == 'gif' {
return imagecreatefromgif($img);
} elseif ($extension == 'png' {
return imagecreatefrompng($img);
}

$new_img - это полный путь к создаваемому изображению? (/images/newimage.png)
Юрий П.
70 сообщений
#12 лет назад
vovikov84,
//создание рисунка
function create($img, $extension){
$pic="";
switch($extension){
case "gif":
$pic = imagecreatefromgif($img);
break;
case "jpg":
$pic = imagecreatefromjpeg($img);
break;
case "jpeg":
$pic = imagecreatefromjpeg($img);
break;
case "png":
$pic = imagecreatefrompng($img);
break;

}
return $pic;
}


$img - в функции сохранения такого параметра нет

зато есть
$pic - изображение в памяти
,$new_img - путь для сохранения
Владимир Коваль
65 сообщений
#12 лет назад
Function resize($img, $new_img, $nw, $nh, $quality){

$img - это просто имя временного файла или массив параметров файла, причем с ним никакие операции не проводились?


может нужно сделать так?
function create($img, $extension){
$pic="";
switch($extension){
case "gif":
$pic = imagecreatefromgif($img->tempName);
break;
case "jpg":
$pic = imagecreatefromjpeg($img->tempName);
break;
case "jpeg":
$pic = imagecreatefromjpeg($img->tempName);
break;
case "png":
$pic = imagecreatefrompng($img->tempName);
break;

}
return $pic;
}
Юрий П.
70 сообщений
#12 лет назад
vovikov84,
$img->tempName - это же объект
а у нас эта переменная не объект

может поделитесь рабочим примером? я у себя буду уже сам адаптировать
Владимир Коваль
65 сообщений
#12 лет назад
Класс, который обрабатывает файл

<?php

class KVUploadImage
{
private $image;
private $ext;
private $type;

private $imgH;
private $imgW;
private $getPath;
private $mainPath;
private $createPath;
private $quality;
private $cut;

public function __construct($load_image, $type=null)
{
$this->image = $load_image;
$this->ext = isset($this->image) ? mb_strtolower($this->image->extensionName): null;
$this->type = $type;
}

public function save($max_h=50, $max_w=50, $path=null, $quality, $sub_folder=false, $cut=true) {
$img_name = (isset($this->image) && $path) ? $this->image : "";
if($img_name) {
$this->imgH = $max_h;
$this->imgW = $max_w;
$this->getPath = $path;
$this->mainPath = realpath($path).'/';
$this->createPath = '/';
if($sub_folder === true) {
$this->createPath = date('Y'.'/'.date('m'.'/';
} elseif(is_string($sub_folder)) {
$this->createPath = $sub_folder.'/';
}
$this->quality = $quality;
$this->sub_folder = $sub_folder;
$this->cut = $cut;
switch($this->type) {
case 'small':
$img_name = $this->getSmallImage();
break;
}
}
return $img_name;
}

private function getSmallImage() {
$return_name = "";
if($this->ext == 'jpg' {
$img = imagecreatefromjpeg($this->image->tempName);
} elseif ($this->ext == 'gif' {
$img = imagecreatefromgif($this->image->tempName);
} elseif ($this->ext == 'png' {
$img = imagecreatefrompng($this->image->tempName);
}

$img_y = imagesy($img);
$img_x = imagesx($img);
$coor_x = 0;
$coor_y = 0;

if($this->cut) { // cut picture
if($img_y/$img_x >= $this->imgH/$this->imgW) {
$result_w = $this->imgW;
$result_h = ($img_y * $result_w)/$img_x;
$orig_img_y = $img_y;
$img_y = $img_x * $this->imgH / $this->imgW;
$coor_y = ($orig_img_y - $img_y) / 2;
} else {
$result_h = $this->imgH;
$result_w = ($img_x * $result_h)/$img_y;
$orig_img_x = $img_x;
$img_x = $img_y * $this->imgW / $this->imgH;
$coor_x = ($orig_img_x - $img_x) / 2;
}
$coordY = 0;
$coordX = 0;
if($result_w > $this->imgW)
$coordX = ($result_w - $this->imgW) / 2;
if($result_h > $this->imgH)
$coordY = ($result_h - $this->imgH) / 2;
$result_w = $this->imgW;
$result_h = $this->imgH;
} else { // save proportions
if($img_y/$img_x >= $this->imgH/$this->imgW) {
$result_h = $this->imgH;
$result_w = ($img_x * $result_h)/$img_y;
} else {
$result_w = $this->imgW;
$result_h = ($img_y * $result_w)/$img_x;
}
}

$tmb = imagecreatetruecolor($result_w, $result_h);
imageinterlace($tmb, true);
imagecopyresampled($tmb, $img, 0,0,$coor_x,$coor_y,$result_w,$result_h,$img_x,$img_y);

$imagefilename = (is_string($this->sub_folder)) ? 'userpic' : md5(uniqid(rand(),1));
$imagename = $this->createPath.$imagefilename.".".$this->ext;
$uploadfile = $this->mainPath.$imagename;

if(is_dir($this->mainPath.$this->createPath) || mkdir($this->mainPath.$this->createPath, 0755, true)) {
if($this->ext == "jpg" {
if(imagejpeg($tmb, $uploadfile, $this->quality)) {
chmod($uploadfile, 0755);
$return_name = '/'.$this->getPath.$imagename;

}
} elseif ($this->ext == "gif" {
if(imagegif($tmb, $uploadfile)) {
chmod($uploadfile, 0755);
$return_name = '/'.$this->getPath.$imagename;
}
} elseif ($this->ext == "png" {
imagealphablending($tmb, false);
imagesavealpha($tmb, true);
if(imagepng($tmb, $uploadfile)) {
chmod($uploadfile, 0755);
$return_name = '/'.$this->getPath.$imagename;
}
}
} else {
$return_name = 'error';
}
return $return_name;
}
}

Код сохранения картинки

$image = new KVUploadImage($loadAvatar, 'small';
$image_name = $image->save(50, 50, 'upload/avatar/', 100, 'users/user', true);

У меня $loadAvatar - это объект

$loadAvatar->tempName - временное имя файла
$loadAvatar->extensionName - расширение файла

Вроде код у вас должен работать, у меня прозрачность для png работает