php 之添加图片水印,根据比例计算水印的新尺寸

以下是 `_imgWatermark` 函数的中文注释和解析。该函数用于在图像上添加水印:

function _imgWatermark($src_image, $water_image, $path_image = '', $position = 10, $pct = 30, $angle = 15)
{// 检查源图和水印图文件是否存在if (!is_file($src_image)) {$error = '源图不存在';return false;}if (!is_file($water_image)) {$error = '水印图不存在';return false;}// 获取图片信息$src_info = getimagesize($src_image);$water_info = getimagesize($water_image);// 定义允许的图片 MIME 类型$allow = array('image/jpeg' => 'jpeg','image/gif' => 'gif','image/jpg' => 'jpg','image/png' => 'png','image/pjpeg' => 'jpeg');// 检查图像类型是否被允许if (!array_key_exists($src_info['mime'], $allow)) {$error = "源图类型不支持添加水印";return false;}if (!array_key_exists($water_info['mime'], $allow)) {$error = "水印图类型不支持";return false;}// 根据 MIME 类型创建打开和保存图片的函数$src_open = 'imagecreatefrom' . $allow[$src_info['mime']];$water_open = 'imagecreatefrom' . $allow[$water_info['mime']];$src_save = 'image' . $allow[$src_info['mime']];// 打开图像资源$src = $src_open($src_image);$water = $water_open($water_image);// 根据比例计算水印的新尺寸$scale_factor = 0.15; // 水印的相对大小比例$new_water_width = $src_info[0] * $scale_factor;$new_water_height = ($water_info[1] / $water_info[0]) * $new_water_width;// 创建缩放后的水印图$resized_water = imagecreatetruecolor($new_water_width, $new_water_height);imagealphablending($resized_water, false);imagesavealpha($resized_water, true);imagecopyresampled($resized_water, $water, 0, 0, 0, 0, $new_water_width, $new_water_height, $water_info[0], $water_info[1]);// 释放原始水印资源,使用缩放后的水印imagedestroy($water);$water = $resized_water;$water_info[0] = $new_water_width;$water_info[1] = $new_water_height;if ($angle) {// 旋转水印图片$water = imagerotate($water, $angle, imageColorAllocateAlpha($water, 0, 0, 0, 127));// 获取旋转后的水印尺寸$sourceInfo[0] = imagesx($water);$sourceInfo[1] = imagesy($water);// 设置水印平铺的间距$ww = $src_info[0] * 0.1;  // 水平方向间距$hh = $src_info[1] * 0.1;  // 垂直方向间距}if ($position == 10) {$offset_x = $water_info[0] / 2;}// 计算水印在源图中的位置$start_x = $start_y = 0;switch ($position) {case 1:break;case 2:$start_x = floor(($src_info[0] - $water_info[0]) / 2);break;case 3:$start_x = $src_info[0] - $water_info[0];break;case 4:$start_y = floor(($src_info[1] - $water_info[1]) / 2);break;case 5:$start_x = floor(($src_info[0] - $water_info[0]) / 2);$start_y = floor(($src_info[1] - $water_info[1]) / 2);break;case 6:$start_x = $src_info[0] - $water_info[0];$start_y = floor(($src_info[1] - $water_info[1]) / 2);break;case 7:$start_y = $src_info[1] - $water_info[1];break;case 8:$start_x = floor(($src_info[0] - $water_info[0]) / 2);$start_y = $src_info[1] - $water_info[1];break;case 9:$start_x = $src_info[0] - $water_info[0];$start_y = $src_info[1] - $water_info[1];break;case 10:// 创建用于平铺的图像资源$fun = 'imagecreatefrom' . image_type_to_extension($src_info[2], false);$thumb = $fun($src_image);// 定义总长度$start_x = $src_info[0] - 0;$start_y = $src_info[1] - 0;$index = 0;$ccasd = 0;$ccasdy = 0;// 循环平铺水印for ($x = 0; $x < $start_x; $x) {for ($y = 0; $y < $start_y; $y) {if ($x == 0 && $y == 0) {$x = round($ww / 2);}$index++;imagecopy($src, $thumb, 0, 0, $x + $ccasd - $offset_x, $y + $ccasdy, $sourceInfo[0], $sourceInfo[1]);imagecopy($src, $water, 0, 0, 0, 0, $sourceInfo[0], $sourceInfo[1]);imagecopymerge($thumb, $src, $x + $ccasd - $offset_x, $y + $ccasdy, 0, 0, $sourceInfo[0], $sourceInfo[1], $pct);$y += $sourceInfo[1] + $hh;}$x += $sourceInfo[0] + $ww;$index = 0;}$src_save($thumb, $path_image);imagedestroy($src);imagedestroy($water);return $imagename;break;}// 合并水印到源图if (imagecopymerge($src, $water, $start_x, $start_y, 0, 0, $water_info[0], $water_info[1], $pct) && $position != 10) {$src_save($src, $path_image);imagedestroy($src);imagedestroy($water);return $imagename;} else {$error = "水印制作失败";return false;}
}

