Bootstrap

图片添加水印,仿照水印相机样式,定位时间备注等

需求:业务流程中,用户微信上传图片,展示的时候自动添加上水印(地址,时间,备注等信息)

  • 开发思路1、将每个元素添加分别单独到背景图片上,调整位置和透明度
  • 开发思路2、将水印信息先整合为一张水印图片,再将水印图片添加到背景图片,调整位置和透明度

因为考虑到不同图片尺寸大小等问题,元素内容又多,根据思路1,定位问题太麻烦,而且还因调整大小等因素,决定先整合为一张水印图片

1、参考水印相机,确认水印模板

本来水印图片打算全部用代码生成的,开发的过程中发现元素太多,背景色也上下分层,代码可以实现,但是ps更有性价比,于是打算先用ps画一个水印模板,然后在利用代码添加元素。

这个是参考模板,水印相机生成的照片(模仿他的样子开发,抄谁不会啊)
在这里插入图片描述

这个是ps做的水印模板图片,这些元素固定,开发时只需要再增加时间,地点和备注信息。
在这里插入图片描述

2、水印图片上添加时间、地点备注信息

添加文字水印,函数imagefttext需要用到字体,在电脑上C:\Windows\fonts里面黑体【simhei.ttf】,效果于水印图片上文字不一致,看了ps源文件,是Adobe 黑体 std字体,于是网上找了【AdobeHeitiStd-Regular.otf】(强迫症患者,要保持一致的嘛)。

$font_src = 'D:\php\wwwroot\127.0.0.1\device\font\AdobeHeitiStd-Regular.otf';
$image_logo_src = './image/logo.png';

$time = date('Y-m-d H:i:s');
$watermark_address = '上海市上海市上海上海馆';
$watermark_notes = '这是一个备注,这是一个备注,这是一个备注';

//创建水印图片
$image_logo = imagecreatefrompng($image_logo_src);
//获取水印尺寸
$image_logo_info = getimagesize($image_logo_src);
$image_logo_width = $image_logo_info[0];
$image_logo_height = $image_logo_info[1];

//设置字体颜色
$white = imagecolorallocate($image_logo, 255, 255, 255);
$blue = imagecolorallocate($image_logo, 100, 154, 222);

//根据位置往图片中写入文字
imagefttext( resource $image, float $size, float $angle,
              int $x, int $y, int $color, string $fontfile,
              string $text, array $extrainfo);
imagefttext($image_logo, 30, 0, 240, 155, $white, $font_src, $time);
imagefttext($image_logo, 38, 0, 200, 278, $blue, $font_src, $watermark_address);
imagefttext($image_logo, 20, 0, 150, 340, $blue, $font_src, $watermark_notes);

生成的水印照片,时间,地点和备注在添加的时候,用imagefttext来设置位置参数。

  • $image:它指定要处理的图像。
  • $size:它指定要使用的字体大小(以磅为单位)。
  • $angle:它以度为单位指定角度。
  • $x:它指定x坐标。
  • $y:它指定y坐标。
  • $color:它指定文本所需颜色的索引。
  • $fontfile:它指定要使用的字体。
  • $text:它指定要写入的文本。
  • $extrainfo (Optional):它指定了额外的信息。
    在这里插入图片描述

3、创建背景图片

imagecreatefrom 系列函数用于从文件或 URL 载入一幅图像,成功返回图像资源,失败则返回一个空字符串。
如果imagecreatefrom后边跟照片类型,如果是jpg更换为jpeg

  • imagecreatefromgif():创建一块画布,并从 GIF 文件或 URL 地址载入一副图像
  • imagecreatefromjpeg():创建一块画布,并从 JPEG 文件或 URL 地址载入一副图像
  • imagecreatefrompng():创建一块画布,并从 PNG 文件或 URL 地址载入一副图像
  • imagecreatefromwbmp():创建一块画布,并从WBMP 文件或 URL 地址载入一副图像
  • imagecreatefromstring():创建一块画布,并从字符串中的图像流新建一副图像
$image_bg_src = './image/1.jpg';

$image_bg_info = getimagesize($image_bg_src);
$image_type = explode('/', $image_bg_info['mime'])[1];
$image_type = $image_type == 'jpg' ? 'jpeg' : $image_type;
$image_bg_width = $image_bg_info[0];
$image_bg_height = $image_bg_info[1];

$image_fun_info = "imagecreatefrom" . $image_type;
$image_canvas = $image_fun_info($image_bg_src);

4、水印调整格式

计算水印图片的宽高,理想情况下无论背景图片 大小、宽高 如果改变,水印只占据图片的左下角

  • 如果背景图片 宽>高,水印图片 宽 为背景图片的 0.5(自己看效果定),按照比例求出水印图片的高(新宽 / 旧宽 * 旧高)
  • 如果背景图片 高>宽,水印图片 高 为背景图片的 0.3(自己看效果定),按照比例求出水印图片的宽(新高 / 旧高 * 旧宽)

根据图片重新调整水印的大小

  • imagecopy() 拷贝图像资源的一部分
  • imagecopyresampled() 重采样拷贝部分图像并调整大小
  • imagecopyresized 拷贝部分图像并调整大小
imagecopyresampled ( resource $dst_image , resource $src_image , int $dst_x , int $dst_y , int $src_x , int $src_y , int $dst_w , int $dst_h , int $src_w , int $src_h )
  • dst_image 目标图象连接资源。
  • src_image 源图象连接资源。
  • dst_x 目标 X 坐标点。
  • dst_y 目标 Y 坐标点。
  • src_x 源的 X 坐标点。
  • src_y 源的 Y 坐标点。
  • dst_w 目标宽度。
  • dst_h 目标高度。
  • src_w 源图象的宽度。
  • src_h 源图象的高度。
