返回介绍

10.5 图片水印处理

发布于 2025-01-30 22:11:35 字数 6910 浏览 0 评论 0 收藏 0

生成水印是整个技术里面最简单的一步。定位水印位置的时候涉及到一点点、最初浅的几何知识。

而上一章我们学习了图片的裁剪技术。水印只不过是图片裁剪技术的一点点的小变形的体现。

一点点几何上的重点知识:

  1. 图片大小
  2. 图片放在哪个坐标上
  3. 图片的宽高

图片水印技术的核心相当于是两张图片:一张大图;一张小图。将小图放置在大图的某个位置上。

水印技术是这个里面最为简单的一个技术,实现方式:

  1. 打开原图(也叫操作的目标图片)
  2. 打开水印图(也叫水印来源图片)
  3. 使用 imagecopymerge 将小图合并至大图的指定位置
  4. 输出图片
  5. 销毁资源

一、简单图片水印

需要加水印的目标图片(假设存储在我电脑的 d:/www/img/meinv.jpg),图片如下:
document/2015-09-22/5600d61ee6dfc

需要加上的 logo 图片(假设存储在我电脑的 d:/www/img/logo.png),图片如下:
document/2015-09-22/5600ed86f1a65

最主要的是要使用这个函数:

bool imagecopymerge ( resource $目标图片 , resource $来源图片, int $目标开始的 x , int $目标开始的 y, int $来源的 x , int $来源的 y , int $来源的宽 , int $来源的高 , int $透明度)

注意:
透明度的值为 0-100 的整数。imagecopy 和 imagecopymerge 的区别在于一个有透明度,一个没有透明度。

按照总结的步骤,做一个简单的方法:

<?php
//打开目标图片
$dst = imagecreatefrompng('d:/www/img/meinv.jpg');

//打开 Logo 来源图片
$src = imagecreatefrompng('d:/www/img/logo.png');

//得到目标图片的宽高
$dst_info = getimagesize('fbb.png');

//得到 logo 图片的宽高
$src_info = getimagesize('logo.png');

//放到最右下脚可得出图片水印图片需要开始的位置即:
//x 点位置:需要大图的宽 - 小图的宽;
//y 点位置:放大图的高 - 小图的高

$dst_x = $dst_info[0] - $src_info[0];

$dst_y = $dst_info[1] - $src_info[1];

//要将图片加在右下脚
imagecopymerge($dst, $src, $dst_x, $dst_y, 0, 0, $src_info[0], $src_info[1], 100);

header('Content-type:image/png');
imagepng($dst);

imagedestroy($dst);

imagedestroy($src);

?>

我们看看最终的效果如下:
document/2015-09-22/5600ee0269dbf

二、做一个智能的图片水印函数

一、 我们可以做一个自动化打开图片的函数

之前创建图片或者打开图片的函数我们都学习过:

  1. imagecreate
  2. imagecreatetruecolor
  3. imagecreatefromjpeg 等

我们来推理下下。我们如果能够想办法得到图片的 MIME 类型,根据 MIME 类型找到打开该文件的函数就行了。

因此,做这一步分为两块来完成:

  1. 得到文件 MIME 类型,返回类型。
  2. 传入路径,打开函数,返回资源。

因此,上面两块,我们都可以做成两个函数。

传入图片的路径,将图片的宽、高、图片的 MIME 类型全部返回一个数组,需要的时候使用对应的参数即可。

我们可以将 mime 类型传到到$data 当中的 type 关联数组中。代码如下:

function getImageInfo($path) {
$info = getimagesize($path);
$data['width'] = $info[0];
$data['height'] = $info[1];
$data['type'] = $info['mime'];
return $data;

}

打开文件的函数,传入一个图片的类型,传入一个图片的路径就打开了图片,返回成了资源类型。

下面的例子中,$type 使用 swithc...case 进行判断,如果是 imagejpeg 就使用 imagecreatefromjpeg 来打开$path 中路径指定的文件。最后,返回一个资源类型。

function openImg($path, $type) {
switch ($type) {
  case 'image/jpeg':
  case 'image/jpg':
  case 'image/pjpeg':
    $img = imagecreatefromjpeg($path);
    break;
  case 'image/png':
  case 'image/x-png':
    $img = imagecreatefrompng($path);
    break;
  case 'image/gif':
    $img = imagecreatefromgif($path);
    break;
  case 'image/wbmp':
    $img = imagecreatefromwbmp($path);
    break;
  default:
    exit('图片类型不支持');

}
return $img;
}

自动计算位置:

