/** * 用一张PNG图片给原始图片加水印,水印图片将自动调整到目标图片大小 * * @param string $png png图片的路径 * @param string $hp 水平位置 left|center|right * @param string $vp 垂直位置 top|center|bottom * @param int $pct 水印的透明度 0-100, 0为完全透明,100为完全不透明,只适用于非PNG图片水印 * @param string $path 如果指定则生成图片到$path * @param * @return */ function waterMark($markImg, $hp = 'center', $vp = 'center', $pct = 50, $path = null) { //原图信息 $srcw = $this->getWidth(); $srch = $this->getHeight(); //水印图信息 $mark = new self($markImg); $markw = $mark->getWidth(); $markh = $mark->getHeight(); //水印图片大于目标图片,调整大小 if ($markw > $srcw || $markh > $srch) { //先将水印图片调整到原始图片大小-10个像素 $mark->resize($srcw - 10, $srch - 10, true); $markw = $mark->getWidth(); $markh = $mark->getHeight(); } //判断水印位置 $arrx = array('left' => 0, 'center' => floor(($srcw - $markw) / 2), 'right' => $srcw - $markw); $arry = array('top' => 0, 'center' => floor(($srch - $markh) / 2), 'bottom' => $srch - $markh); $x = isset($arrx[$hp]) ? $arrx[$hp] : $arrx['center']; $y = isset($arry[$vp]) ? $arry[$vp] : $arry['center']; //png图片水印 if ($mark->getType() == 3) { //打开混色模式 imagealphablending($this->img, true); imagecopy($this->img, $mark->getResource(), $x, $y, 0, 0, $markw, $markh); } else { imagecopymerge($this->img, $mark->getResource(), $x, $y, 0, 0, $markw, $markh, $pct); } unset($mark); if ($path) { return $this->save($path); } return $this; }
/** * Overlay an image on top of another, works with 24-bit PNG alpha-transparency * * @param string|Image $overlay An image filename or a Image object * @param string $position center|top|left|bottom|right|top left|top right|bottom left|bottom right * @param float|int $opacity Overlay opacity 0-1 or 0-100 * @param int $globOffsetX Horizontal offset in pixels * @param int $globOffsetY Vertical offset in pixels * * @return $this * @throws Exception */ public function overlay($overlay, $position = 'bottom right', $opacity = 0.4, $globOffsetX = 0, $globOffsetY = 0) { // Load overlay image if (!$overlay instanceof self) { $overlay = new self($overlay); } // Convert opacity $opacity = Helper::opacity($opacity); $globOffsetX = VarFilter::int($globOffsetX); $globOffsetY = VarFilter::int($globOffsetY); // Determine position list($xOffset, $yOffset) = Helper::getInnerCoords($position, array($this->_width, $this->_height), array($overlay->getWidth(), $overlay->getHeight()), array($globOffsetX, $globOffsetY)); // Perform the overlay Helper::imageCopyMergeAlpha($this->_image, $overlay->getImage(), array($xOffset, $yOffset), array(0, 0), array($overlay->getWidth(), $overlay->getHeight()), $opacity); return $this; }
/** * @see \wcf\system\image\adapter\IImageAdapter::overlayImage() */ public function overlayImage($file, $x, $y, $opacity) { $overlayImage = new self(); $overlayImage->loadFile($file); // fix PNG alpha channel handling // see http://php.net/manual/en/function.imagecopymerge.php#92787 $cut = imagecreatetruecolor($overlayImage->getWidth(), $overlayImage->getHeight()); imagecopy($cut, $this->image, 0, 0, $x, $y, $overlayImage->getWidth(), $overlayImage->getHeight()); imagecopy($cut, $overlayImage->image, 0, 0, 0, 0, $overlayImage->getWidth(), $overlayImage->getHeight()); imagecopymerge($this->image, $cut, $x, $y, 0, 0, $overlayImage->getWidth(), $overlayImage->getHeight(), $opacity * 100); }
/** * Resize the layer * * @param string $unit * @param float $pourcentWidth * @param float $pourcentHeight * @param boolean $converseProportion * @param integer $positionX * @param integer $positionY * @param string $position * * $position: http://phpimageworkshop.com/doc/22/corners-positions-schema-of-an-image.html * * $positionX, $positionY, $position can be ignored unless you choose a new width AND a new height AND to conserve proportion. */ public function resize($unit = "pixel", $newWidth = null, $newHeight = null, $converseProportion = false, $positionX = 0, $positionY = 0, $position = 'MM') { if ($newWidth || $newHeight) { if ($unit == 'pourcent') { if ($newWidth) { $newWidth = round($newWidth / 100 * $this->width); } if ($newHeight) { $newHeight = round($newHeight / 100 * $this->height); } } if ($converseProportion) { // Proportion are conserved if ($newWidth && $newHeight) { // Proportions + $newWidth + $newHeight if ($this->getWidth() > $this->getHeight()) { $this->resizeInPixel($newWidth, null, true); if ($this->getHeight() > $newHeight) { $this->resizeInPixel(null, $newHeight, true); } } else { $this->resizeInPixel(null, $newHeight, true); if ($this->getWidth() > $newWidth) { $this->resizeInPixel($newWidth, null, true); } } if ($this->getWidth() != $newWidth || $this->getHeight() != $newHeight) { $layerTmp = new self(array('width' => $newWidth, 'height' => $newHeight)); $layerTmp->addLayer(1, $this, round($positionX * ($newWidth / 100)), round($positionY * ($newHeight / 100)), $position); $this->width = $layerTmp->getWidth(); $this->height = $layerTmp->getHeight(); unset($this->image); unset($this->layerLevels); unset($this->layerPositions); unset($this->layers); $this->image = $layerTmp->getImage(); $this->layerLevels = $layerTmp->getLayerLevels(); $this->layerPositions = $layerTmp->getLayerPositions(); $this->layers = $layerTmp->getLayers(); unset($layerTmp); } return; } elseif ($newWidth) { $widthResizePourcent = $newWidth / ($this->width / 100); $newHeight = round($widthResizePourcent / 100 * $this->height); $heightResizePourcent = $widthResizePourcent; } elseif ($newHeight) { $heightResizePourcent = $newHeight / ($this->height / 100); $newWidth = round($heightResizePourcent / 100 * $this->width); $widthResizePourcent = $heightResizePourcent; } } elseif ($newWidth && !$newHeight || !$newWidth && $newHeight) { // New width OR new height is given if ($newWidth) { $widthResizePourcent = $newWidth / ($this->width / 100); $heightResizePourcent = 100; $newHeight = $this->height; } else { $heightResizePourcent = $newHeight / ($this->height / 100); $widthResizePourcent = 100; $newWidth = $this->width; } } else { // New width AND new height are given $widthResizePourcent = $newWidth / ($this->width / 100); $heightResizePourcent = $newHeight / ($this->height / 100); } // Update the layer positions in the stack foreach ($this->layerPositions as $layerId => $layerPosition) { $newPosX = round($widthResizePourcent / 100 * $layerPosition['x']); $newPosY = round($heightResizePourcent / 100 * $layerPosition['y']); $this->layerPositions[$layerId] = array("x" => $newPosX, "y" => $newPosY); } // Resize layers in the stack $layers = $this->layers; foreach ($layers as $key => $layer) { $layer->resizeInPourcent($widthResizePourcent, $heightResizePourcent); $this->layers[$key] = $layer; } // Resize the layer $this->resizeBackground($newWidth, $newHeight); } }