Imagerotate met transparante png

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Mark D

Mark D

17/07/2009 20:17:00
Quote Anchor link
Ik probeer een transparante png 8 graden te draaien, maar ik zit met het probleem dat de standaard functie, imagerotate, daar een zwarte achtergrond bij plakt waar ik niet echt op zit te wachten...
Is er een manier om een png te draaien zodat wat nu zwart is transparant wordt?

Alvast bedankt,
Mark
 
PHP hulp

PHP hulp

22/11/2024 05:21:50
 
Emmanuel Delay

Emmanuel Delay

17/07/2009 21:08:00
Quote Anchor link
Probeer zo eens

index.php
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?php
function LoadPNG($imgname, $degrees = 0)
{

    /* Attempt to open */
    $im = @imagecreatefrompng($imgname);
    if ($degrees > 0)
    {

      list($width, $height, $type, $attr) = getimagesize($imgname);
      $rotate = imagerotate($im, $degrees, 0);
      $cBackground = imagecolorallocate($rotate, 0, 0, 0);  // Zwarte kleur wordt als transparant gezet.
      imagecolortransparent($rotate, $cBackground);
    }

  header('Content-Type: image/png');
  return ( $degrees > 0 ? $rotate : $im);
}


  $image = '027b.png';
  $degrees = 15;
  
switch ($_GET['p'])
{
  default:

  list($width, $height, $type, $attr) = getimagesize($image);
  echo '<html><head><style>body{padding: 10px; background-color: #aaaaff}</style></head><body><img src="index.php?p=i" width="'. $width .'" height="'. $height .'" /></body></html>';
  break;
  case
'i':
    $img = LoadPNG($image, $degrees);
    imagepng($img);
    imagedestroy($img);
  break;
}

?>
Gewijzigd op 01/01/1970 01:00:00 door Emmanuel Delay
 
Mark D

Mark D

17/07/2009 21:24:00
Quote Anchor link
Het werkt, maar ik krijg nog wel een grijs randje om het plaatje heen, is dat ook nog weg te werken op de een of andere manier?

Klopt het trouwens dat de functie imagecolorallocate alle zwarte pixels transparant maakt, want dan zouden er ook delen van mijn plaatje verdwijnen...
 
Emmanuel Delay

Emmanuel Delay

17/07/2009 21:28:00
Quote Anchor link
Ik vrees dat je gelijk hebt, zwarte pixels binnen de afbeelding zullen waarschijnlijk ook transparant worden.

Ook geen idee hoe je de rand beter kan krijgen.

EDIT

Wat je kan doen: eerst vervang je in de afbeelding alle zwarte pixels door pixels met waarde #010101 (Niemand ziet dat dat niet volledig zwart is.).

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
<?php
  $image
= '027b.png';  // zelf aanpassen
  $degrees = 15;        // zelf aanpassen
  
switch ($_GET['p'])
{
  default:

      if( file_exists($image) )
        {

        list($width, $height, $type, $attr) = getimagesize($image);
        echo htmlHeading('<img src="index.php?p=i"  />', 'Geroteerde png' ) ; // eventueel voeg je dit toe // width="'. $width .'" height="'. $height .'"
        }
        else
          echo htmlHeading('<div>File "'. $image .'" bestaat niet</div>', 'File "'. $image .'" bestaat niet');
  break;
  case
'i':
    $img = LoadPNG($image, $degrees);
    imagepng($img);
    imagedestroy($img);
  break;
}

function
LoadPNG($imgname, $degrees = 0)
{

try
  {
      if( file_exists($imgname) )
        {

          /* Attempt to open */
          $im = @imagecreatefrompng($imgname);
          if ($degrees )
          {

            list($width, $height, $type, $attr) = getimagesize($imgname);
            vervangZwart($im, $width, $height);
            $rotate = imagerotate($im, $degrees, 0);
            $cBackground = imagecolorallocate($rotate, 0, 0, 0);  // Zwarte kleur wordt als transparant gezet
            imagecolortransparent($rotate, $cBackground);
          }

        header('Content-Type: image/png');
        return ( $degrees ? $rotate : $im);
      }
  }

catch (Exception $e)
  {

    return null;
  }
}

