2024 年 PHP Conference Japan

imagecopymerge

(PHP 4 >= 4.0.1, PHP 5, PHP 7, PHP 8)

imagecopymerge複製並合併部分影像

說明

imagecopymerge(
    GdImage $dst_image,
    GdImage $src_image,
    int $dst_x,
    int $dst_y,
    int $src_x,
    整數 (int) $src_y,
    整數 (int) $src_width,
    整數 (int) $src_height,
    整數 (int) $pct
): 布林值 (bool)

src_image 的一部分複製到 dst_image 上,起始位置的 x、y 座標為 src_xsrc_y,寬度為 src_width,高度為 src_height。定義的部分將複製到 x、y 座標 dst_xdst_y 上。

參數

dst_image

目標影像資源。

src_image

來源影像資源。

dst_x

目標點的 x 座標。

dst_y

目標點的 y 座標。

src_x

來源點的 x 座標。

src_y

來源點的 y 座標。

src_width

來源寬度。

src_height

來源高度。

pct

這兩個影像將根據 pct 合併,範圍從 0 到 100。當 pct = 0 時,不執行任何操作;當 pct = 100 時,此函式的行為與調色盤影像的 imagecopy() 相同,但會忽略 Alpha 元件,而對於真彩影像,它會實作 Alpha 透明度。

回傳值

成功時回傳 true,失敗時回傳 false

更新日誌

版本 說明
8.0.0 dst_imagesrc_image 現在需要 GdImage 實例;先前需要的是 資源

範例

範例 #1 以 75% 透明度合併 PHP.net 標誌的兩個副本

<?php
// 建立影像實例
$dest = imagecreatefromgif('php.gif');
$src = imagecreatefromgif('php.gif');

// 複製並合併
imagecopymerge($dest, $src, 10, 10, 0, 0, 100, 47, 75);

// 輸出並釋放記憶體
header('Content-Type: image/gif');
imagegif($dest);

imagedestroy($dest);
imagedestroy($src);
?>

新增註釋

使用者貢獻的註釋 22 則註釋

Sina Salek
15 年前
我剛查看了 PHP 的問題追蹤器,一位核心開發者說這個函式從來就沒打算支援 Alpha 通道!而且他們拒絕提交提供的修補程式!真是荒謬。
無論如何,我嘗試了 rodrigo 的解決方法,而且效果相當不錯,感謝 rodrigo 的分享。
我想出了另一個比他的解決方案快得多的主意(它可能需要多一點記憶體)。

希望它能幫助到某些人。

<?php
/**
* 支援 PNG Alpha 透明通道的 imagecopymerge(); 函式
* 作者:Sina Salek
*
* 由 Ralph Voigt 修正錯誤 (導致此函式僅在 $src_x = $src_y = 0 時才能正常運作的錯誤。
* 此外,也不需要反轉透明度。)
* 2011年1月8日
*
**/
function imagecopymerge_alpha($dst_im, $src_im, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $pct){
// 建立一個裁切用的資源
$cut = imagecreatetruecolor($src_w, $src_h);

// 將背景圖的相關區塊複製到裁切資源
imagecopy($cut, $dst_im, 0, 0, $dst_x, $dst_y, $src_w, $src_h);

// 將浮水印的相關區塊複製到裁切資源
imagecopy($cut, $src_im, 0, 0, $src_x, $src_y, $src_w, $src_h);

// 將裁切資源插入到目標圖片
imagecopymerge($dst_im, $cut, $dst_x, $dst_y, 0, 0, $src_w, $src_h, $pct);
}

?>
Leo
12 年前
PHP 的 imagecopymerge 函式幫助我建立了一個快速的方法,可以在真彩色圖像中取代一種顏色為另一種顏色。

在此之前,為了達到這個目的,我必須遍歷圖像的所有像素,並使用 imagecolorat 和 imagesetpixel 逐個像素地替換顏色;這種方法對於大型圖像來說非常慢。

所以這裡有一個快速的方法

<?php

函數 replaceColorInImage ($image, $old_r, $old_g, $old_b, $new_r, $new_g, $new_b)
{
imagecolortransparent ($image, imagecolorallocate ($image, $old_r, $old_g, $old_b));

$w = imagesx ($image);
$h = imagesy ($image);

$resImage = imagecreatetruecolor ($w, $h);

imagefill ($resImage, 0, 0, imagecolorallocate ($resImage, $new_r, $new_g, $new_b));

imagecopymerge ($resImage, $image, 0, 0, 0, 0, $w, $h, 100);

return $resImage;
}

?>
Steve
19 年前
基於 backglancer 和 stefan 以下的貼文,以下腳本會在任何圖片上疊加一個 24 位元 PNG 浮水印。

要準備 24 位元浮水印,我建議在 Photoshop 中建立一個白色商標或文字,背景設為透明。透過「儲存為網頁用…」將其儲存為 24 位元 PNG。務必在 Photoshop 中設定商標圖層的透明度。30-40% 是不錯的設定。

資源準備好後,將完整或相對的伺服器路徑傳給以下的浮水印函式

