完美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图片添加水印类的更多相关文章

  1. Android--很实用的图片工具类

    import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileNotFoundException; imp ...

  2. .net为图片添加水印(转) jpg png和gif格式

    .net为图片添加水印(转) jpg png和gif格式 .net为图片添加水印(转) jpg png和gif格式,转自csdn的hyde82,现在跟大家一起来分享下: 利 用.net中System. ...

  3. 神奇的canvas——巧用 canvas 为图片添加水印

    代码地址如下:http://www.demodashi.com/demo/11637.html 很久之前写过一篇关于 canvas 的文章,是通过 canvas 来实现一个绚丽的动画效果,不管看过没看 ...

  4. PHP的图片处理类(缩放、加图片水印和剪裁)

    <!--test.php文件内容--> <?php //包含这个类image.class.php include "image.class.php"; $img ...

  5. 不错.net图片水印类

    using System; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Draw ...

  6. [Xcode 实际操作]九、实用进阶-(16)给图片添加水印效果

    目录:[Swift]Xcode实际操作 本文将演示如何截取屏幕画面,并将截取图片,存入系统相册. 在项目文件夹[DemoApp]上点击鼠标右键 ->[New File]创建一个扩展文件-> ...

  7. Python Windows 快捷键自动给剪贴板(复制)图片添加水印

    编写一个能在windows上使用的按下快捷键自动给剪贴板(复制)的图片添加水印的小工具.plyer.PIL.pyinstaller.pynput.win32clipboard库.记录自己踩过的坑,部分 ...

  8. Android 图片添加水印图片或者文字

    给图片添加水印的基本思路都是载入原图,添加文字或者载入水印图片,保存图片这三个部分 添加水印图片: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ...

  9. 分享一下怎么开发一款图片视频类App,秒拍和prisma

    第一步,分解短视频App的功能 我们在秒拍官网看到如此描述: [视频拍摄及导入]支持直接拍摄及导入手机本地的视频 [照片电影]照片专属特效,轻松创作照片电影 [MV特效]10余款全新MV特效,让普通视 ...

随机推荐

  1. Spring DeferredResult 异步请求

    Spring DeferredResult 异步请求 一.背景 二.分析 三.实现要求 四.后端代码实现 五.运行结果 1.超时操作 2.正常操作 六.DeferredResult运行原理 六.注意事 ...

  2. allegro查看线宽的方法

  3. Shooting Bricks题解

    题目传送门 以后我绝对不会一直磕着一道题磕几个小时了...感觉还是自己节奏出了问题,不知为啥感觉有点小慌... 算了,其实再回头仔细看一下这个题dp的思路还是比较好想出来的,打代码之前一定要做好足够的 ...

  4. java线程同步以及对象锁和类锁解析(多线程synchronized关键字)

    一.关于线程安全 1.是什么决定的线程安全问题? 线程安全问题基本是由全局变量及静态变量引起的. 若每个线程中对全局变量.静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的:若有多个线 ...

  5. Matlab画colormap的一种色彩搭配方法

    声学与振动数据分析经常需要画colormap,来识别是结构频率共振,还是激励源阶次问题,比如图1,横坐标表示电机的转速,负值表示CW(顺时针)方向转动,正值表示CCW逆时针方向转动.Y轴表示对应的声音 ...

  6. robot framework 导入资源

    创建资源后添加关键字 创建资源文件用于存放关键字,项目下的所有套件都可以引用. 1.创建资源 测试项目->new resource->输入资源名称->点击"确认" ...

  7. Swift-Framework(一)访问资源文件

    摘要 Framework 就是在 APP 应用中的一种封装功能的表现形式,虽然不能独立运行,但是也可以在它里面存放和访问图片.语音等资源文件,可算是麻雀虽小,五脏俱全. 毕竟不是 APP 工程,所以 ...

  8. MySQL之DDL数据定义语言:库、表的管理

    库的管理 常用命令 #创建库 create database if not exists 库名 [ character set 字符集名]; create database if not exists ...

  9. [python]Robotframework+Git+jenkins实现持续集成并生成测试报告发送邮件

    1.环境需求 &robotframework(不写搭建,自行百度) & git(不写安装,自行百度) &jenkins 2.安装jenkins 官网下载最新版本https:// ...

  10. USB3.0 转USB3.0

    前段时间因为项目需求需要将相机的USB3.0口转接出来,心想那还不想简单,结果第一次就碰壁了:先说一下usb3.0的引脚定义如图: 九个脚,2个地:注意USB3.0转3.0时数据线全交叉,DM-和DP ...