前端地址替换
<!--原图片-->
<img src='/uploads/1.jpg'>
<!--压缩引用图片-->
<img src='/uploads/1.jpg!size=130X130'>
nginx 配置转发规则
# --------------------自动拆图----------↓-----------------------------
# 缩略图参数重定向 x.jpg!size=s 定位到 s_x.jpg
location ~ .*\.(gif|jpg|jpeg|png|bmp)!size=(.+)$
{
expires 30d; # 缓冲时间
rewrite ^(.+)/([a-zA-Z0-9]+\.(gif|jpg|jpeg|png|bmp))!size=(.+)$ $1/$4_$2;
}
# 动态调用图片裁图工具 s_x.jpg 不存在则裁图
location ~ .*(.+)/(.+)_([a-zA-Z0-9]+\.(gif|jpg|jpeg|png|bmp))$
{
try_files $uri /admin/Resources/ResizeImage/?url=$uri;
}
# --------------------自动拆图---------↑------------------------------
后端拆图保存代码
<?php
namespace app\admin\controller;
use think\Controller;
use think\facade\Env;
/**
* =============== 文件上传 于资源管理 =========
* 1.图片:上传、自定裁图
* 资源文件管理 上传/访问时自动裁图保存
* Class Resources
* @package app\admin\controller
*/
class Resources extends Controller {
/**
* 图片访问自动切图方法
* 第一步:原始访问:xxxxx.jpg!size=150x150
* 第二步:nginx 路由转写成150X150_xxxx.jpg
* 第三步:nginx 对规则路径重定向到 Resources/ResizeImage?url=150X150_xxxx.jpg
*/
public function ResizeImage($url){
// 正则匹配 .jpg
$pattern = "/(.+\/)(.+)_([a-zA-Z0-9]+\.(gif|jpg|jpeg|png|bmp))/";
preg_match($pattern,$url,$res);
if(count($res)>0){
$folder = $res[1];
$size = $res[2];
$filename= $res[3];
$filePath=$folder.$filename;
//查询文件是否存在
//裁剪不同尺寸
$width =0;
$height=0;
switch ($size){
case "150X150": $width =150;$height = 150;break;
case "300X300": $width =300;$height = 300;break;
case "750X750": $width =750;$height = 750;break;
case "750X469": $width =750;$height = 469;break;
case "640X320": $width =640;$height = 320;break;
default:$this->error("格式化参数错误");
}
$path = $this->CutImage($filePath,$width,$height,$size);
$fullpath = Env::get('root_path').'public/'.$path;
//返回数据
$mime = getimagesize($fullpath)["mime"];
$img = file_get_contents($fullpath,true);
return response($img,200,["Content-Length"=>strlen($img),])->contentType($mime);
}
else{
return json(["code"=>500,"msg"=>"格式化参数错误"]);
}
}
private function CutImage($filePath,$width,$height,$Prefix){
// 判断原始文件是否存在
$root=Env::get('root_path').'public';
if(!file_exists($root.$filePath)){
$this->error('原始文件不存在');
}
// 判断新文件是否存在
$FileName= substr(strrchr($filePath, '/'), 1);// 221212.jpg
$Folder =str_replace($FileName,'',$filePath);
$newFileName = $Prefix."_".$FileName;// s_22212.jpg
//新尺寸文件存在则直接返回相对路径
if(file_exists($root.$Folder.$newFileName)){
return $Folder.$newFileName;
}
//读取图片
$image = \think\Image::open($root.$filePath);
//保存裁剪后的图片
$image->thumb($width, $height,\think\Image::THUMB_CENTER)
->save($root.$Folder.$newFileName);
return $Folder.$newFileName;
}
}
Java
/**
* 根据参数裁图
* @return
*/
@GetMapping(value ="/resizeImage", produces = MediaType.IMAGE_JPEG_VALUE)
@Anonymous
public byte[] resizeImage(@RequestParam("url") String url) throws IOException {
String pattern = "(.+/)(.+)_([a-zA-Z0-9]+\\.(gif|jpg|jpeg|png|bmp))";
// 创建 Pattern 对象
Pattern r = Pattern.compile(pattern);
// 创建 matcher 对象
Matcher m = r.matcher(url);
if(m.find()){
String folder = m.group(1);
String size = m.group(2);
String filename= m.group(3);
String filePath=folder+filename;
//查询文件是否存在
//裁剪不同尺寸
Integer width =0,height=0;
switch (size){
case "150X150": width =150;height = 150;break;
case "300X300": width =300;height = 300;break;
case "480X640": width =480;height = 640;break;
case "640X480": width =640;height = 480;break;
case "750X469": width =750;height = 469;break;
case "750X750": width =750;height = 750;break;
case "640X320": width = 640;height = 320;break;
default:throw new FileNotFoundException("格式化SIZE参数错误");
}
//裁剪图片
String path = ImageUtils.cutImage(filePath,width,height,size);
//返回字节数据
return ImageUtils.readFile(path);
}
else{
throw new FileNotFoundException("格式化参数错误");
}
}
/**
* 剪切图片
* @param url
* @param width
* @param height
* @param Prefix 切图后前缀
*/
public static String cutImage(String url,int width, int height,String Prefix) throws IOException {
// 判断原始文件是否存在
// 本机地址
String localPath = RuoYiConfig.getProfile();
String downloadPath = StringUtils.substringAfter(url, Constants.RESOURCE_PREFIX);
Path rootLocation = Paths.get(localPath, downloadPath);
if(Files.notExists(rootLocation)){
throw new FileNotFoundException("原始文件不存在");
}
// 判断新文件是否存在
File srcFile = rootLocation.toFile();
// 文件名称 221212.jpg
String FileName = srcFile.getName();
// 拓展名 如:jpg
String fileSufix = FileName.substring(FileName.lastIndexOf(".") + 1);
// 拼接新地址 String newFileName = width+"X"+height+"_"+FileName;// 150x150_22212.jpg
String newFileName = Prefix+"_"+FileName;
File destFile = new File(srcFile.getParent(), newFileName);
// 新尺寸文件存在则直接返回
if(destFile.exists()){
return StringUtils.removeEnd(url,FileName)+newFileName;
}
BufferedImage image = ImageIO.read(srcFile);
int srcWidth = image.getWidth(null);
int srcHeight = image.getHeight(null);
int newWidth = 0, newHeight = 0;
int x = 0, y = 0;
double scaleW = (double) width / srcWidth;
double scaleH = (double) height / srcHeight;
// 按原比例缩放图片
if (scaleW < scaleH) {
newHeight = height;
newWidth = (int) (srcWidth * scaleH);
x = (newWidth - width) / 2;
} else {
newHeight = (int) (srcHeight * scaleW);
newWidth = width;
y = (newHeight - height) / 2;
}
BufferedImage newImage = new BufferedImage(newWidth, newHeight,BufferedImage.TYPE_INT_RGB);
newImage.getGraphics()
.drawImage(image.getScaledInstance(newWidth, newHeight, Image.SCALE_SMOOTH),0, 0, null);
// 保存裁剪后的图片
ImageIO.write(newImage.getSubimage(x, y, width, height), fileSufix,destFile);
return StringUtils.removeEnd(url,FileName)+newFileName;
}