/******************************************************************/

函數 watermark($sourcefile, $watermarkfile) {

#
# $sourcefile = 要加上浮水印的圖片檔名。
# $watermarkfile = 24 位元 PNG 浮水印檔案的檔名。
#

//取得圖片的資源 ID
$watermarkfile_id = imagecreatefrompng($watermarkfile);

imageAlphaBlending($watermarkfile_id, false);
imageSaveAlpha($watermarkfile_id, true);

$fileType = strtolower(substr($sourcefile, strlen($sourcefile)-3));

switch($fileType) {
case('gif')
$sourcefile_id = imagecreatefromgif($sourcefile);
break;

case('png')
$sourcefile_id = imagecreatefrompng($sourcefile);
break;

default
$sourcefile_id = imagecreatefromjpeg($sourcefile);
}

//取得兩個像素的尺寸
$sourcefile_width=imageSX($sourcefile_id);
$sourcefile_height=imageSY($sourcefile_id);
$watermarkfile_width=imageSX($watermarkfile_id);
$watermarkfile_height=imageSY($watermarkfile_id);

$dest_x = ( $sourcefile_width / 2 ) - ( $watermarkfile_width / 2 );
$dest_y = ( $sourcefile_height / 2 ) - ( $watermarkfile_height / 2 );

// 如果是 gif,我們必須將其升頻到真彩圖像
if($fileType == 'gif') {
// 建立一個空的真彩容器
$tempimage = imagecreatetruecolor($sourcefile_width,
$sourcefile_height);

// 將 8 位元 gif 複製到真彩圖像中
imagecopy($tempimage, $sourcefile_id, 0, 0, 0, 0,
$sourcefile_width, $sourcefile_height);

// 複製來源圖片 ID 的整數值
$sourcefile_id = $tempimage;
}

imagecopy($sourcefile_id, $watermarkfile_id, $dest_x, $dest_y, 0, 0,
$watermarkfile_width, $watermarkfile_height);

//從修改後的圖片建立 JPEG 檔案
switch($fileType) {

// 我們不再需要 GIF 了,所以只使用 PNG 或 JPEG。
// 參見上面緊鄰的放大程式碼,了解我們如何處理 GIF
case('png')
header("Content-type: image/png");
imagepng ($sourcefile_id);
break;

default
header("Content-type: image/jpg");
imagejpeg ($sourcefile_id);
}

imagedestroy($sourcefile_id);
imagedestroy($watermarkfile_id);

}
Leo
12 年前
以下函式會為指定顏色建立真彩圖像的遮罩。以前建立圖像遮罩時,我習慣使用 imagecolorat 迴圈遍歷所有圖像像素,檢查它們的顏色,如果顏色匹配,則使用 imagesetpixel 複製。這對於大型圖像來說非常慢,因此以下程式碼改進了這個過程。

<?php

function getOppositeColor ($color)
{
return (
( (
255 - ($color >> 16) & 0xFF) << 16 ) +
( (
255 - ($color >> 8 ) & 0xFF) << 8 ) +
( (
255 - ($color ) & 0xFF) )
);
}

function
createImageMask (&$image, $color)
{
$w = imagesx ($image);
$h = imagesy ($image);

$tmpImage = imagecreatetruecolor ($w, $h);

imagecopy ($tmpImage, $image, 0, 0, 0, 0, $w, $h);

imagefilter ($image, IMG_FILTER_NEGATE);

imagecolortransparent ($image, getOppositeColor ($color));

imagecopymerge ($tmpImage, $image, 0, 0, 0, 0, $w, $h, 50);

imagedestroy ($image);

$image = $tmpImage;
}

?>

例如,如果我們有一張照片,並指定顏色 = (255, 0, 0),也就是紅色,結果將會是一張大小相同的圖片,其中原本照片中紅色像素的位置會顯示紅色,其他位置則顯示灰色像素。
backglancer in the hotmail
19 年前
我差點要崩潰了…
你們有人試圖合併半透明的 PNG 嗎…
使用 imagecopy :)
<?
$flag = imagecreatefrompng('flags/images/flagWhiteFill.png');
$mask = imagecreatefrompng('flags/images/flag_transparent.png');

imagealphablending($flag, 1);
imagealphablending($mask, 1);

imagecopy($flag, $mask, 0, 0, 0, 0, 25, 43);

Header("Content-type: image/jpeg");
imagepng($flag);
?>

ImageSaveAlpha(resource, bool); 設定透明色彩時,卻沒有透明效果... 不知道為什麼 :)
rodrigo dot polo at gmail dot com
15 年前
<?php
/**
* PNG ALPHA CHANNEL SUPPORT for imagecopymerge();
* This is a function like imagecopymerge but it handle alpha channel well!!!
**/