我们可将位置分为 10 个值,分别为 0-9。

我们用画图来表示位置:

document/2015-09-22/5600ef919671d

注:
0 为随机位置,可出现在页面中的任意处。但是不能超过图片的范围。

0 的位置为:

x = 0 至 (大图宽 - 小图宽)
y = 0 至  (大图高 - 小图高)

1 的位置为:

x = 0 
y = 0

2 的位置为:

x = (大图宽 - 小图宽) /2 
y = 0 

3 的位置为:

x = 大图宽 - 小图宽
y = 0

4 的位置为:

x = 0
y = (大图高 - 小图高) / 2

... ....依此类推。

我们来推理 0-9 的实现代码:

  switch($pos){
  case 1:
    $x=0;
    $y=0;
    break;
  case 2:
    $x=ceil(($info['width']-$logo['width'])/2);
    $y=0;
    break;
  case 3:
    $x=$info['width']-$logo['width'];
    $y=0;
    break;
  case 4:
    $x=0;
    $y=ceil(($info['height']-$logo['height'])/2);
    break;
  case 5:
    $x=ceil(($info['width']-$logo['width'])/2);
    $y=ceil(($info['height']-$logo['height'])/2);
    break;
  case 6:
    $x=$info['width']-$logo['width'];
    $y=ceil(($info['height']-$logo['height'])/2);
    break;

  case 7:
    $x=0;
    $y=$info['height']-$logo['height'];
    break;
  case 8:
    $x=ceil(($info['width']-$logo['width'])/2);
    $y=$info['height']-$logo['height'];
    break;
  case 9:
    $x=$info['width']-$logo['width'];
    $y=$info['height']-$logo['height'];
    break;
  case 0:
  default:
    $x=mt_rand(0,$info['width']-$logo['width']);
    $y=mt_rand(0,$y=$info['height']-$logo['height']);
    break;

}

最后调用一下图片的合并、输出和销毁代码即可:

imagecopymerge($dst,$src,$x,$y,0,0,$logo['width'],$logo['height'],$tm);

我们将最终的代码整合好后给大家实验看效果:

<?php

water('zxy.jpg','logo.gif',0,50);

function water($img,$water,$pos=9,$tm=100){

$info=getImageInfo($img);

$logo=getImageInfo($water);

$dst=openImg($img,$info['type']);
$src=openImg($water,$logo['type']);

switch($pos){
  case 1:
    $x=0;
    $y=0;
    break;
  case 2:
    $x=ceil(($info['width']-$logo['width'])/2);
    $y=0;
    break;
  case 3:
    $x=$info['width']-$logo['width'];
    $y=0;
    break;
  case 4:
    $x=0;
    $y=ceil(($info['height']-$logo['height'])/2);
    break;
  case 5:
    $x=ceil(($info['width']-$logo['width'])/2);
    $y=ceil(($info['height']-$logo['height'])/2);
    break;
  case 6:
    $x=$info['width']-$logo['width'];
    $y=ceil(($info['height']-$logo['height'])/2);
    break;

  case 7:
    $x=0;
    $y=$info['height']-$logo['height'];
    break;
  case 8:
    $x=ceil(($info['width']-$logo['width'])/2);
    $y=$info['height']-$logo['height'];
    break;
  case 9:
    $x=$info['width']-$logo['width'];
    $y=$info['height']-$logo['height'];
    break;
  case 0:
  default:
    $x=mt_rand(0,$info['width']-$logo['width']);
    $y=mt_rand(0,$y=$info['height']-$logo['height']);
    break;

}
imagecopymerge($dst,$src,$x,$y,0,0,$logo['width'],$logo['height'],$tm);

imagejpeg($dst);

imagedestory($dst);
imagedestory($src);

}

function openImg($path,$type){
  switch($type){
    case 'image/jpeg':
    case 'image/jpg':
    case 'image/pjpeg':
      $img=imagecreatefromjpeg($path);
      break;
    case 'image/png':
    case 'image/x-png':
      $img=imagecreatefrompng($path);
      break;
    case 'image/gif':
      $img=imagecreatefromgif($path);
      break;
    case 'image/wbmp':
      $img=imagecreatefromwbmp($path);
      break;
    default:
      exit('图片类型不支持');

  }
  return $img;
}

?>

本文仅为技术人员交流学习、交流技术使用。

本文中所使用到的图像:

  1. 范冰冰女士的形象照片不可用于商业使用。所有权均为范冰冰女士及相关机构所有。
  2. 本文中所使用到的 logo 归百度公司所有。

特此声明!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文