php图片水印处理

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

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

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

    1.图片大小

    2.图片放在哪个坐标上

    3.图片的宽高

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

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

    1.打开原图(也叫操作的目标图片)

    2.打开水印图(也叫水印来源图片)

    3.使用 imagecopymerge 将小图合并至大图的指定位置

    4.输出图片

    .5销毁资源

一、简单图片水印

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

99.png

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

document_2015-09-22_56010df4559d3.png

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

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

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

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

<?php
//打开目标图片
$dst = imagecreatefrompng('/upload/course/000/000/002/5833ebba648cf229.png');

//打开Logo来源图片
$src = imagecreatefrompng('/upload/course/000/000/002/5833ebe90cc11285.png');

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

//得到logo图片的宽高
$src_info = getimagesize('5833ebe90cc11285.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);

?>

我们看看最终的效果如下: 

11.png

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

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

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

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.png


注:
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('/upload/course/000/000/002/5833ebba648cf229.png','/upload/course/000/000/002/5833ebe90cc11285.png',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;
   }




?>

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

本文中所使用到的图像:

范冰冰女士的形象照片不可用于商业使用。所有权均为范冰冰女士及相关机构所有。

本文中所使用到的logo归百度公司所有。

特此声明!


继续学习
||
<?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; } ?>
提交重置代码
章节
笔记
提问
课件
反馈
捐赠

php入门教程之一周学会PHP

高并发千万级数据库系统解决方案
  • 推荐课程
  • 评论
  • 问答
  • 笔记
  • 课件下载

Jan

刚刚搞定 乱码原因是没有用上header('Content-Type: image/jpeg');让浏览器识别图像的类型

5年前    添加回复 0

Jan

getImageInfo()方法是自已封装的一个函数来的 不过整个流程下来图片没有显示 倒是一大队的乱码

5年前    添加回复 0

phpcn_bobo

Call to undefined function getImageInfo() 在手册里没有找到此方法

6年前    添加回复 0

为什么我的水印加不上去,图片输出不出来,只有一个 小框,前面的图片缩放和裁剪也是如此?

[最新 啊啊啊啊啊啊啊啊啊欧 的回答] 如果图片直接改后缀名,会导致这种情况,可通过PS修改后缀名,希望回答有所帮助。另外课程上的方法(亲测可用),不同在于getImageInfo函数。

时间:5年前

课件暂不提供下载,工作人员正在整理中,后期请多关注该课程~