// A fix to get a function like imagecopymerge WITH ALPHA SUPPORT
// Main script by aiden dot mail at freemail dot hu
// Transformed to imagecopymerge_alpha() by rodrigo dot polo at gmail dot com
function imagecopymerge_alpha($dst_im, $src_im, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $pct){
if(!isset(
$pct)){
return
false;
}
$pct /= 100;
// Get image width and height
$w = imagesx( $src_im );
$h = imagesy( $src_im );
// Turn alpha blending off
imagealphablending( $src_im, false );
// Find the most opaque pixel in the image (the one with the smallest alpha value)
$minalpha = 127;
for(
$x = 0; $x < $w; $x++ )
for(
$y = 0; $y < $h; $y++ ){
$alpha = ( imagecolorat( $src_im, $x, $y ) >> 24 ) & 0xFF;
if(
$alpha < $minalpha ){
$minalpha = $alpha;
}
}
//loop through image pixels and modify alpha for each
for( $x = 0; $x < $w; $x++ ){
for(
$y = 0; $y < $h; $y++ ){
//get current alpha value (represents the TANSPARENCY!)
$colorxy = imagecolorat( $src_im, $x, $y );
$alpha = ( $colorxy >> 24 ) & 0xFF;
//calculate new alpha
if( $minalpha !== 127 ){
$alpha = 127 + 127 * $pct * ( $alpha - 127 ) / ( 127 - $minalpha );
} else {
$alpha += 127 * $pct;
}
//get the color index with new alpha
$alphacolorxy = imagecolorallocatealpha( $src_im, ( $colorxy >> 16 ) & 0xFF, ( $colorxy >> 8 ) & 0xFF, $colorxy & 0xFF, $alpha );
//set pixel with the new color + opacity
if( !imagesetpixel( $src_im, $x, $y, $alphacolorxy ) ){
return
false;
}
}
}
// The image copy
imagecopy($dst_im, $src_im, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h);
}

// USAGE EXAMPLE:
$img_a = imagecreatefrompng('image1.png');
$img_b = imagecreatefrompng('wm2.png');

// SAME COMMANDS:
imagecopymerge_alpha($img_a, $img_b, 10, 10, 0, 0, imagesx($img_b), imagesy($img_b),50);

// OUTPUT IMAGE:
header("Content-Type: image/png");
imagesavealpha($img_a, true);
imagepng($img_a, NULL);
?>
gigitrix
16 年前
一些很有趣的東西:這段程式碼看起來很正常,是一種隨機裁切圖片片段的方法。

<?php
header
("Content-Type: image/jpeg");
$width=837;
$height=771;
$origim = imagecreatefromjpeg("theimage.jpeg"); /* 嘗試開啟 */
$imagetodisplay=imagecreate($width, $height);

for(
$i=0;$i<=100;$i++)
{
$xPos=rand(0,$width-9);
$yPos=rand(0,$height-9);
imagecopy($imagetodisplay, $origim, $xPos, $yPos , $xPos, $yPos , 10 , 10);
}

imagejpeg($imagetodisplay);
imagedestroy($imagetodisplay);
imagedestroy($origim);
?>

然而,試著執行這段程式碼,一個被忽略的細節增添了趣味。由於第一個被定義的顏色會被視為背景顏色,我們從 $origim 中隨機選擇一個顏色作為 $imagetodisplay 的背景顏色,但這個隨機顏色會根據背景圖片進行加權。這是一個驚喜(我原本以為背景會是黑色),但我現在決定保留它,因為看起來不錯。
jtacon at php dot net
19 年前
這個範例展示如何使用 imageCopyMerge 建立一個浮水印函式,並將浮水印放置在四個隨機位置(四個角落)。

<?php
函式 waterMark($fileInHD, $wmFile, $transparency = 50, $jpegQuality = 90, $margin = 5) {

$wmImg = imageCreateFromGIF($wmFile);
$jpegImg = imageCreateFromJPEG($fileInHD);

// 浮水印隨機位置
$wmX = (bool)rand(0,1) ? $margin : (imageSX($jpegImg) - imageSX($wmImg)) - $margin;
$wmY = (bool)rand(0,1) ? $margin : (imageSY($jpegImg) - imageSY($wmImg)) - $margin;

// 浮水印處理
imageCopyMerge($jpegImg, $wmImg, $wmX, $wmY, 0, 0, imageSX($wmImg), imageSY($wmImg), $transparency);

// 覆寫圖片
ImageJPEG($jpegImg, $fileInHD, $jpegQuality);
}

waterMark('myImage.jpg','waterMark.gif');

?>

希望有幫助。

Javier Tacón.
stefan dot wehowsky at profilschmiede dot de
23 年前
此函式旨在作為 "imageCopyMerge" 函式的範例。
我希望它能幫助一些經驗較少的 PHP 編碼人員。
我寫這個函式是為了將房地產經紀人的物件標記為「已售出」,方法是將「已售出」圖片複製到房屋圖片中。

<?php