### 关键点:

- **文件存在性检查:** 确保源图和水印图文件存在。
- **支持的图像类型:** 验证图像是否属于支持的类型(JPEG、GIF、PNG)。
- **图像缩放:** 根据比例缩放水印图,使其相对于源图的尺寸更小。
- **水印位置:** 水印可以根据 `position` 参数被放置在源图的不同位置。
- **水印平铺:** 如果 `position` 设置为 10,水印将在整个图像上平铺。
- **透明度和旋转:** 水印可以通过 `angle` 和 `pct` 参数进行旋转和调整透明度。
- **资源管理:** 函数确保所有图像资源在使用后被销毁以释放内存。

该函数为图像添加水印提供了灵活的方式,允许用户自定义水印的位置、透明度和平铺方式。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/60456.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

表格理解专题(五)表头和数据项定义

在 Excel 中&#xff0c;表头和数据项的区分主要取决于数据的组织结构。简单来说&#xff0c;表头 是用来描述数据含义的标签&#xff0c;而 数据项 是表格中存储的实际值。下面我会列举不同情况下&#xff0c;什么是表头&#xff0c;什么是数据项。 1. 表头的定义 表头通常是…

Day09 C++ 存储类

2024.11.12 C 存储类 一、C 存储类 存储类定义 C 程序中变量/函数的范围&#xff08;可见性&#xff09;和生命周期。这些说明符放置在它们所修饰的类型之前。下面列出 C 程序中可用的存储类&#xff1a; auto&#xff1a;这是默认的存储类说明符&#xff0c;通常可以省略不…

FS8x 功能安全

fail-safe是电独立的和物理隔离的。fail-safe由自己的参考电压和电流提供,有自己的振荡器,有重复的模拟路径以最小化常见的故障,并有LBIST/ABIST来覆盖潜在故障。fail-safe根据设备部件号提供ASIL B或ASIL D遵从性。除非另有规定,fail-safe定时来自故障安全振荡器,其精度为…

项目模块十七:HttpServer模块

一、项目模块设计思路 目的&#xff1a;实现HTTP服务器搭建 思想&#xff1a;设计请求路由表&#xff0c;记录请求方法与对应业务的处理函数映射关系。用户实现请求方法和处理函数添加到路由表&#xff0c;服务器只接受请求并调用用户的处理函数即可。 处理流程&#xff1a; …

内网域环境、工作组、局域网等探针方案

1. 信息收集 1.1 网络收集 了解当前服务器的计算机基本信息&#xff0c;为后续判断服务器角色&#xff0c;网络环境做准备 systeminfo 详细信息 net start 启动服务 tasklist 进程列表 schtasks 计划任务&#xff08;受权限影响&#xff09; 了解当前服务器的网络接口信息…

什么是量化交易

课程大纲 内容初级初识量化&#xff0c;理解量化 初识量化 传统量化和AI量化的区别 量化思想挖掘 量化思想的挖掘及积累技巧 量化代码基础&#xff1a; python、pandas、SQL基础语法 金融数据分析 常用金融分析方式 常用因子分析方式 数据分析实战练习 回测及交易引擎 交易引擎…

OpenHarmony-1.启动流程

OpenHarmony启动流程 1.kernel的启动 流程图如下所示&#xff1a;   OpenHarmony(简称OH)的标准系统的底层系统是linux&#xff0c;所以调用如下代码&#xff1a; linux-5.10/init/main.c: noinline void __ref rest_init(void) {struct task_struct *tsk;int pid;rcu_sch…

简单理解回调函数

回调函数是编程中一个非常重要的概念&#xff0c;它是一种以函数作为参数并在某个事件或条件满足时被调用的函数。这种机制使得程序能够以非线性的方式执行&#xff0c;增加了代码的灵活性和模块化。下面我将详细解释回调函数的几个关键点&#xff1a; 定义和作用 回调函数是一…

C++:线程(thread)的创建、调用及销毁

在 C 中&#xff0c;线程的管理主要依赖于标准库 std::thread&#xff0c;自 C11 起&#xff0c;这一功能被标准化&#xff0c;使得我们能够更加方便地创建、管理和销毁线程。这里我们详细讲解线程的创建、调用和销毁流程。 1. 线程的创建 创建线程通常是为了在单独的线程中执…