function
vervangZwart($im, $width, $height)
{

  for ($x = 0; $x < $width; $x++)
  {

    for ($y = 0; $y < $height; $y++)
    {

      $pixel = imagecolorat  ( $im  , $x  , $y  );
      if ($pixel == 0)
        imagesetpixel  ( $im , $x  , $y  , 0x010101 );
    }
  }
}
function
htmlHeading($body, $title)
  {

  return
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//NL" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
  <head>
    <title>'
. $title .'</title>
    <style>
      body {padding: 10px; background-color: #aaaaff}
    </style>
  </head>
  <body>
    '
. $body .'
  </body>
</html>'
;
  }

?>


Getest. Het werkt.
Gewijzigd op 01/01/1970 01:00:00 door Emmanuel Delay
 
Mark D

Mark D

18/07/2009 10:23:00
Quote Anchor link
Ik kom er net achter dat het gedraaide plaatje altijd op een zwarte achtergrond moet worden geplakt, dus dat jet zwarte verdwijnt maakt in feite niks uit. Is er toevallig ook nog een oplossing om de randjes wat mooier te maken met antialiasing? De standaard php functie wil namelijk niet werken. ( het plaatje is een truecolorimage)
 
Emmanuel Delay

Emmanuel Delay

18/07/2009 12:43:00
Quote Anchor link
Okay, probeer dan dit eens

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
<?php
  $image
= '027b.png';  // zelf aanpassen
  $degrees = 8;         // zelf aanpassen
  $randDikte = 3;       // zelf aanpassen
  $vervang_zwart_niet = true;
  $transparant = false;
switch ($_GET['p']) // voel je vrij om op een andere manier de funtie aan te roepen.
{
  default:

      if( file_exists($image) )
        {

        list($width, $height, $type, $attr) = getimagesize($image);
        echo htmlHeading('<img src="index.php?p=i"  />', 'Geroteerde png' ) ; // eventueel voeg je dit toe // width="'. $width .'" height="'. $height .'"
        }
        else
          echo htmlHeading('
            <div>File "'
. $image .'" bestaat niet</div>', 'File "'. $image .'" bestaat niet');
  break;
  case
'i':
    $img = LoadPNG($image, $degrees, $vervang_zwart_niet, $randDikte, $transparant);
    imagepng($img);
    imagedestroy($img);
  break;
}

 
// deze functie laadt png bestand.  Het bestand wordt geroteerd.  De randen blijven transparant
function LoadPNG($imgname, $degrees = 0, $vervang_zwart_niet = 0, $randDikte = 0, $transparant = true)
{

$background = 0x000000; // zwart
try
  {
      if( file_exists($imgname) )
        {

          /* Attempt to open */
          $im = @imagecreatefrompng($imgname);
            list($width, $height, $type, $attr) = getimagesize($imgname);
            if ( !empty($vervang_zwart_niet) )
              vervangZwart($im, $width, $height);
            vervangRand($im, $width, $height, $randDikte, $background );
          if ($degrees )
          {

            $rotate = imagerotate($im, $degrees, 0);
            if ($transparant)
            {

              $cBackground = imagecolorallocate($rotate, 0, 0, 0);  // Zwarte kleur wordt als transparant gezet
              imagecolortransparent($rotate, $cBackground);
            }
          }

        header('Content-Type: image/png');
        return ( $degrees ? $rotate : $im);
      }
  }

catch (Exception $e)
  {

    return null;
  }
}

function
vervangZwart($im, $width, $height)
{

  for ($x = 0; $x < $width; $x++)
  {

    for ($y = 0; $y < $height; $y++)
    {

      $pixel = imagecolorat  ( $im  , $x  , $y  );
      if ($pixel == 0)
        imagesetpixel  ( $im , $x  , $y  , 0x010101 );
    }
  }
}
function
vervangRand($im, $width, $height, $randDikte, $background = 0x000000)
{

  for ($x = 0; $x < $width; $x++)
  {

    for ($y = 0; $y < $height; $y++)
    {

      if ( ! isRand($x, $y, $width, $height, $randDikte) )
        continue;
      $laag = randLaag($x, $y, $width, $height, $randDikte); // aantal pixel vanaf de rand
      
      $pixel = imagecolorat  ( $im  , $x  , $y  );
      imagesetpixel  ( $im , $x  , $y  , antiAlias($pixel, $background, $laag, $randDikte) );
    }
  }
}
function
antiAlias($pixel, $background, $laag, $randDikte)
{

if ($background == 0)
  {

    $rgb = int2rgba($pixel);
    $rgb['r'] = (int) $rgb['r'] * $laag / $randDikte;
    $rgb['g'] =(int)  $rgb['g'] * $laag / $randDikte;
    $rgb['b'] = (int) $rgb['b'] * $laag / $randDikte;
    return rgba2int($rgb['r'], $rgb['g'], $rgb['b']);
  }

  // TO DO: herberekenen voor andere achtergronden
}
function
isRand($x, $y, $width, $height, $randDikte)
{

      if ($x < $randDikte)
        return true;
  elseif ($y < $randDikte)
        return true;
  elseif ( ($width - $x) < $randDikte)
        return true;
  elseif ( ($height - $y) < $randDikte)
        return true;
  return false;  
}
function
randLaag($x, $y, $width, $height, $randDikte)
{

  $infinity = 1000;
  $pixelsVanDeRand = array();
  $pixelsVanDeRand['left'] = ($x < $randDikte ? $x : $infinity);
  $pixelsVanDeRand['top'] = ($y < $randDikte ? $y : $infinity);
  $pixelsVanDeRand['right'] = ( ($width - $x) < $randDikte ? ($width - $x - 1) : $infinity);
  $pixelsVanDeRand['bottom'] = ( ($height - $y) < $randDikte ? ($height - $y - 1) : $infinity);
  $result =  min($pixelsVanDeRand);
  if ($result < $randDikte)
    return (int) $result;
  return 0;
}
function
htmlHeading($body, $title)
  {

  return
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//NL" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
  <head>
    <title>'
. $title .'</title>
    <style>
      body {padding: 10px; background-color: #ffffff}
    </style>
  </head>
  <body>
    '
. $body .'
  </body>
</html>'
;
  }

  
  // http://us.php.net/manual/en/function.imagecolorat.php
function rgba2int($r, $g, $b, $a=1) {
    /*
    This function builds a 32 bit integer from 4 values which must be 0-255 (8 bits)
    Example 32 bit integer: 00100000010001000000100000010000
    The first 8 bits define the alpha
    The next 8 bits define the blue
    The next 8 bits define the green
    The next 8 bits define the red
    */

    return ($a << 24) + ($b << 16) + ($g << 8) + $r;
}
function
int2rgba($int) {
    $a = ($int >> 24) & 0xFF;
    $b = ($int >> 16) & 0xFF;
    $g = ($int >> 8) & 0xFF;
    $r = $int & 0xFF;
    return array('r'=>$r, 'g'=>$g, 'b'=>$b, 'a'=>$a);
}

?>


(EDIT: aangepast)


De laatste veranderingen zijn vlug vlug in mekaar gestoken. De functies zijn aan verfijning toe. Voorlopig kan je er wel mee voort, denk ik.
Beschouw dit dus als een quick and dirty versie
Gewijzigd op 01/01/1970 01:00:00 door Emmanuel Delay
 
Ceasar Feijen

Ceasar Feijen

18/07/2009 12:54:00
Quote Anchor link
Kijk anders hier even hoe ze het gedaan hebben.
Of makkelijker :) Gebruik gewoon deze class
http://www.mywebmymail.com/?q=content/easyphpthumbnail-class
 
Emmanuel Delay

Emmanuel Delay

18/07/2009 13:02:00
Quote Anchor link
Ziet er goed uit.

Ja, ik heb de (soms slechte) gewoonte om vaak zelf eens te proberen.
Vaak vind ik dan ook opnieuw het warm water uit.
 
Ceasar Feijen

Ceasar Feijen

18/07/2009 13:11:00
Quote Anchor link
Ik heb de pro versie hiervan aangeschaft en verder gewoon wat verbeteringen gemaakt die je in het forum van de maker kunt vinden
vb met crop en water effect
http://www.alexanderbeets.nl/gallery.html
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.