//$sourcefile = Filename of the picture into that $insertfile will be inserted.
//$insertfile = Filename of the picture that is to be inserted into $sourcefile.
//$targetfile = Filename of the modified picture.
//$transition = Intensity of the transition (in percent)
//$pos = Position where $insertfile will be inserted in $sourcefile
// 0 = middle
// 1 = top left
// 2 = top right
// 3 = bottom right
// 4 = bottom left
// 5 = top middle
// 6 = middle right
// 7 = bottom middle
// 8 = middle left
//
//
function mergePix($sourcefile,$insertfile, $targetfile, $pos=0,$transition=50)
{

//Get the resource id?s of the pictures
$insertfile_id = imageCreateFromJPEG($insertfile);
$sourcefile_id = imageCreateFromJPEG($sourcefile);

//Get the sizes of both pix
$sourcefile_width=imageSX($sourcefile_id);
$sourcefile_height=imageSY($sourcefile_id);
$insertfile_width=imageSX($insertfile_id);
$insertfile_height=imageSY($insertfile_id);

//middle
if( $pos == 0 )
{
$dest_x = ( $sourcefile_width / 2 ) - ( $insertfile_width / 2 );
$dest_y = ( $sourcefile_height / 2 ) - ( $insertfile_height / 2 );
}

//top left
if( $pos == 1 )
{
$dest_x = 0;
$dest_y = 0;
}

//top right
if( $pos == 2 )
{
$dest_x = $sourcefile_width - $insertfile_width;
$dest_y = 0;
}

//bottom right
if( $pos == 3 )
{
$dest_x = $sourcefile_width - $insertfile_width;
$dest_y = $sourcefile_height - $insertfile_height;
}

//bottom left
if( $pos == 4 )
{
$dest_x = 0;
$dest_y = $sourcefile_height - $insertfile_height;
}

//top middle
if( $pos == 5 )
{
$dest_x = ( ( $sourcefile_width - $insertfile_width ) / 2 );
$dest_y = 0;
}

//middle right
if( $pos == 6 )
{
$dest_x = $sourcefile_width - $insertfile_width;
$dest_y = ( $sourcefile_height / 2 ) - ( $insertfile_height / 2 );
}

//bottom middle
if( $pos == 7 )
{
$dest_x = ( ( $sourcefile_width - $insertfile_width ) / 2 );
$dest_y = $sourcefile_height - $insertfile_height;
}

//middle left
if( $pos == 8 )
{
$dest_x = 0;
$dest_y = ( $sourcefile_height / 2 ) - ( $insertfile_height / 2 );
}

//The main thing : merge the two pix
imageCopyMerge($sourcefile_id, $insertfile_id,$dest_x,$dest_y,0,0,$insertfile_width,$insertfile_height,$transition);

//Create a jpeg out of the modified picture
imagejpeg ($sourcefile_id,"$targetfile");

}
claudio dot gaetani at gdldesign dot it
20 年前
此函式旨在作為 "imageCopyMerge"- "ImageCopyResized", "ImageColorTransparent" 函式的範例。
我希望它能有所幫助。
此函式選取一張圖片,將其裁剪為正方形,重新取樣至要求的大小,最後將結果與另一張圖片合併,以獲得圓形圖片結果。我遇到的問題是如何獲得一個縮圖,它既能尊重顏色,又能以圓形裁剪,我希望這個解決方案能給你一些線索,讓你獲得自由形式的圖片,我也用這個方法來創建多重裁剪的圖片。

<?php
$generalsrc
="$image"; //the image to resample, resize and iconaize
$final_thumbwidth ="125";
$final_thumbheight ="125";

$abc = imagecreatefromjpeg("$generalsrc");
$def = imagecreatetruecolor($final_thumbwidth, $final_thumbheight);
$src_mx = round((imagesx($abc) / 2)-"0.1"); // middle x point of the image
$src_my = round((imagesy($abc) / 2)-"0.1"); // middle y point of the image
$src_x = ($src_mx * 2);
$src_y = ($src_my * 2);
$src_sq = ($src_x >= $src_y)?$src_y:$src_x; //used to define the best size for a square cut of the image
$pl = ($src_x >= $src_y)?"1":"2"; //define if the image is portait or landscape
$strt_pntx = ($pl=="1")?round(($src_my / 2)-"0. 1"):"0"; //defines the x start point
$strt_pnty = ($pl=="2")?round(($src_mx / 2)-"0. 1"):"0"; //defines the y start point

imagecopyresized($def, $abc, 0, 0, $strt_pntx, $strt_pnty, $final_thumbwidth, $final_thumbheight, $src_sq, $src_sq);

$overlay_img = imagecreatefromPNG("circle_125.png"); //NOTE use png for this
$src_w = "ImageSX($overlay_img)";
$src_h = "ImageSY($overlay_img)";

$can_img = imagecreatetruecolor($src_w, $src_h);

$black = ImageColorAllocate ($overlay_img, 0, 0, 0);

ImageColorTransparent($overlay_img , $black);

imagecopy($can_img, $def, 0,0,0,0, $src_w, $src_h);
imagecopymerge($can_img, $overlay_img , 0,0,0,0, ImageSX($overlay_img), ImageSY($overlay_img),100); //Imagecopy won't work, you must used imagecopymerge

ImageJPEG($can_img,"merge_$generalsrc",100);

imagedestroy($overlay_img);
imagedestroy($can_img);
ImageDestroy($abc);
ImageDestroy($def);