【LeetCode】【算法】64. 最小路径和

LeetCode 64. 最小路径和 题目描述 给定一个包含非负整数的 m x n 网格 grid &#xff0c;请找出一条从左上角到右下角的路径&#xff0c;使得路径上的数字总和为最小。 说明&#xff1a;每次只能向下或者向右移动一步。 思路 思路&#xff1a;这种题太典了&#xff0c;典…

什么时候需要复写hashcode()和compartTo方法

在Java编程中&#xff0c;复写&#xff08;重写&#xff09;hashCode()和compareTo()方法的需求通常与对象的比较逻辑和哈希集合的使用紧密相关。但请注意&#xff0c;您提到的compartTo可能是一个拼写错误&#xff0c;正确的方法名是compareTo()。以下是关于何时需要复写这两个…

1.7 JS性能优化

从输入url到页面加载完成都做了些什么 输入 URL - 资源定位符 http://www.zhaowa.com - http 协议 追问&#xff1a;http 与 TCP 1. http - 应用层 < > TCP - 传输层 2. 关联 - http基于TCP实现连接 < > UDP > 握手 & 挥手 &#xff08;传输速率上较…

批量修改文本的神器“多光标”(Multi-cursor)

“多光标”是许多文本编辑器和IDE&#xff08;如Visual Studio Code、Sublime Text或PyCharm&#xff09;中的一个功能&#xff0c;允许你在文本的不同位置放置多个光标并同时编辑它们。这在处理重复性任务时非常有用&#xff0c;比如重命名变量、同时编辑多行文本或在多个位置…

Spring Task详细讲解

✨Spring Task简介 Spring Task 是 Spring 提供的轻量级定时任务工具&#xff0c;也就意味着不需要再添加第三方依赖了&#xff0c;相比其他第三方类库更加方便易用。可以按照约定的时间自动执行某个代码逻辑。 使用场景&#xff1a; 信用卡每月还款提醒银行贷款每月还款提醒…

FreeRTOS源码(二) 任务调度

FreeRTOS源码(二) 任务调度 任务创建 1、任务结构体 typedef struct tskTaskControlBlock {volatile StackType_t *pxTopOfStack; /* Points to the location of the last item placed on the tasks stack. */ListItem_t xStateListItem; /* The list that holds…

Qt/C++ 海康SDK开发示例Demo

*** 工业相机在机器视觉中起到关键作用&#xff0c;本文基于海康 SDK 详细解读了设备连接与控制的各个步骤。内容涵盖设备枚举、句柄创建、图像采集回调以及设备异常处理&#xff0c;帮助开发者快速理解如何通过代码控制相机&#xff0c;实时采集并处理图像数据。*** 1. 搜索并…

ubuntu ros 解决建完图后 保存的地图非常小的问题

解决建完图后 保存的地图非常小的问题 在ROS中使用Gmapping等SLAM算法建图后&#xff0c;如果保存的地图非常小&#xff0c;通常是由于建图过程中的分辨率设置不当或地图边界没有覆盖到整个环境导致的。以下是详细的解决方案和具体步骤&#xff1a; 解决方案概述 调整地图分…

HDLBIts习题(5):移位寄存器

&#xff08;1&#xff09;易错习题1&#xff1a;109题&#xff08;shift18&#xff09; 对算数左移和算数右移概念不清&#xff0c;不知道该如何计算。 逻辑左移和算术左移之间没有区别。&#xff08;无论是有符号位数据还是无符号位数据&#xff0c;右侧补0&#xff09; 逻辑…

想要成为独立游戏作者 :通关!游戏设计之道 2-2 关卡设计

本文通过ai辅助总结加个人微调,不喜勿喷 前篇如下&#xff1a; 想要成为独立游戏作者 &#xff1a;通关&#xff01;游戏设计之道 2-1 HUD-CSDN博客 1.关卡的多重定义 在电子游戏行业里 “关卡” 有多种含义&#xff0c;如游戏行为发生的环境、分割的游戏体验单元、量…

【深圳大学】数据结构A+攻略(计软版)

1. 考试 1.1 形式 分为平时&#xff0c;笔试&#xff0c;机试三部分。其中&#xff1a; 平时占30%&#xff0c;包含平时OJ测验和课堂练习&#xff0c;注意这个可能会因老师的不同和课题组的新策略而改变。笔试占60%&#xff0c;是分值占比的主要部分。机试占10%。 1.2 题型…