Autor Zpráva
sniclman
Profil *
Ahoj, potřeboval bych poradit se zachováním průhledné barvy při použití funkce imagecopyresampled.
Program má vytvořit kruhovou výseč z libovolného obrázku. Pokud vynechám funkci imagecopyresampled, funguje vše v pořádku.

Zdrojový kód programu:
$filename = $_GET["img"];
$quality = (100-$_GET["q"])*0.09;
list($width, $height) = getimagesize($filename);

/*VYTVOŘENÍ OBRÁZKU detekce formátu*/
$createimagefrom = array(IMAGETYPE_GIF => 'gif',IMAGETYPE_JPEG => 'jpeg',IMAGETYPE_JPG => 'jpeg',IMAGETYPE_PNG => 'png');
switch($createimagefrom[exif_imagetype($filename)]){
case 'jpeg': $image = imagecreatefromjpeg($filename); break;
case 'gif': $image = imagecreatefromgif($filename); break;
case 'png': $image = imagecreatefrompng($filename); break;}

//kruhová výseč
if($_GET["c"] != null){
if($height > $width){$circle_size = $width;}
else if($width > $height){$circle_size = $height;}
else{}
$output = imagecreatetruecolor($circle_size, $circle_size);
imagecopy($output, $image, 0, 0, $width/2-$circle_size/2, $height/2-$circle_size/2, $circle_size, $circle_size);
//Vytvoří masku s růžovou barvou o velikosti vstupního obrázku
$mask = imagecreatetruecolor($circle_size, $circle_size);
$pink = imagecolorallocate($mask, 255, 0, 255);
imagefill($mask, 0, 0, $pink);
//Vytvoří uprostřed masky výseč (elipsa/kruh) s transparentní barvou  
$circle = imagecolorallocate($mask, 255, 255, 255);
imagecolortransparent($mask, $circle);
imagefilledellipse($mask, $circle_size/2, $circle_size/2, $circle_size, $circle_size, $circle);
//nakopíruje masku přes vstupní obrázek a nastaví masku jako průhlednou
imagecopymerge($output, $mask, 0, 0, 0, 0, $circle_size, $circle_size, 100);
imagecolortransparent($output, $pink);}

/*ZMENŠENÍ*/
$image_p = imagecreatetruecolor(300, 300);
imagecopyresampled($image_p, $output, 0, 0, 0, 0, 300, 300, $circle_size, $circle_size);

/*VÝSTUP ZOBRAZENÍ*/
header('Content-Type: image/png');
imagepng($image_p);
imagedestroy($image_p);

obrázek upravený programem


Děkuji za veškeré rady.
DarkMeni
Profil
Kdysi sem taky něco podobnýho řešil, a pomohly mi funkce imageAlphaBlending() a imageSaveAlpha()
Nějak takto sem to nakonec vyřešil
<?php
    //$file = isset($_GET['image']) ? $_GET['image'] : 'notfound.jpg';
    $file = 'image.jpg';
    if(!file_exists($file)){
        exit;
    }
    $file_ext = substr($file, strrpos($file, '.') + 1);
    switch($file_ext){
        case 'jpg':
            $image = imageCreateFromJPEG($file);
            break;
        case 'png':
            $image = imageCreateFromPNG($file);
            break;
        case 'bmp':
            $image = imageCreateFromBMP($file);
            break;
    }
    
    list($img_width, $img_height) = getImageSize($file);
    if(isset($_GET['size']) && is_numeric($_GET['size'])){
        $width = $_GET['size'];
    }else{
        $width = $img_width > $img_height ? $img_height : $img_width;
    }
    if($img_width > $img_height){
        $clip_x = 0;//round(($img_width - $img_height) / 4);
        $clip_y = 0;
    }else{
        $clip_x = 0;
        $clip_y = 0;//round(($img_height - $img_width) / 4);
    }
    
    $height = $width;
    $center = round($width / 2);
    $radius = $width - 4;

    $output_image = imageCreateTrueColor($width, $height);
    $ellipse_image = imageCreateTrueColor($width, $height);

    $white = imageColorAllocate($ellipse_image, 0xFF, 0xFF, 0xFF);
    $black = imageColorAllocate($ellipse_image, 0x00, 0x00, 0x00);
    $transparent = imageColorAllocateAlpha($ellipse_image, 0xFF, 0xFF, 0xFF, 127);

    imageAlphaBlending ($ellipse_image, false);
    imageFill          ($ellipse_image, 0, 0, $white);    
    imageFilledEllipse ($ellipse_image, $center, $center, $radius, $radius, $transparent);    
    imageEllipse       ($ellipse_image, $center, $center, $radius, $radius, $black);
    
    imageCopyResampled ($output_image, $image, 0, 0, $clip_x, $clip_y, $width, $height, $img_width, $img_height);    
    imageCopy          ($output_image, $ellipse_image, 0, 0, 0, 0, $width, $height);

    $bg_transparency = imageColorAllocateAlpha($output_image, 0xFF, 0x00, 0x00, 127);
    imageFill($output_image, 0, 0, $bg_transparency);
    
    header('Content-Type: image/png');
    
    imageSaveAlpha($output_image, true);
    imagePNG($output_image);
    imageDestroy($image);
    imageDestroy($output_image);
    imageDestroy($ellispe_image);