print
"<HTML><HEAD><TITLE>test</TITLE></HEAD><BODY>
original:<hr><img src=\"
$generalsrc\" width=\"300\"><br><br><br>new:<hr><img src=\"merge_$generalsrc\">
<br>width =
$src_x
<br>height =
$src_y
<br>mdlw =
$src_mx
<br>mdlh =
$src_my
<br>sqr =
$src_sq
<br>pl =
$pl
<br>start point x =
$strt_pntx
<br>start point y =
$strt_pnty
</BODY></HTML>"
;
?>
nick at prient dot co dot uk
19 年前
任務:旋轉一張大圖,然後縮小它的大小,並將其放置在一個小的背景上(例如,作為插入圖)。

問題:如果您先調整影像大小,旋轉會產生嚴重的鋸齒... 所以,先旋轉再縮小影像比較合理。
遺憾的是,當您重新取樣影像時,您會遺失背景顏色(至少,某些顏色可能會改變),因此您無法再根據需要設定透明度。如果您改為調整影像大小(而不是重新取樣),鋸齒看起來同樣很糟。

解決方案:調整背景大小 - 將其放大。然後新增原始(大)嵌入圖像,並將整個影像調整回正常大小。

<?php
/* We will shrink the inset to 25% */
$resizePercentage = 0.25;

/* Load a source image and a background */
$iSource = ImageCreateFromJpeg($source_file);
$iBackground = ImageCreateFromJpeg($background_file);

/* Do something here, such a rotate, skew etc */
...
/* Assume $iSource is still the image we want to insert onto the background */

/* Set the background color to be transparent */
$cBackground = ImageColorClosest($iSource, 255, 0, 255);
ImageColorTransparent($iSource, $cBackground);

/* Resize the background - make it huge */
$iBackground = ImageResize($iTemplate, ImageSX($iBackground ) / $resizePercentage, ImageSY($iBackground ) / $resizePercentage);
/* Place the image on the background - all full size, so no aliasing issues */
ImageCopyMerge($iBackground , $iSource,
((
ImageSX($iBackground ) - ImageSX($iSource)) / 2),
((
ImageSY($iBackground ) - ImageSY($iSource)) / 2) - 25, 0, 0, ImageSX($iWorking), ImageSY($iSource), 100);
/* Shrink the combined image... no issues with transparancy! */
$iBackground = ImageResize($iTemplate, ImageSX($iBackground ) * $resizePercentage, ImageSY($iBackground ) * $resizePercentage);

/* Output the image as a PNG */
header("Content-Type: image/png");
ImagePng($iBackground);
exit();

function
ImageResize($pImage, $t_width, $t_height) {
// Target image
$iCanvas = @ImageCreateTrueColor($t_width, $t_height);
// Source dimensions
$s_width = ImageSX($pImage);
$s_height = ImageSY($pImage);
// Copy image
ImageCopyResampled($iCanvas, $pImage, 0, 0, 0, 0, $t_width, $t_height, $s_width, $s_height);
// Return image
return $iCanvas;
}
?>
barbarina_sv at libero dot it
19 年前
我需要在地圖上繪製一個「指標」影像,但在 png 影像透明度方面遇到了一些問題。
所以我建立了一個具有白色背景(非透明)的 png 影像,並在將白色定義為透明色後將其合併到我的地圖上

<?php

$src_file
= 'source.jpg';
list(
$src_w, $src_h, $src_t, $src_a) = getimagesize($src_file);

$ptr_file = 'pointer.png'; // must have no transparency, but white background
list($ptr_w, $ptr_h, $ptr_t, $ptr_a) = getimagesize($ptr_file);

// destination image dimensions:
$dst_w = 400;
$dst_h = 200;

// pointer position:
$ptr_x = 195;
$ptr_y = 70;

$srcImage = imageCreateFromJpeg($src_file) or die ('failed imageCreateFromJpg');
$dstImage = imageCreateTrueColor($dst_w, $dst_h) or die ('failed imageCreateTrueColor');

imageCopyResampled($dstImage, $srcImage, 0, 0, 0, 0, $dst_w, $dst_h, $src_w, $src_h) or die ('failed imageCopyResampled');

$ptrImage = imageCreateFromPng($ptr_file) or die ('failed imageCreateFromPng');

$ptr_white = imageColorAllocate($ptrImage,255,255,255);
imageColorTransparent($ptrImage,$ptr_white);

imageCopyMerge($dstImage, $ptrImage, $ptr_x, $ptr_y, 0, 0, $ptr_w, $ptr_h, 100) or die ('failed imageCopyMerge');

imageJpeg($dstImage,'',100) or die ('failed imageJpeg');

imageDestroy($srcImage) or die ('failed imageDestroy(1)');
imageDestroy($dstImage) or die ('failed imageDestroy(2)');
imageDestroy($ptrImage) or die ('failed imageDestroy(3)');

?>
jonny at sanriowasteland dot net
22 年前
如果您需要合併兩個具有不同調色盤的 png(或大概是兩個 gif),我發現這是要使用的函式。只需將 pct 設定為 99,您就搞定了。將 pct 設定為 100,或者使用 imagecopy,調色盤似乎會變得不正常。(它可能只使用了來源影像的調色盤,但這只是我的猜測,別引用我的話)。
Al
17 年前
檢查您的標頭... 他的說法是錯的...

<?php
header
("Content-Type: image/png");
?>
thciobanu
13 年前
這就是我在合併兩個影像時,同時遵守 Alpha 色版所使用的程式碼(公式取自維基百科關於 Alpha 合成的文章;它們看起來不太美觀,因為我並沒有真的試圖讓它們看起來很漂亮,而是讓它們能夠正常運作,並且在幾個月後查看時仍然能夠理解),有一個特殊之處 - 一個額外的參數(預設為 NULL 以忽略)可以手動指定「透明」顏色,該顏色不會從來源複製到目標。與這裡的其他實作相比,只對 $src_im 進行一次遍歷,但執行了更多計算

<?php
function imagecopymerge_alpha($dst_im, $src_im, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $pct, $trans = NULL)
{
$dst_w = imagesx($dst_im);
$dst_h = imagesy($dst_im);

// bounds checking
$src_x = max($src_x, 0);
$src_y = max($src_y, 0);
$dst_x = max($dst_x, 0);
$dst_y = max($dst_y, 0);
if (
$dst_x + $src_w > $dst_w)
$src_w = $dst_w - $dst_x;
if (
$dst_y + $src_h > $dst_h)
$src_h = $dst_h - $dst_y;

for(
$x_offset = 0; $x_offset < $src_w; $x_offset++)
for(
$y_offset = 0; $y_offset < $src_h; $y_offset++)
{
// get source & dest color
$srccolor = imagecolorsforindex($src_im, imagecolorat($src_im, $src_x + $x_offset, $src_y + $y_offset));
$dstcolor = imagecolorsforindex($dst_im, imagecolorat($dst_im, $dst_x + $x_offset, $dst_y + $y_offset));

// apply transparency
if (is_null($trans) || ($srccolor !== $trans))
{
$src_a = $srccolor['alpha'] * $pct / 100;
// blend
$src_a = 127 - $src_a;
$dst_a = 127 - $dstcolor['alpha'];
$dst_r = ($srccolor['red'] * $src_a + $dstcolor['red'] * $dst_a * (127 - $src_a) / 127) / 127;
$dst_g = ($srccolor['green'] * $src_a + $dstcolor['green'] * $dst_a * (127 - $src_a) / 127) / 127;
$dst_b = ($srccolor['blue'] * $src_a + $dstcolor['blue'] * $dst_a * (127 - $src_a) / 127) / 127;
$dst_a = 127 - ($src_a + $dst_a * (127 - $src_a) / 127);
$color = imagecolorallocatealpha($dst_im, $dst_r, $dst_g, $dst_b, $dst_a);
// paint
if (!imagesetpixel($dst_im, $dst_x + $x_offset, $dst_y + $y_offset, $color))
return
false;
imagecolordeallocate($dst_im, $color);
}
}
return
true;
}

// use it like this (identical to imagecopymerge)
function imagecopymerge_alpha($dst_im, $src_im, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $pct)
// or this
function imagecopymerge_alpha($dst_im, $src_im, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $pct, array('red' => 1, 'green' => 2, 'blue' => 3, 'alpha' =>4))
?>
santin1991[at]gmail[dot]com
15 年前
在影像上新增 logo 的腳本。
<?php
/**
* 將 logo 放置在 jpeg 圖像的右下角
* 使用 stefan 的腳本定位
**/
$logo_file = "logo.png";
$image_file = "img.jpg";
$targetfile = "img2.jpg";
$photo = imagecreatefromjpeg($image_file);
$fotoW = imagesx($photo);
$fotoH = imagesy($photo);
$logoImage = imagecreatefrompng($logo_file);
$logoW = imagesx($logoImage);
$logoH = imagesy($logoImage);
$photoFrame = imagecreatetruecolor($fotoW,$fotoH);
$dest_x = $fotoW - $logoW;
$dest_y = $fotoH - $logoH;
imagecopyresampled($photoFrame, $photo, 0, 0, 0, 0, $fotoW, $fotoH, $fotoW, $fotoH);
imagecopy($photoFrame, $logoImage, $dest_x, $dest_y, 0, 0, $logoW, $logoH);
imagejpeg($photoFrame, $targetfile);
echo
'<img src="'.$targetfile.'" />';
?>
bjorn AT smokingmedia DOT com
21 年前
補充 stefan 的貼文

我發現如果你對帶有 Alpha 通道的 png-24 檔案使用 imagecopymerge,它會失效,請改用 imagecopy。
imagecopymerge 似乎沒有正確處理 Alpha 通道(是個 bug 嗎?)。

這裡有一些範例程式碼,可以將圖像 (image.png) 放置在背景顏色或背景圖像上。

<?php

