Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В. C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В. PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Создание вотермарка
 
 автор: darkozoid   (27.06.2013 в 13:35)   письмо автору
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;
        }
    }

  Ответить  
 
 автор: confirm   (27.06.2013 в 14:22)   письмо автору
 
   для: 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, который не имеет прозрачности, это круто.

  Ответить  
 
 автор: darkozoid   (28.06.2013 в 08:49)   письмо автору
 
   для: 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, который не имеет прозрачности, это круто.

опять же не важно... может это логотип компании который не имеет прозрачности...

проблема все равно актуальна

  Ответить  
 
 автор: confirm   (28.06.2013 в 10:56)   письмо автору
 
   для: darkozoid   (28.06.2013 в 08:49)
 

Ну если не важно, тогда и сказать нечего.
Вы свой класс в помойку, и просто делайте для примера наложения разных типов с разными свойствами друг на друга и смотрите результат. Может тогда и "не важно" в помойку. )

А если бы я написал кода эдак строк 300, вы бы его тоже процитировали? )

  Ответить  
 
 автор: darkozoid   (28.06.2013 в 17:19)   письмо автору
 
   для: confirm   (28.06.2013 в 10:56)
 

>Ну если не важно, тогда и сказать нечего.
>Вы свой класс в помойку, и просто делайте для примера наложения разных типов с разными свойствами друг на друга и смотрите результат. Может тогда и "не важно" в помойку. )
>
>А если бы я написал кода эдак строк 300, вы бы его тоже процитировали? )

а я пишу как умею... не хотите помогать... не помогайте....

типы может и разные, но при сохранении все работает а при прямом выводе нет....

  Ответить  
 
 автор: confirm   (28.06.2013 в 17:47)   письмо автору
 
   для: darkozoid   (28.06.2013 в 17:19)
 

Я не о том, умеете вы или нет, я о том что вы делаете.

Изображения бывают двух типов - основанные на палитре и полноцветные. А вы производите наложение без учета этого, совсем не заботясь о том, что в итоге получится. Судите сами - исходное изображение gif (и может быть и png), это ограниченная палитра. Что в итоге получится если на нее наложить png с альфа каналом? Если смысл наложения на палитру полноцветных изображений и наоборот? Если у вас так все универсально, то зачем иметь налагаемое в трех форматах?

Вот это надо сперва сделать, а уж обрамлять потом в класс или в функцию, это второстепенное, может быть и вообще совсем не нужное. То есть вы написали что-то, без учета выше сказанного, теперь пытаетесь разобраться почему не работает, а ведь по большому счету работа вашего кода в большей степени бессмысленна.

  Ответить  
 
 автор: darkozoid   (01.07.2013 в 08:46)   письмо автору
 
   для: confirm   (28.06.2013 в 17:47)
 

ок, то есть мне для для каждого формата надо заготовить свой логотип того же формата... а как же быть если это пользовательская функция и надо дать возможность накладывать png логотипы на jpg картинки? - как то же это делается? я сам где то это делал.... может надо как то конвертировать палитру или что то типа того?

  Ответить  
 
 автор: confirm   (01.07.2013 в 09:45)   письмо автору
 
   для: 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, это размер в три раза больше исходного.

  Ответить  
 
 автор: darkozoid   (01.07.2013 в 14:09)   письмо автору
 
   для: confirm   (01.07.2013 в 09:45)
 

>А как же быть с этим тогда - header('Content-Type: image/jpeg');?
упс... упустил...


вот спасибо!

  Ответить  
 
 автор: Deed   (28.06.2013 в 15:05)   письмо автору
 
   для: darkozoid   (27.06.2013 в 13:35)
 

http://php.net/manual/en/image.examples.merged-watermark.php
"На пальцах": http://www.sitepoint.com/watermark-images-php/

  Ответить  
 
 автор: darkozoid   (28.06.2013 в 17:24)   письмо автору
 
   для: Deed   (28.06.2013 в 15:05)
 

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

Вопрос то не в том как сделать наложение... а в том почему картинка отображается полностью и корректно если ее сохранять и куском и коряво если выводить в браузер без сохранения....
одна на другую накладывается всегда и всегда верно... проблема с выводом...

  Ответить  
 
 автор: Deed   (28.06.2013 в 23:46)   письмо автору
 
   для: darkozoid   (28.06.2013 в 17:24)
 

Попробуйте или в классе, или перед самим выводом присвоить полученную картинку еще какой-нибудь переменной, и выводить уже эту переменную.

  Ответить  
 
 автор: confirm   (29.06.2013 в 05:15)   письмо автору
 
   для: Deed   (28.06.2013 в 23:46)
 

Какой это переменной и что даст? Зачем вы советуете, если не понимаете в чем причина?

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования