所以这是我的实现:
首先在 php 页面生成期间调用图像时:
$reqinfo['id'] = $data[id];
$reqinfo['maxsize'] = 320;
$reqinfo['timestamp'] = time();
$reqinfo['base'] = false;
$encoded = base64_encode(openssl_encrypt(serialize($reqinfo), 'AES-128-CBC', 'martine',0,'fgrgfvcfghtfdrfg'));
echo'<div class="imagecontainer"><img src="photo.php?info='.$encoded.'" /></div>';
这已经在 imagecontainer 类的 css 和 javascript 中实现了一些限制。我发送图像 ID(或名称)最大宽度或高度以及请求时间戳,所有这些都在发送到 photo.php 的请求字符串中加密,如果图像可以绕过所有内容并像普通图像一样被调用,则这些都是真实的。
照片.php
<?
//request info
$reqinfo = unserialize(openssl_decrypt(base64_decode($_GET[info]), 'AES-128-CBC', 'martine',0,'fgrgfvcfghtfdrfg'));
//image expired
if(time() - $reqinfo[timestamp] > 10){ exit(); }
//public image
if($reqinfo[base] == true){ readfile('img/'.$reqinfo[id].'.jpg'); exit(); }
//header cache
header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
header('Content-type: image/jpeg');
//check cache existance and send out
if(file_exists( 'img/'.$reqinfo[id].'_'.$reqinfo[maxsize].'.jpg')) { readfile('img/'.$reqinfo[id].'_'.$reqinfo[maxsize].'.jpg'); exit(); }
//source Image
$image_path = 'img/'.$reqinfo[id].'.jpg';
list($original_width, $original_height)= getimagesize($image_path);
$srcImage = imagecreatefromjpeg( $image_path );
$ratio = $original_height/$original_width;
//create destination image holder
$destination_width = $reqinfo['maxsize'];
if($destination_width < 1) $destination_width = 1;
if($destination_width > $original_width)$destination_width = $original_width;
$destination_height = round($destination_width*$ratio);
if ($destination_height > $reqinfo['maxsize'])
{
$destination_height = $reqinfo['maxsize'];
$destination_width = round($destination_height/$ratio);
}
$targetImage = imagecreatetruecolor( $destination_width, $destination_height );
imagealphablending($targetImage,true);
//resample copy logo
imagecopyresampled( $targetImage, $srcImage,
0, 0,
0, 0,
$destination_width, $destination_height,
$original_width, $original_height );
// watermark
$watermark = imagecreatefrompng('watermark.png');
imagesettile($targetImage, $watermark);
imagefilledrectangle($targetImage, 0, 0, $destination_width, $destination_height, IMG_COLOR_TILED);
//output
imagejpeg( $targetImage, 'img/'.$reqinfo[id].'_'.$reqinfo[maxsize].'.jpg' );
imagejpeg( $targetImage );
imagedestroy( $targetImage );
?>
'martine' 是一个简单的密码短语 img 显然是一个非公共路径
希望这或多或少清楚,基本上是这个(按顺序):
- 解密 $reqinfo 数组
- 检查 imagerequest 是否新鲜,如果用户复制 url 并加载到另一个框架中,则不会加载任何图像。
- 检查图像是否可以绕过调整大小和水印并发送到浏览器
- 检查是否存在缓存版本以加快进程
- 重新创建调整大小的版本
- 添加水印
- 保存服务器缓存版本
- 发出“一次性”图像
希望这可以帮助某人...