$im
= "image.png";
$bg = "ffddee"; // hex representation of the color (i.e. #ffffff for white)
$out = "png"; // or "jpg" for jpg file output
// $backgroundfile = ""; // optional backgroundfile if you don't want to use a color

//
// function to convert hex colorcode to decimal
//

function colordecode($hex){

$code[r] = hexdec(substr($hex, 0 ,2));
$code[g] = hexdec(substr($hex, 2 ,2));
$code[b] = hexdec(substr($hex, 4 ,2));

return
$code;

}
// end func colordecode

// create the resource id
$image_id = imageCreateFromPNG($im);

// get image size
$im_X = ImageSX($image_id);
$im_Y = ImageSY($image_id);

// create a truecolor background image of the right size
// or use a background image like this
// $backgroundimage = imageCreateFromPNG($backgroundfile);
$backgroundimage = imagecreatetruecolor($im_X, $im_Y);

// get the desired backgroundcolor:
// don't use this if you want to use a background image
$code = colordecode($bg);
$backgroundcolor = ImageColorAllocate($backgroundimage, $code[r], $code[g], $code[b]);
ImageFilledRectangle($backgroundimage, 0, 0, $im_X, $im_Y, $backgroundcolor);

// merge the two together with alphablending on!
ImageAlphaBlending($backgroundimage, true);
imagecopy($backgroundimage, $image_id, 0, 0, 0, 0, $im_X, $im_Y);

// output the image:
if($output == "jpg"){
Header( "Content-type: image/jpeg");
ImageJPEG($backgroundimage);
}
else{
Header( "Content-type: image/png");
ImagePNG($backgroundimage);
}

// destroy the memory
ImageDestroy($backgroundimage);
ImageDestroy($image_id);
?>
jylyn at hotmail dot com
18 年前
更正 nick at prient 提供的程式碼的一些錯誤

$iTemplate 應為 $iBackground
$iWorking 應為 $iSource

修正這兩個錯誤後,我發現這個腳本真的很有用,謝謝!
Ascent [at] WebAQ.com
19 年前
首先,您需要製作 0~9 的 gif 格式圖片和一張背景圖片。

<?php
/*
make random image number check
20050524 by ascent WebAQ.com
*/

$rands = rand(1000,9999);

session_start();
$_SESSION['random_image_number_check'] = $rands;

$bg = './random_image_bg.jpg';
$numimgp = './random_image_number_%d.gif';

$numimg1 = sprintf($numimgp,substr($rands,0,1));
$numimg2 = sprintf($numimgp,substr($rands,1,1));
$numimg3 = sprintf($numimgp,substr($rands,2,1));
$numimg4 = sprintf($numimgp,substr($rands,3,1));
$ys1 = rand(-4,4);
$ys2 = rand(-4,4);
$ys3 = rand(-4,4);
$ys4 = rand(-4,4);

$bgImg = imageCreateFromJPEG($bg);
$nmImg1 = imageCreateFromGIF($numimg1);
$nmImg2 = imageCreateFromGIF($numimg2);
$nmImg3 = imageCreateFromGIF($numimg3);
$nmImg4 = imageCreateFromGIF($numimg4);
imageCopyMerge($bgImg, $nmImg1, 10, $ys1, 0, 0, 20, 30, 50);
imageCopyMerge($bgImg, $nmImg2, 30, $ys2, 0, 0, 20, 30, 50);
imageCopyMerge($bgImg, $nmImg3, 50, $ys3, 0, 0, 20, 30, 50);
imageCopyMerge($bgImg, $nmImg4, 70, $ys4, 0, 0, 20, 30, 50);
header("Content-type: image/jpg");
ImageJPEG($bgImg,"",100);
imagedestroy($bgImg);
imagedestroy($nmImg1);
imagedestroy($nmImg2);
imagedestroy($nmImg3);
imagedestroy($nmImg4);
?>

玩得開心!
killing_wombles0000 at hotmail dot com
13 年前
任何想要創建圖像反射效果的人。這是一個簡單的過程,它逐行從圖像底部複製指定數量的像素。每一行會逐漸變得更加透明。並將 PNG 輸出到螢幕上。

這是硬編碼的程式 - 所有四個輸入變數(輸入圖像、反射高度、起始透明度、圖像和反射之間的間隙)都在這裡手動設置。

<?php
$in
= imagecreatefromjpeg('C:\test.jpg');
$reflection_strength = 120; // starting transparency (0-127, 0 being opaque)
$reflection_height = 40; // height of reflection in pixels
$gap = 10; // gap between image and reflection

$orig_height = imagesy($in); // store height of original image
$orig_width = imagesx($in); // store height of original image
$output_height = $orig_height + $reflection_height + $gap; // calculate height of output image

// create new image to use for output. fill with transparency. ALPHA BLENDING MUST BE FALSE
$out = imagecreatetruecolor($orig_width, $output_height);
imagealphablending($out, false);
$bg = imagecolortransparent($out, imagecolorallocatealpha($out, 255, 255, 255, 127));
imagefill($out, 0, 0, $bg);
imagefilledrectangle($out, 0, 0, imagesx($in), imagesy($in), $bg1);

