Imagerotate met transparante png
Is er een manier om een png te draaien zodat wat nu zwart is transparant wordt?
Alvast bedankt,
Mark
index.php
Code (php)
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
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;
}
?>
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
Klopt het trouwens dat de functie imagecolorallocate alle zwarte pixels transparant maakt, want dan zouden er ook delen van mijn plaatje verdwijnen...
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)
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
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>';
}
?>
$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
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)
Code (php)
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
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);
}
?>
$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
Of makkelijker :) Gebruik gewoon deze class
http://www.mywebmymail.com/?q=content/easyphpthumbnail-class
Ja, ik heb de (soms slechte) gewoonte om vaak zelf eens te proberen.
Vaak vind ik dan ook opnieuw het warm water uit.