|
 214.2 Кб |
|
| Добрый день, написал метод который накладывает водяной знак на картинку.
Метод принимает 4 переменных (картинка, водяной знак, расположение, $dis)
$dis == или 0 или 1 (по умолчанию 0)
если 0 то метод накладывает водяной знак и песохраняет исходник, а если $dis == 1 то не сохраняет а просто выводит в браузер.
Соответственно при вызове метода так:
print"<img src='".$watermark->mark('./img/11.jpg', './img/w.png', '3')."'>";
|
выводится картинка исходник, уже с водяным знаком, так как она уже перезаписана... тут все работает как часы
но если вызывать так:
print"<img src='img.php?img=./img/11.jpg&water=./img/w.png&pos=4'>";
/////////////////// листинг страницы img.php ////////////////////
<?php
include_once("./class.php");
$wm = new watermark;
print $wm->mark($_GET['img'], $_GET['water'], $_GET['pos'],1);
?>
/////////////////////////////////////////////////////////////////
|
то картинка выводится, но только кусками... при чем не всегда одинаковыми... (см приложение)
Вопрос: почему это может быть?
Листинг метода
public function mark($name, $namew, $r, $dis=0){
$prv=substr(sprintf('%o', fileperms($name)), -1);
if($dis==0){
if(($prv=='4')or($prv=='1')or($prv=='0')or($prv=='5')){
if(!chmod($name, 0777)){
$this->err("Не могу изменить права на файл ".$name.", возможна ошибка. <br>Дайте публичные права на запись.</p>"); break;
}
}
}
$type=getimagesize($name);
$typew=getimagesize($namew);
switch($type[2]){
case "1": $im = imagecreatefromgif($name); break;
case "2": $im = imagecreatefromjpeg($name); break;
case "3": $im = imagecreatefrompng($name); break;
default: $this->err(" No valid type image<br> "); break(1);
}
switch($typew[2]){
case "1": $gl = imagecreatefromgif($namew); break;
case "2": $gl = imagecreatefromjpeg($namew); break;
case "3": $gl = imagecreatefrompng($namew); break;
default: $this->err(" No valid type watermark<br> ".$typew[2]); break(1);
}
switch($r){
case 1: $nx=imagesx($im)-imagesx($gl); $ny=imagesy($im)-imagesy($gl); break; // нижний правый
case 2: $nx=0; $ny=imagesy($im)-imagesy($gl); break; // нижний левый
case 3: $nx=imagesx($im)-imagesx($gl); $ny=0; break; // верхний правый
case 4: $nx=0; $ny=0; break; // верхний левый
default: $nx=imagesx($im)-imagesx($gl); $ny=imagesy($im)-imagesy($gl); break; // нижний правый
}
if(imagecopy($im, $gl, $nx, $ny, 0, 0, imagesx($gl), imagesy($gl))){
if($dis==0){
if(imagejpeg($im,$name,100)){
imagedestroy($im);
imagedestroy($lg);
return $name;
}else{
$this->err("error save (chmod not xx6 or xx7 for file ".$name.")<br>");
return false;
}
}elseif($dis==1){
header('Content-Type: image/jpeg');
imagejpeg($im);
imagedestroy($im);
imagedestroy($lg);
}
}
else{
$this->err("error copy<br>");
return false;
}
}
|
| |
|
|
|
|
|
|
|
для: darkozoid
(27.06.2013 в 13:35)
| | switch($type[2]){
case "1": $im = imagecreatefromgif($name); break;
case "2": $im = imagecreatefromjpeg($name); break;
.....
Зачем же так писать, и тоже самое для заголовков? Можно же описать этот зоопарк изображений:
<?
$ext = array('image/gif'=>'imagecreatefromgif', 'image/jpeg'=>'imagecreatefromjpeg', 'image/png'=>'imagecreatefrompng');
$im = 'image.ext';
$mime = end(getimagesize($im));
if(array_key_exists($mime, $ext)) {
$im = $ext[$mime]($im);
}
|
Нет в вашем коде никакого водяного знака, это вообще совсем другое понятие. Но чтобы на картинку в качестве логотипа накладывался тип jpeg, который не имеет прозрачности, это круто. | |
|
|
|
|
|
|
|
для: confirm
(27.06.2013 в 14:22)
| | >switch($type[2]){
>case "1": $im = imagecreatefromgif($name); break;
>case "2": $im = imagecreatefromjpeg($name); break;
>.....
>
>Зачем же так писать, и тоже самое для заголовков? Можно же описать этот зоопарк изображений:
<?
>$ext = array('image/gif'=>'imagecreatefromgif', 'image/jpeg'=>'imagecreatefromjpeg', 'image/png'=>'imagecreatefrompng');
>$im = 'image.ext';
>$mime = end(getimagesize($im));
>if(array_key_exists($mime, $ext)) {
> $im = $ext[$mime]($im);
>}
|
за это спасибо, я учту.
>Нет в вашем коде никакого водяного знака, это вообще совсем другое понятие.
не важно, суть в том чтобы наложить одно изображение на другое
> Но чтобы на картинку в качестве логотипа накладывался тип jpeg, который не имеет прозрачности, это круто.
опять же не важно... может это логотип компании который не имеет прозрачности...
проблема все равно актуальна | |
|
|
|
|
|
|
|
для: darkozoid
(28.06.2013 в 08:49)
| | Ну если не важно, тогда и сказать нечего.
Вы свой класс в помойку, и просто делайте для примера наложения разных типов с разными свойствами друг на друга и смотрите результат. Может тогда и "не важно" в помойку. )
А если бы я написал кода эдак строк 300, вы бы его тоже процитировали? ) | |
|
|
|
|
|
|
|
для: confirm
(28.06.2013 в 10:56)
| | >Ну если не важно, тогда и сказать нечего.
>Вы свой класс в помойку, и просто делайте для примера наложения разных типов с разными свойствами друг на друга и смотрите результат. Может тогда и "не важно" в помойку. )
>
>А если бы я написал кода эдак строк 300, вы бы его тоже процитировали? )
а я пишу как умею... не хотите помогать... не помогайте....
типы может и разные, но при сохранении все работает а при прямом выводе нет.... | |
|
|
|
|
|
|
|
для: darkozoid
(28.06.2013 в 17:19)
| | Я не о том, умеете вы или нет, я о том что вы делаете.
Изображения бывают двух типов - основанные на палитре и полноцветные. А вы производите наложение без учета этого, совсем не заботясь о том, что в итоге получится. Судите сами - исходное изображение gif (и может быть и png), это ограниченная палитра. Что в итоге получится если на нее наложить png с альфа каналом? Если смысл наложения на палитру полноцветных изображений и наоборот? Если у вас так все универсально, то зачем иметь налагаемое в трех форматах?
Вот это надо сперва сделать, а уж обрамлять потом в класс или в функцию, это второстепенное, может быть и вообще совсем не нужное. То есть вы написали что-то, без учета выше сказанного, теперь пытаетесь разобраться почему не работает, а ведь по большому счету работа вашего кода в большей степени бессмысленна. | |
|
|
|
|
|
|
|
для: confirm
(28.06.2013 в 17:47)
| | ок, то есть мне для для каждого формата надо заготовить свой логотип того же формата... а как же быть если это пользовательская функция и надо дать возможность накладывать png логотипы на jpg картинки? - как то же это делается? я сам где то это делал.... может надо как то конвертировать палитру или что то типа того? | |
|
|
|
|
|
|
|
для: darkozoid
(01.07.2013 в 08:46)
| | >а как же быть если это пользовательская функция и надо дать возможность накладывать png логотипы на jpg картинки?
А как же быть с этим тогда - header('Content-Type: image/jpeg');?
Вы ведь старательно открываете каждый тип соответствующей функцией, а отдаете в одном и том же формате. Согласитесь, ваш вопрос в таком случае не имеет смысла.
Если и отдавать всегда в одном формате независимо от входного, то смысла распознавать входной формат нет. В этом случае лучше поступать так:
<?
if($im = @imagecreatefromstring(file_get_contents('image.ext'))) {
//$im - открытый ресурс в формате GD
}
| Но нужно знать, что JPEG формат, это оптимальный выбор для изображения с плавными переходами яркости и цвета. GIF формат, а также PNG8, это ограниченная палитра, и JPEG компрессор для этого типа изображения не лучший вариант - качество будет далеко не лучшее, а вот размер изображения намного будет превышать размер исходного.
Отсюда следует, что сохранять нужно как минимум в двух форматах - JPEG для полноцветных изображений (.jpg, .png), и GIF (PNG) для основанных на палитре. Ну или в трех форматах, и загружать для каждого свой логотип (хотя для .jpg вполне годится наложение png с альфа каналом, так как исходное изображение truecolor, а при его открытии будет создан альфа канал по умолчанию).
Узнать какому типу относится изображение (основанное на палитре или truecolor) можно функцией imageistruecolor() и получать соответствующий логотип.
Что касается вывода, почему так получается. А потому, что вывод вод здесь - imagejpeg($im);, и в первом вашем случае все как положено и происходит - print выводит в браузер строку описывающую изображение, а изображение получает бинарные данные тела.
Во втором случае бардак - если это так и есть как и написано, то вообще не понять кому отдается поток, и к тому же вы разбиваете поток. Вот поэтому такое и происходит.
Если вы хотите сразу выгрузить на страницу изображение с телом, то это можно сделать так:
<img src="data:image/gif;base64,<?=base64_encode($wm->mark(...))?>" />
| Но при этом нужно буферизировать вывод изображения и учитывать, что браузеры ограничивают эту величину, каждый своим размером, которая составляет не более нескольких десятков КБ, а бинарные данные в base64, это размер в три раза больше исходного. | |
|
|
|
|
|
|
|
для: confirm
(01.07.2013 в 09:45)
| | >А как же быть с этим тогда - header('Content-Type: image/jpeg');?
упс... упустил...
вот спасибо! | |
|
|
|
|
|
|
|
|
для: Deed
(28.06.2013 в 15:05)
| | спасибо конечно, но ведь у меня то же самое по сути дела, может написано чуть с другой логикой и посложнее...
Вопрос то не в том как сделать наложение... а в том почему картинка отображается полностью и корректно если ее сохранять и куском и коряво если выводить в браузер без сохранения....
одна на другую накладывается всегда и всегда верно... проблема с выводом... | |
|
|
|
|
|
|
|
для: darkozoid
(28.06.2013 в 17:24)
| | Попробуйте или в классе, или перед самим выводом присвоить полученную картинку еще какой-нибудь переменной, и выводить уже эту переменную. | |
|
|
|
|
|
|
|
для: Deed
(28.06.2013 в 23:46)
| | Какой это переменной и что даст? Зачем вы советуете, если не понимаете в чем причина? | |
|
|
|