// copy original image onto new one, leaving space underneath for reflection and 'gap'
imagecopyresampled ( $out , $in , 0, 0, 0, 0, imagesx($in), imagesy($in), imagesx($in), imagesy($in));

// create new single-line image to act as buffer while applying transparency
$reflection_section = imagecreatetruecolor(imagesx($in), 1);
imagealphablending($reflection_section, false);
$bg1 = imagecolortransparent($reflection_section, imagecolorallocatealpha($reflection_section, 255, 255, 255, 127));
imagefill($reflection_section, 0, 0, $bg1);

// 1. copy each line individually, starting at the 'bottom' of the image, working upwards.
// 2. set transparency to vary between reflection_strength and 127
// 3. copy line back to mirrored position in original
for ($y = 0; $y<$reflection_height;$y++)
{
$t = ((127-$reflection_strength) + ($reflection_strength*($y/$reflection_height)));
imagecopy($reflection_section, $out, 0, 0, 0, imagesy($in) - $y, imagesx($in), 1);
imagefilter($reflection_section, IMG_FILTER_COLORIZE, 0, 0, 0, $t);
imagecopyresized($out, $reflection_section, $a, imagesy($in) + $y + $gap, 0, 0, imagesx($in) - (2*$a), 1, imagesx($in), 1);
}

// output image to view
header('Content-type: image/png');
imagesavealpha($out,true);
imagepng($out);
?>
highton ridley
5 年前
killing_wombles0000 提供了一段幾乎可以運作的程式碼,可以用遞增的透明度來鏡像圖像。在 stackexchange 上 showdev 的幫助下,以下是修正後的完整程式碼。
<?php
$in
= imagecreatefromjpeg('https://picsum.photos/id/1084/536/354?grayscale');
$reflection_strength = 120; // starting transparency (0-127, 0 being opaque)
$reflection_height = 40; // height of reflection in pixels
$gap = 0; // gap between image and reflection

$orig_height = imagesy($in); // store height of original image
$orig_width = imagesx($in); // store height of original image
$output_height = $orig_height + $reflection_height + $gap; // calculate height of output image

// create new image to use for output. fill with BLACK.
$out = imagecreatetruecolor($orig_width, $output_height);
//imagealphablending($out, false);
//$bg = imagecolortransparent($out, imagecolorallocatealpha($out, 255, 255, 255, 127));
$bg = imagecolorallocatealpha($out, 0,0,0,0);
imagefill($out, 0, 0, $bg);
imagefilledrectangle($out, 0, 0, imagesx($in), imagesy($in), $bg);

// copy original image onto new one, leaving space underneath for reflection and 'gap'
imagecopyresampled ( $out , $in , 0, 0, 0, 0, imagesx($in), imagesy($in), imagesx($in), imagesy($in));

// create new single-line image to act as buffer while applying transparency
$reflection_section = imagecreatetruecolor(imagesx($in), 1);
imagealphablending($reflection_section, false);
$bg1 = imagecolortransparent($reflection_section, imagecolorallocatealpha($reflection_section, 255, 255, 255, 127));
imagefill($reflection_section, 0, 0, $bg1);

// 1. copy each line individually, starting at the 'bottom' of the image, working upwards.
// 2. set transparency to vary between reflection_strength and 127
// 3. copy line back to mirrored position in original
for ($y = 0; $y<$reflection_height;$y++)
{
$t = ((127-$reflection_strength) + ($reflection_strength*($y/$reflection_height)));
imagecopy($reflection_section, $out, 0, 0, 0, imagesy($in) - $y, imagesx($in), 1);
imagefilter($reflection_section, IMG_FILTER_COLORIZE, 0, 0, 0, $t);
imagecopyresized($out, $reflection_section, 0, imagesy($in) + $y + $gap, 0, 0, imagesx($in) - 0, 1, imagesx($in), 1);
}

// output image to view
header('Content-type: image/png');
imagesavealpha($out,true);
imagepng($out);
?>
jay at zylex dot net dot nz
17 年前

我寫了這個腳本來將浮水印圖像添加到較大圖像的右下角。我知道它很基本,但這是我目前需要的全部。這對新手來說也是一個容易理解的函式。它只需要兩個圖像類型作為參數。

例如:
$image = imagecreatefromjpeg("檔案位置");
$insert = imagecreatefrompng("浮水印檔案位置");
$image = image_overlap($image, $insert);

function image_overlap($background, $foreground){
$insertWidth = imagesx($foreground);
$insertHeight = imagesy($foreground);

$imageWidth = imagesx($background);
$imageHeight = imagesy($background);

$overlapX = $imageWidth-$insertWidth-5;
$overlapY = $imageHeight-$insertHeight-5;
imagecolortransparent($foreground,
imagecolorat($foreground,0,0)); imagecopymerge($background,$foreground,
$overlapX,$overlapY,0,0,$insertWidth,$insertHeight,100); return $background;
}

它沒有平滑兩個圖像之間的邊緣,但它很容易使用。
To Top