完美png图片添加水印类
完美png图片添加水印类
被添加水印图片和水印图片都可以是png,保证透明无色背景,可调节透明度
<?php
class Imgshuiyin{
/* 缩略图相关常量定义 */
const THUMB_SCALING = 1; //常量,标识缩略图等比例缩放类型
const THUMB_FILLED = 2; //常量,标识缩略图缩放后填充类型
const THUMB_CENTER = 3; //常量,标识缩略图居中裁剪类型
const THUMB_NORTHWEST = 4; //常量,标识缩略图左上角裁剪类型
const THUMB_SOUTHEAST = 5; //常量,标识缩略图右下角裁剪类型
const THUMB_FIXED = 6; //常量,标识缩略图固定尺寸缩放类型
/* 水印相关常量定义 */
const WATER_NORTHWEST = 1; //常量,标识左上角水印
const WATER_NORTH = 2; //常量,标识上居中水印
const WATER_NORTHEAST = 3; //常量,标识右上角水印
const WATER_WEST = 4; //常量,标识左居中水印
const WATER_CENTER = 5; //常量,标识居中水印
const WATER_EAST = 6; //常量,标识右居中水印
const WATER_SOUTHWEST = 7; //常量,标识左下角水印
const WATER_SOUTH = 8; //常量,标识下居中水印
const WATER_SOUTHEAST = 9; //常量,标识右下角水印
/* 翻转相关常量定义 */
const FLIP_X = 1; //X轴翻转
const FLIP_Y = 2; //Y轴翻转
/**
* 图像资源对象
*
* @var resource
*/
protected $im;
protected function __construct(\SplFileInfo $file)
{
//获取图像信息
$info = @getimagesize($file->getPathname());
//检测图像合法性
if (false === $info || (IMAGETYPE_GIF === $info[2] && empty($info['bits']))) {
//throw new ImageException('Illegal image file');
}
//设置图像信息
$this->info = [
'width' => $info[0],
'height' => $info[1],
'type' => image_type_to_extension($info[2], false),
'mime' => $info['mime'],
];
//打开图像
if ('gif' == $this->info['type']) {
//$this->gif = new Gif($file->getPathname());
//$this->im = @imagecreatefromstring($this->gif->image());
} else {
$fun = "imagecreatefrom{$this->info['type']}";
$this->im = @$fun($file->getPathname());
}
if (empty($this->im)) {
//throw new ImageException('Failed to create image resources!');
}
}
/**
* 打开一个图片文件
* @param \SplFileInfo|string $file
* @return Image
*/
public static function open($file)
{
if (is_string($file)) {
$file = new \SplFileInfo($file);
}
if (!$file->isFile()) {
//throw new ImageException('image file not exist');
}
return new self($file);
}
/**
* 添加水印
*
* @param string $source 水印图片路径
* @param int $locate 水印位置
* @param int $alpha 透明度
* @return $this
*/
public function water($source, $locate = 5, $alpha = 100)
{
if (!is_file($source)) {
// throw new ImageException('水印图像不存在');
}
//获取水印图像信息
$info = getimagesize($source);
if (false === $info || (IMAGETYPE_GIF === $info[2] && empty($info['bits']))) {
//throw new ImageException('非法水印文件');
}
//创建水印图像资源
$fun = 'imagecreatefrom' . image_type_to_extension($info[2], false);
$water = $fun($source);
//设定水印图像的混色模式
imagealphablending($water, true);
/* 设定水印位置 */
switch ($locate) {
/* 右下角水印 */
case self::WATER_SOUTHEAST:
$x = $this->info['width'] - $info[0];
$y = $this->info['height'] - $info[1];
break;
/* 左下角水印 */
case self::WATER_SOUTHWEST:
$x = 0;
$y = $this->info['height'] - $info[1];
break;
/* 左上角水印 */
case self::WATER_NORTHWEST:
$x = $y = 0;
break;
/* 右上角水印 */
case self::WATER_NORTHEAST:
$x = $this->info['width'] - $info[0];
$y = 0;
break;
/* 居中水印 */
case self::WATER_CENTER:
$x = ($this->info['width'] - $info[0]) / 2;
$y = ($this->info['height'] - $info[1]) / 2;
break;
/* 下居中水印 */
case self::WATER_SOUTH:
$x = ($this->info['width'] - $info[0]) / 2;
$y = $this->info['height'] - $info[1];
break;
/* 右居中水印 */
case self::WATER_EAST:
$x = $this->info['width'] - $info[0];
$y = ($this->info['height'] - $info[1]) / 2;
break;
/* 上居中水印 */
case self::WATER_NORTH:
$x = ($this->info['width'] - $info[0]) / 2;
$y = 0;
break;
/* 左居中水印 */
case self::WATER_WEST:
$x = 0;
$y = ($this->info['height'] - $info[1]) / 2;
break;
default:
/* 自定义水印坐标 */
if (is_array($locate)) {
list($x, $y) = $locate;
} else {
// throw new ImageException('不支持的水印位置类型');
}
}
do {
//添加水印
$src = imagecreatetruecolor($info[0], $info[1]);
// 调整默认颜色
$color = imagecolorallocate($src, 0, 0, 0);
//设置透明
imagecolortransparent($src,$color);
imagefill($src, 0, 0, $color);
imagecopy($src, $this->im, 0, 0, $x, $y, $info[0], $info[1]);
imagecopy($src, $water, 0, 0, 0, 0, $info[0], $info[1]);
imagecopymerge($this->im, $src, $x, $y, 0, 0, $info[0], $info[1], $alpha);
//销毁零时图片资源
imagedestroy($src);
} while (!empty($this->gif) && $this->gifNext());
//销毁水印资源
imagedestroy($water);
return $this;
} /**
* 保存图像
* @param string $pathname 图像保存路径名称
* @param null|string $type 图像类型
* @param int $quality 图像质量
* @param bool $interlace 是否对JPEG类型图像设置隔行扫描
* @return $this
*/
public function save($pathname, $type = null, $quality = 80, $interlace = true)
{
//自动获取图像类型
if (is_null($type)) {
$type = $this->info['type'];
} else {
$type = strtolower($type);
}
//保存图像
if ('jpeg' == $type || 'jpg' == $type) {
//JPEG图像设置隔行扫描
imageinterlace($this->im, $interlace);
imagejpeg($this->im, $pathname, $quality);
} elseif ('gif' == $type && !empty($this->gif)) {
$this->gif->save($pathname);
} elseif ('png' == $type) {
//设定保存完整的 alpha 通道信息
imagesavealpha($this->im, true);
//ImagePNG生成图像的质量范围从0到9的
imagepng($this->im, $pathname, min((int) ($quality / 10), 9));
} else {
$fun = 'image' . $type;
$fun($this->im, $pathname);
}
return $this;
}
}
完美png图片添加水印类的更多相关文章
- Android--很实用的图片工具类
import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileNotFoundException; imp ...
- .net为图片添加水印(转) jpg png和gif格式
.net为图片添加水印(转) jpg png和gif格式 .net为图片添加水印(转) jpg png和gif格式,转自csdn的hyde82,现在跟大家一起来分享下: 利 用.net中System. ...
- 神奇的canvas——巧用 canvas 为图片添加水印
代码地址如下:http://www.demodashi.com/demo/11637.html 很久之前写过一篇关于 canvas 的文章,是通过 canvas 来实现一个绚丽的动画效果,不管看过没看 ...
- PHP的图片处理类(缩放、加图片水印和剪裁)
<!--test.php文件内容--> <?php //包含这个类image.class.php include "image.class.php"; $img ...
- 不错.net图片水印类
using System; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Draw ...
- [Xcode 实际操作]九、实用进阶-(16)给图片添加水印效果
目录:[Swift]Xcode实际操作 本文将演示如何截取屏幕画面,并将截取图片,存入系统相册. 在项目文件夹[DemoApp]上点击鼠标右键 ->[New File]创建一个扩展文件-> ...
- Python Windows 快捷键自动给剪贴板(复制)图片添加水印
编写一个能在windows上使用的按下快捷键自动给剪贴板(复制)的图片添加水印的小工具.plyer.PIL.pyinstaller.pynput.win32clipboard库.记录自己踩过的坑,部分 ...
- Android 图片添加水印图片或者文字
给图片添加水印的基本思路都是载入原图,添加文字或者载入水印图片,保存图片这三个部分 添加水印图片: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ...
- 分享一下怎么开发一款图片视频类App,秒拍和prisma
第一步,分解短视频App的功能 我们在秒拍官网看到如此描述: [视频拍摄及导入]支持直接拍摄及导入手机本地的视频 [照片电影]照片专属特效,轻松创作照片电影 [MV特效]10余款全新MV特效,让普通视 ...
随机推荐
- 计算机中的contex理解
原文链接 https://www.xuebuyuan.com/2016635.html 1.其实简单的说就是跟当前主题有关的所有内容. 2.如说到程序的上下文,就是当前这段程序之上和之下的程序段.因 ...
- 用STM32内置的高速ADC实现简易示波器
做一个数字采样示波器一直是我长久以来的愿望,不过毕竟这个目标难度比较大,涉及的方面实在太多,模拟前端电路.高速ADC.单片机.CPLD/FPGA.通讯.上位机程序.数据处理等等,不是一下子就能成的,慢 ...
- 重学STM32---(九)之CAN通信(一)
目录 1.CAN 是什么 2.CAN 特点 3.错误状态的种类 4.总线拓扑 5.CAN 协议 1.CAN 是什么 CAN 是 Controller Area Network的缩写(以下称为 CA ...
- axios & fetch 异步请求
// 一.创建实例 const request = axios.create({ baseURL: "http://kg.zhaodashen.cn/v2", headers: { ...
- Linux 文本三剑客之 awk
Linux 系统中一切皆文件. 文件是个文本.可以读.可以写,如果是二进制文件,还能执行. 在使用Linux的时候,大都是要和各式各样文件打交道.熟悉文本的读取.编辑.筛选就是linux系统管理员的必 ...
- pip切换源
pip国内的一些镜像 阿里云http://mirrors.aliyun.com/pypi/simple/ 中国科技大学https://pypi.mirrors.ustc.edu.cn/simple/ ...
- Linux 用户&用户组
用户和用户组的概念 用户 ---> 使用操作系统的人 Linux系统是一个多用户多任务的分时操作系统,任何一个要使用系统资源的用户,都必须首先向系统管理员申请一个账号,然后以这个账号的身份进入系 ...
- dotnet 6 使用 CreateSymbolicLink 创建文件夹符号链接
本文告诉大家如何使用 dotnet 6 提供的 Directory.CreateSymbolicLink 和 File.CreateSymbolicLink 方法创建文件夹和文件的符号链接 Direc ...
- go闭包使用
1.带参数闭包函数 func main() { //先调用闭包外面的方法传给变量 add_func := add(1, 2) //再调用里面的方法,因为有了i++ 同一个内存地址 在一次编译中i的值会 ...
- [jmeter]Jmeter+ant实现接口自动化
1.安装jmeter 和ant &环境变量配置百度去~ 2.jmeter和ant关联 &将JMeter所在目录下extras子目录里的ant-JMeter-1.1.1.jar复制到an ...