?>
sniclman
Profil *
DarkMeni:
Ahoj, díky za poskytnutý zdroják. Problém je že potřebuji zmenšit obrázek až po ořezání a zprůhlednění okrajů.
Takto se dostanu do situace kdy budu mít sice zmenšený obrázek ale hrany kružnice budou mít viditelné zuby.
DarkMeni
Profil
Aha, tak zkus před imageCopyResampled() vypnout míchání průhlednosti (imageAlphaBlending()) pro $dst_image
Ale myslim že to, jestli to přerozměruješ před oříznutím nebo po něm, tak ty zuby až tak nějak neřeší, ale nevim, možná jo

Třeba takto (upravená část kódu):
    <?php

imageAlphaBlending ($ellipse_image, false);
imageFill          ($ellipse_image, 0, 0, $white);    
imageFilledEllipse ($ellipse_image, $center, $center, $radius, $radius, $transparent);    
imageEllipse       ($ellipse_image, $center, $center, $radius, $radius, $black);
    
imageCopy          ($output_image, $image, 0, 0, 0, 0, $width, $height);
imageCopy          ($output_image, $ellipse_image, 0, 0, 0, 0, $width, $height);

imageAlphaBlending($output_image, false);
$bg_transparency = imageColorAllocateAlpha($output_image, 0xFF, 0x00, 0x00, 127);
imageFill($output_image, 0, 0, $bg_transparency);
    
imageEllipse($output_image, $center, $center, $radius, $radius, $transparent);
    
$output_image2 = imageCreateTrueColor($new_width, $new_height);
    
imageAlphaBlending($output_image2, false);
imageCopyResampled ($output_image2, $output_image, 0, 0, $clip_x, $clip_y, $new_width, $new_height, $img_width, $img_height);    
    
header('Content-Type: image/png');
    
imageSaveAlpha($output_image2, true);
imagePNG($output_image2);
?>
Teda aspoň u mě na localhostu to funguje. Jestli ti to pude taky, tak si to uprav podle sebe, nevěděl sem třeba jak mam vycentrovat a oříznout čtverec v případě, že by hlavní obrázek byl ve tvaru obdelníka (asi taky nějak přes imageCopyResampled, ale nevim který argumenty to řeší)
sniclman
Profil *
DarkMeni:
Děkuju za zdroják, funguje to perfektně. Přikládám vlastní zdroják, který z obrázku vyřízne střed a udělá kulaté okraje.

<?php
$file = $_GET['img'];
$output_size = $_GET["s"];
list($width, $height) = getimagesize($file);

//detekce formátu
$createimagefrom = array(IMAGETYPE_GIF => 'gif',IMAGETYPE_JPEG => 'jpeg',IMAGETYPE_PNG => 'png');
switch($createimagefrom[exif_imagetype($file)]){
case 'jpeg': $image = imagecreatefromjpeg($file); break;
case 'gif': $image = imagecreatefromgif($file); break;
case 'png': $image = imagecreatefrompng($file); break;}   

//čtvercový rozměr
if($height > $width){$circle_size = $width;}
else if($width > $height){$circle_size = $height;}
else{}

//maska 
$ellipse_image = imagecreatetruecolor($circle_size, $circle_size);
$background = imagecolorallocate($ellipse_image, 255, 255, 255);
$transparent = imagecolorallocatealpha($ellipse_image, 0, 0, 0, 127);
imagealphablending ($ellipse_image, false);
imagefill          ($ellipse_image, 0, 0, $background);    
imagefilledellipse ($ellipse_image, $circle_size/2, $circle_size/2, $circle_size-6, $circle_size-6, $transparent);    

//kopírování masky a ořezání obrázku
$proces_image = imagecreatetruecolor($circle_size, $circle_size);
imagecopy($proces_image, $image, 0, 0, $width/2-$circle_size/2, $height/2-$circle_size/2, $circle_size, $circle_size);
imageCopy($proces_image, $ellipse_image, 0, 0, 0, 0, $circle_size, $circle_size);
imagealphablending($proces_image, false);
imagefill($proces_image, 0, 0, $transparent);

//zmenšení převzorkování    
$output = imagecreatetruecolor($output_size, $output_size);
imagealphablending($output, false);
imagecopyresampled ($output, $proces_image, 0, 0, 0, 0, $output_size, $output_size, $circle_size, $circle_size);    

//výstup    
header('Content-Type: image/png');
imagesavealpha($output, true);
imagepng($output);
imagedestroy($output);
imagedestroy($proces_image);
imagedestroy($image);
imagedestroy($ellipse_image);
?>

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: