PHPのお勉強!

PHP TOP

imagecolortransparent

(PHP 4, PHP 5, PHP 7, PHP 8)

imagecolortransparent透明色を定義する

説明

imagecolortransparent(GdImage $image, ?int $color = null): int

指定した画像 image 上の透明色を設定したり、取得したりします。

パラメータ

image

imagecreatetruecolor()のような画像作成関数が返す GdImage オブジェクト。

color

imagecolorallocate() で作成された色識別子。

戻り値

新しい透明色の ID (指定しなかった場合は現在設定されている ID) を返します。colornull の場合、 かつ現在の透明色も設定されていない場合は -1 を返します。

変更履歴

バージョン 説明
8.0.0 image は、 GdImage クラスのインスタンスを期待するようになりました。 これより前のバージョンでは、有効な gd resource が期待されていました。
8.0.0 color は、nullable になりました。

例1 imagecolortransparent() の例

<?php
// 55x30 の画像を作成します
$im = imagecreatetruecolor(55, 30);
$red = imagecolorallocate($im, 255, 0, 0);
$black = imagecolorallocate($im, 0, 0, 0);

// 背景を透明にします
imagecolortransparent($im, $black);

// 赤い矩形を描画します
imagefilledrectangle($im, 4, 4, 50, 25, $red);

// 画像を保存します
imagepng($im, './imagecolortransparent.png');
imagedestroy($im);
?>

上の例の出力は、 たとえば以下のようになります。

出力例 : imagecolortransparent()

注意

注意:

透過性は imagecopymerge() かつ True カラーの場合のみコピーされます。imagecopy() もしくはパレットイメージの場合はコピーされません。

注意:

透明色は画像のプロパティであり、色のプロパティではありません。 ある色を透明色と定義したら、画像上で既にその色で着色されてる領域も 透明になります。

add a note

User Contributed Notes 28 notes

up
5
erik at vectorsector dot net
17 years ago
This script creates transparency for a unspecific RBG color for an already created PNG image. It also includes script of overlay text that does not get ruined in the process.

<?php

header
("Content-type: image/png");
$image = imagecreatetruecolor(250, 250);
$string = $_GET['text'];
$im = imagecreatefrompng("dynIcon.png");
$img = imagecreatetruecolor(16,16);
$orange = imagecolorallocate($im, 220, 210, 60);
$bg_color = imagecolorat($im,1,1);
$px = (imagesx($im) - 3 * strlen($string)) / 2;
imagecolortransparent($im, $bg_color);
imagestring($im, 3, $px, 5, $string, $orange);
imagepng($im);
imagedestroy($im);

?>

Use $bg_color = imagecolorat($im,1,1); for instance, if you made the transparent color in photoshop by clearing out all the color leaving you with the checkered background showing you it's empty.
up
10
markglibres at yahoo dot com
15 years ago
I've made a very simple script that will retain transparency of images especially when resizing.

NOTE: Transparency is only supported on GIF and PNG files.

Parameters:

$new_image = image resource identifier such as returned by imagecreatetruecolor(). must be passed by reference
$image_source = image resource identifier returned by imagecreatefromjpeg, imagecreatefromgif and imagecreatefrompng. must be passed by reference

<?php
function setTransparency($new_image,$image_source)
{

$transparencyIndex = imagecolortransparent($image_source);
$transparencyColor = array('red' => 255, 'green' => 255, 'blue' => 255);

if (
$transparencyIndex >= 0) {
$transparencyColor = imagecolorsforindex($image_source, $transparencyIndex);
}

$transparencyIndex = imagecolorallocate($new_image, $transparencyColor['red'], $transparencyColor['green'], $transparencyColor['blue']);
imagefill($new_image, 0, 0, $transparencyIndex);
imagecolortransparent($new_image, $transparencyIndex);

}
?>


Sample Usage: (resizing)

<?php
$image_source
= imagecreatefrompng('test.png');
$new_image = imagecreatetruecolor($width, $height);
setTransparency($new_image,$image_source);
imagecopyresampled($new_image, $image_source, 0, 0, 0, 0, $new_width, $new_height, $old_width, $old_height);
?>
up
3
email at vladislav dot net
13 years ago
Pay attention, that some GIF images may not include a transparent color. A good example of forced transparency in resized GIF image was given by markglibres at yahoo dot com 29-Mar-2009 02:48. But sometimes the transparent color in GIF images can be not set. The problem is, that the color you force to be transparent can be used in the original GIF as opaque and you will loose that color in resized image. The solution is not to use some default transparent color and to leave the resized image without transparent color (the same as original GIF). I used (nearly) the following code to make resized GIF images trnsparent only when the transparency is needed:

<?php
/* ... */

$img = ImageCreateFromGIF($f); /* create image from existing GIF: original image file name $f you may take from where you need */
$transparent_index = ImageColorTransparent($img); /* gives the index of current transparent color or -1 */
if($transparent_index!=(-1)) $transparent_color = ImageColorsForIndex($img,$transparent_index);

/* ... */

$img_resized = ImageCreateTrueColor( $nw, $nh ); /* (the new width $nw and height $nh must be defined before) */
if(!empty($transparent_color)) /* simple check to find wether transparent color was set or not */
{
$transparent_new = ImageColorAllocate( $img_resized, $transparent_color['red'], $transparent_color['green'], $transparent_color['blue'] );
$transparent_new_index = ImageColorTransparent( $img_resized, $transparent_new );
ImageFill( $img_resized, 0,0, $transparent_new_index ); /* don't forget to fill the new image with the transparent color */
}
list(
$w,$h) = GetImageSize($f); /* defines the original width $w and height $h */
if( ImageCopyResized( $img_resized, $img, 0,0, 0,0, $nw,$nh, $w,$h ) ) /* resized copying and replacing the original image */
{
ImageDestroy($img);
$img = $img_resized;
}

/* ... */

header('Content-Type: image/gif');
ImageGIF($img);
ImageDestroy($img);
?>

P.S.
If there some errors, I hope you could understood the idea.
up
1
romanenko.alex.v at gmail.com
10 years ago
This function has a very strange behaviour with GD version > 2. It returns count of colors instead of -1 (as noted) if cannot find transparent color. Be carefull!
up
1
steved at HaHaHa dot com dot au
16 years ago
How to center your text both vertically and horizontally in a GD image:

<?php
//get box size
$box = imagettfbbox($titlesize, 0, $titlefont, $title);

//Find out the width and height of the text box
$textW = $box[2] - $box[0];
$textH = $box[5] - $box[3];

// Calculate the positions
$positionLeft = ($width - $textW)/2;
$positionTop = (($height - $textH)/2);

// Add some text
if($align=="center"){
imagettftext($pic, size, angle, $positionLeft, $positionTop, colour, font, message);
?>
up
1
Mikasto
17 years ago
To resize transparent PNG (if image is transparent & ImageColorTransparent() returns -1):
1) create a new image with the new sizes
2) make the new image all transparent
3) turn off the alpha blending for the new image (to keep the alpha channel when copy data)
4) do copyresampled or copyresized into new image

PHP code:
// 1
$im2 = ImageCreateTrueColor($w, $h);
// 2
ImageColorTransparent($im2, ImageColorAllocate($im2, 0, 0, 0));
// 3
ImageAlphaBlending($im2, false);
// 4
ImageCopyResampled($im2, $im, 0, 0, 0, 0, $w, $h, ImageSX($im), ImageSY($im));
up
1
talkback at codesponge dot com
19 years ago
Only one color may be transparent in one image. The last call to imagecolortransparent will be the color that is set to transparent.

I am processing button images that have a slightly different fill color than the background color outside the border of the button. I was hoping that I could just make both of those colors transparent and solve the problem.

Hope this tidbit of info will save you some time.
up
1
cca220v
16 years ago
I found out the hard way that for two png's with alpha transparency to correctly stack you need to explicitly re-enable alpha blending.

$img=imagecreatetruecolor($dx,$dy);
$img1=imagecreatefrompng($png1); //first layer
$img2=imagecreatefrompng($png2); //second layer (smaller image)

imagealphablending($img, false);
$transparent = imagecolorallocatealpha($img, 0, 0, 0, 127);
imagefill($img, 0, 0, $transparent);
imagesavealpha($img,true);
imagealphablending($img, true); //removing this causes the second layer's transparency to go trough the 1st layer erasing it (the image >is< transparent there ... as is the 2nd layer ... but not the 1st so it should not be transparent)

imagecopyresampled($img,$img1,
imagecopyresampled($img,$img2,
up
1
webmaster at webnetwizard dotco dotuk
19 years ago
After much devious mindbending, I have found a way to test any GIF for presence of background transparency. This ability is essential for my application which uploads any of GIF, JPEG or PNG and simultaneously creates a thumbnail of identical image type and identical filename (full size and thumbnail versions being stored in different folders).
After uploading and moving the image in the usual way, a switch($image_type) statement ensures that the optimum code is used to generate the thumbnail; regardless of image type.
The problem with the GIF type is that those with transparent backgrounds need to be treated differently to those without. When I don't detect GIF transparency, I either end up with all transparent GIF's having black backgrounds, or all GIF's get converted to transparent background - even if they weren't transparent in the original.
But how to detect transparency in the original? It finally occurred to me that I could test for transparency programmatically by overlaying a copy of the original image over an all-black image, record the color value at particular pixel locations and then repeat the process by overlaying a copy of the original image over an all-white image, recording the color values at identical pixel locations and comparing these with the first set of values.
If the two sets of values correlate exactly, and if sensible sampling points are used, the image can be treated as non-transparent. If the two sets of values show differences, the image should be treated as having a transparent background.
up
1
fmkaiba at optonline dot net
16 years ago
This is my 'perfect' (i use that word lightly) thumbnail generation script, switch '$transparency' to true to have it do its best to handle transparency in gifs and pngs. this code is built off of comments and advice of everyone else here, and i do not deserve full credit. So far this handles every error i can throw at it.
<?php
function createthumb($name, $newname, $new_w, $new_h, $border=false, $transparency=true, $base64=false) {
if(
file_exists($newname))
@
unlink($newname);
if(!
file_exists($name))
return
false;
$arr = split("\.",$name);
$ext = $arr[count($arr)-1];

if(
$ext=="jpeg" || $ext=="jpg"){
$img = @imagecreatefromjpeg($name);
} elseif(
$ext=="png"){
$img = @imagecreatefrompng($name);
} elseif(
$ext=="gif") {
$img = @imagecreatefromgif($name);
}
if(!
$img)
return
false;
$old_x = imageSX($img);
$old_y = imageSY($img);
if(
$old_x < $new_w && $old_y < $new_h) {
$thumb_w = $old_x;
$thumb_h = $old_y;
} elseif (
$old_x > $old_y) {
$thumb_w = $new_w;
$thumb_h = floor(($old_y*($new_h/$old_x)));
} elseif (
$old_x < $old_y) {
$thumb_w = floor($old_x*($new_w/$old_y));
$thumb_h = $new_h;
} elseif (
$old_x == $old_y) {
$thumb_w = $new_w;
$thumb_h = $new_h;
}
$thumb_w = ($thumb_w<1) ? 1 : $thumb_w;
$thumb_h = ($thumb_h<1) ? 1 : $thumb_h;
$new_img = ImageCreateTrueColor($thumb_w, $thumb_h);

if(
$transparency) {
if(
$ext=="png") {
imagealphablending($new_img, false);
$colorTransparent = imagecolorallocatealpha($new_img, 0, 0, 0, 127);
imagefill($new_img, 0, 0, $colorTransparent);
imagesavealpha($new_img, true);
} elseif(
$ext=="gif") {
$trnprt_indx = imagecolortransparent($img);
if (
$trnprt_indx >= 0) {
//its transparent
$trnprt_color = imagecolorsforindex($img, $trnprt_indx);
$trnprt_indx = imagecolorallocate($new_img, $trnprt_color['red'], $trnprt_color['green'], $trnprt_color['blue']);
imagefill($new_img, 0, 0, $trnprt_indx);
imagecolortransparent($new_img, $trnprt_indx);
}
}
} else {
Imagefill($new_img, 0, 0, imagecolorallocate($new_img, 255, 255, 255));
}

imagecopyresampled($new_img, $img, 0,0,0,0, $thumb_w, $thumb_h, $old_x, $old_y);
if(
$border) {
$black = imagecolorallocate($new_img, 0, 0, 0);
imagerectangle($new_img,0,0, $thumb_w, $thumb_h, $black);
}
if(
$base64) {
ob_start();
imagepng($new_img);
$img = ob_get_contents();
ob_end_clean();
$return = base64_encode($img);
} else {
if(
$ext=="jpeg" || $ext=="jpg"){
imagejpeg($new_img, $newname);
$return = true;
} elseif(
$ext=="png"){
imagepng($new_img, $newname);
$return = true;
} elseif(
$ext=="gif") {
imagegif($new_img, $newname);
$return = true;
}
}
imagedestroy($new_img);
imagedestroy($img);
return
$return;
}
//example useage
createthumb("img.gif", "tn_img.gif", 64,64,true, true, false);
?>
up
1
wesley dot gunn at email dot it
17 years ago
a simple way to check png with alpha channel reading IHDR PNG HEADER

$readPng = fopen ($argSourceImagePath, "rb");
$readAlp = fread ($readPng, 52);
fclose ($readPng);

if(substr(bin2hex($readAlp),50,2) == "04" || substr(bin2hex($readAlp),50,2) == "06")
echo("Png has alpha");
up
1
glenn at bengeweb dot co dot nz
18 years ago
in reference to webmaster at webnetwizard dotco dotuk who had a rather complicated method of determining if a GIF had any transparency set ...

imagecolortransparent will return -1 if no transparency is found.

eg:

$transColorIndexMain = imageColorTransparent($mainImgObj);
if ($transColorIndexMain >= 0 ) {
# GIF has transparency ... ;
}

Current PHP Version: 4.4.4
[GD Version] => bundled (2.0.28 compatible)
up
1
emilus at galeria-m dot art dot pl
20 years ago
To resize or copy image (gif [with gd>=2.0.28] or png) with transparency.
-Take current transparency color
-create a new image with palette like old one and fill new image with transparent color
-set transparent color
-copy resized image

$colorTransparent = imagecolortransparent($im);
$im2 = imagecreate($new_w,$new_h);
imagepalettecopy($im2,$im);
imagefill($im2,0,0,$colorTransparent);
imagecolortransparent($im2, $colorTransparent);
imagecopyresized($im2,$im,0,0,0,0,$new_w,$new_h,$imsx,$imsy);
up
1
creator79>>web>>de
21 years ago
Hi!
I'm using GDLib 1.6.3 so far I know.
You can have transparency on any defined color on any image type when using the imagecolorclosest($im, $R, $G, $B) function instead of imagecolorallocate() or imagecolorexact().
up
0
Sebastian Sejzer
9 years ago
If you are looking for a blank PNG, you don't need to generate it every time. Just define this constant:

define("BLANK_PNG", "iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29m".
"dHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAADqSURBVHjaYvz//z/DYAYAAcTEMMgBQAANegcCBNCg".
"dyBAAA16BwIE0KB3IEAADXoHAgTQoHcgQAANegcCBNCgdyBAAA16BwIE0KB3IEAADXoHAgTQoHcgQAAN".
"egcCBNCgdyBAAA16BwIE0KB3IEAADXoHAgTQoHcgQAANegcCBNCgdyBAAA16BwIE0KB3IEAADXoHAgTQ".
"oHcgQAANegcCBNCgdyBAAA16BwIE0KB3IEAADXoHAgTQoHcgQAANegcCBNCgdyBAAA16BwIE0KB3IEAA".
"DXoHAgTQoHcgQAANegcCBNCgdyBAgAEAMpcDTTQWJVEAAAAASUVORK5CYII=");
up
0
john at jbwalker dot com
12 years ago
A transparent background with text doesn't seem to work very well because of the antialiasing . But I tried the following kluge and it turned out very well:

<?php
$im
= imagecreatetruecolor(100,20);
$almostblack = imagecolorallocate($im,254,254,254);
imagefill($im,0,0,$almostblack);
$black = imagecolorallocate($im,0,0,0);
imagecolortransparent($im,$almostblack);
//... set x and y..
imagettftext($im,8,0,$x,$y,$black,"calibri.ttf",$txt);
?>
up
0
admin at fastproxyservers dot org
14 years ago
I would like to share with others how to make PNG image transparent. I have tried almost all examples described on that page but none of them work for me. Finally I found the solution, but there is a bit cheating :) but who cares if it works?

So when I tried to allocate white (as an example) color as a transparent, it worked randomly (lets say 1 in 10 examples). That in turn pushed me to the idea that the problem is that white color is already exist in color palette. So if I try to add another white color with DIFFERENT index as a transparent, that will cause error.

So I found the solution, instead of adding new index, I searched for the white color’s index in the color palette and made it defined as transparent :) The best idea is to use not a white but left bottom corner as transparent color (I guess that s standard for some other software languages).

<?php
$index
= imagecolorexact($this->image, 255, 255, 255);
imagecolortransparent($this->image, $index);
?>

All you need is to add that two lines before outputting your result.
up
0
ajamal
15 years ago
This might be of importance to newbies...If you are trying to create GIF's with transparencies, stick to the 216 colour pallet for all colours on the image... or transparencies wont work...at the very least yo will get dithering...