//计算比例
if ($image_bg_width > $image_bg_height) {
    $image_logo_height_new = round($image_bg_height * 0.3);
    $image_logo_width_new = round($image_logo_height_new / $image_logo_height * $image_logo_width);
    $offset = $image_bg_height * 0.03;
} else {
    $image_logo_width_new = round($image_bg_width * 0.5);
    $image_logo_height_new = round($image_logo_width_new / $image_logo_width * $image_logo_height);
    $offset = $image_bg_width * 0.03;
}
$image_logo_new = imagecreatetruecolor($image_logo_width_new, $image_logo_height_new);
imagecopyresampled($image_logo_new, $image_logo, 0, 0, 0, 0, $image_logo_width_new, $image_logo_height_new, $image_logo_width, $image_logo_height);

5、将水印放在背景图上

imagecopymerge()函数是一个强大的PHP图像处理函数,可以用于将两个图像合并到一个单一的图像中,并在混合时应用透明度。imagecopymerge()函数是通过按指定比例在两个图像之间绘制一个透明的GIF来实现的。

  • 如果背景图片 宽>高,水印图片距离左下角 左边 和 底部 的距离为 背景图片 高 的 3%(根据实际效果可微调)
  • 如果背景图片 高>宽,水印图片距离左下角 底部 和 左边 的距离为 背景图片 宽 的 3%(根据实际效果可微调)
imagecopymerge($image_canvas, $image_logo_new, $offset, $image_bg_height - $offset - $image_logo_height_new, 0, 0, $image_logo_width_new, $image_logo_height_new, 75);
#imagecopymerge( resource dst_im, resource src_im, int dst_x, int dst_y, int src_x, int src_y, int src_w, int src_h, int pct )
  • dst_im 目标图像
  • src_im 被拷贝的源图像
  • dst_x 目标图像开始 x 坐标
  • dst_y 目标图像开始 y 坐标,x,y同为 0 则从左上角开始
  • src_x 拷贝图像开始 x 坐标
  • src_y 拷贝图像开始 y 坐标,x,y同为 0 则从左上角开始拷贝
  • src_w (从 src_x 开始)拷贝的宽度
  • src_h (从 src_y 开始)拷贝的高度
  • pct 图像合并程度,取值 0-100,当 pct=0 时,实际上什么也没做,反之完全合并.

6、全部代码和效果

  • 宽>高
    在这里插入图片描述

  • 高>宽
    在这里插入图片描述

$font_src = 'D:\php\wwwroot\127.0.0.1\device\font\AdobeHeitiStd-Regular.otf';
$time = date('Y-m-d H:i:s');
$image_logo_src = './image/logo.png';
$image_bg_src = './image/1.jpg';
$watermark_address = '上海市上海市上海上海馆';
$watermark_notes = '这是一个备注,这是一个备注,这是一个备注';

$image_bg_info = getimagesize($image_bg_src);
$image_type = explode('/', $image_bg_info['mime'])[1];
$image_type = $image_type == 'jpg' ? 'jpeg' : $image_type;
$image_bg_width = $image_bg_info[0];
$image_bg_height = $image_bg_info[1];

$image_fun_info = "imagecreatefrom" . $image_type;
$image_canvas = $image_fun_info($image_bg_src);

//创建一个图片
$image_logo = imagecreatefrompng($image_logo_src);

//创建logo
$image_logo_info = getimagesize($image_logo_src);
$image_logo_width = $image_logo_info[0];
$image_logo_height = $image_logo_info[1];

//设置字体颜色
$white = imagecolorallocate($image_logo, 255, 255, 255);
$blue = imagecolorallocate($image_logo, 100, 154, 222);

//往图片中写入文字
imagefttext($image_logo, 30, 0, 240, 155, $white, $font_src, $time);
imagefttext($image_logo, 38, 0, 200, 278, $blue, $font_src, $watermark_address);
imagefttext($image_logo, 20, 0, 150, 340, $blue, $font_src, $watermark_notes);

//计算比例
if ($image_bg_width > $image_bg_height) {
    $image_logo_height_new = round($image_bg_height * 0.3);
    $image_logo_width_new = round($image_logo_height_new / $image_logo_height * $image_logo_width);
    $offset = $image_bg_height * 0.03;
} else {
    $image_logo_width_new = round($image_bg_width * 0.5);
    $image_logo_height_new = round($image_logo_width_new / $image_logo_width * $image_logo_height);
    $offset = $image_bg_width * 0.03;
}
//改变水印的尺寸
$image_logo_new = imagecreatetruecolor($image_logo_width_new, $image_logo_height_new);
imagecopyresampled($image_logo_new, $image_logo, 0, 0, 0, 0, $image_logo_width_new, $image_logo_height_new, $image_logo_width, $image_logo_height);

//将水印放到图片的合适位置
imagecopymerge($image_canvas, $image_logo_new, $offset, $image_bg_height - $offset - $image_logo_height_new, 0, 0, $image_logo_width_new, $image_logo_height_new, 75);

header('Content-Type: image/' . $image_type);
$image_fun_out = "image" . $image_type;
$image_fun_out($image_canvas);

imagedestroy($image_canvas);
imagedestroy($image_logo);
imagedestroy($image_logo_new);
;