使用thinkphp开发app后端中,需要实现一个处理上传图片队列的功能

这是个上传多图片保存并且需要对其中一张图片进行压缩的功能

(使用的html5 mui框架开发app,如果直接载入原图,app客户端列表中图稍微多几张就会使得webview十分卡顿,建议在开发中,一定要对用户上传的图片进行服务器端的压缩)

之前已经写过一篇关入如何使用html5+的uploader上传多张图片到服务器的博客:

http://www.cnblogs.com/devilyouwei/p/6790255.html

并且实现了在前端进行压缩的功能(这是第一次压缩,有用户手机端进行)

上传到服务器后我们还需对图片进行处理,我这里使用的php作为后端语言,框架为thinkphp5

需要用到thinkphp的File类和Image类

File类:前者获取到用户上传的file(文件)并进行路径和文件名的操作

File类下的方法众多,主要有以下一些,使用之前应该先打印看一下,随意找一个文件测试一下效果,可以看的更加明白些:

$file = new File(ROOT_PATH."/public/uploads/20170506/abc.jpg");
$arr = [
'getATime' => $file->getATime(), //最后访问时间
'getBasename' => $file->getBasename(), //获取无路径的basename
'getCTime' => $file->getCTime(), //获取inode修改时间
'getExtension' => $file->getExtension(), //文件扩展名
'getFilename' => $file->getFilename(), //获取文件名
'getGroup' => $file->getGroup(), //获取文件组
'getInode' => $file->getInode(), //获取文件inode
'getLinkTarget' => $file->getLinkTarget(), //获取文件链接目标文件
'getMTime' => $file->getMTime(), //获取最后修改时间
'getOwner' => $file->getOwner(), //文件拥有者
'getPath' => $file->getPath(), //不带文件名的文件路径
'getPathInfo' => $file->getPathInfo(), //上级路径的SplFileInfo对象
'getPathname' => $file->getPathname(), //全路径
'getPerms' => $file->getPerms(), //文件权限
'getRealPath' => $file->getRealPath(), //文件绝对路径
'getSize' => $file->getSize(),//文件大小,单位字节
'getType' => $file->getType(),//文件类型 file dir link
'isDir' => $file->isDir(), //是否是目录
'isFile' => $file->isFile(), //是否是文件
'isLink' => $file->isLink(), //是否是快捷链接
'isExecutable' => $file->isExecutable(), //是否可执行
'isReadable' => $file->isReadable(), //是否可读
'isWritable' => $file->isWritable() //是否可写
]; print_r($arr);
return false;

print_r打印到浏览器后:

Array
(
[getATime] => 1494041766
[getBasename] => abc.jpg
[getCTime] => 1494041766
[getExtension] => jpg
[getFilename] => abc.jpg
[getGroup] => 0
[getInode] => 0
[getLinkTarget] => D:\wamp\www\dashen\public\uploads\20170506\abc.jpg
[getMTime] => 1494041766
[getOwner] => 0
[getPath] => D:\wamp\www\dashen\/public/uploads/20170506
[getPathInfo] => SplFileInfo Object
(
[pathName:SplFileInfo:private] => D:\wamp\www\dashen\/public/uploads/20170506
[fileName:SplFileInfo:private] => 20170506
) [getPathname] => D:\wamp\www\dashen\/public/uploads/20170506/abc.jpg
[getPerms] => 33206
[getRealPath] => D:\wamp\www\dashen\public\uploads\20170506\abc.jpg
[getSize] => 571800
[getType] => file
[isDir] =>
[isFile] => 1
[isLink] =>
[isExecutable] =>
[isReadable] => 1
[isWritable] => 1
)

关于如何用thinkphp5处理上传的多张图片文件,专门写一个private方法来处理,最后返回处理好的图片的路径的数组

图片处理包括:

  1. 将用户上传的图片保存到public/uploads/目录下
  2. 按照日期建立目录,md5的编码时间作为文件名
  3. 压缩其中第一张图片为缩略图,专门用于预览(也要保存到数据库)
  4. 返回所有处理过图片的路径数组,由调用者处理后保存数据库

代码:


// 用户提交疑难
public function addQues() {
// 验证登陆session
if (!session("?user_info"))
return ['info'=>'登录状态失效', 'login'=>0]; $ajax['title_id'] = input('post.title_id/d');
$ajax['content'] = input('post.content/s');
$ajax['star'] = input("post.star/s");
$ajax['reward'] = input('post.reward/s');
$ajax['message'] = input('post.message/s');
$ajax['price'] = input('post.price/f'); if($ajax['reward']!="金钱悬赏")
$ajax['price'] = 0; if ($ajax['title_id'] == null || $ajax['content'] == null || $ajax['star'] == null || $ajax['reward'] == null)
return ['info'=>'标题,内容,难度,悬赏方式不能为空', 'status'=>0]; if ($ajax['title_id'] == 0 || $ajax['content'] == "" || $ajax['star'] == "" || $ajax['reward'] == "")
return ['info'=>'标题,内容,难度,悬赏方式不能为空', 'status'=>0]; // 上传图片
$ajax['uid'] = session("user_info")['id'];
$ajax['create_time'] = time();
$ajax['update_time'] = $ajax['create_time'];
$ajax['ip'] = get_client_ip();
if (request()->file() != null) {
$imgs = $this->upload(); //根据imgs是否为数组鉴定是否有上传错误和超范围
if(!is_array($imgs))
return['status'=>0,'info'=>$imgs]; $ajax = array_merge($ajax, $imgs);
}
$ajax['is_del'] = 0;
$ajax['is_effect'] = 1;
$ajax['state'] = 0;
$f = db("Ques")->insert($ajax);
if ($f >= 1)
return ['status'=>1, 'info'=>'需求单提交成功'];
else
return ['status'=>0, 'info'=>'数据插入失败'];
}

此方法中,压缩第一张图时需要用到原图的文件路径,名称等,我保存在原图同一目录下,在原图前面加上“thumb_”前缀作为区别。

调用upload方法的控制器方法(外部方法):


// 文件上传转储(多文件)
// 暂且按照UNIX路径存储
private function upload() {
//创建的目录名称,日期(相对项目目录。用于数据库保存)
$dirName = "public".DS."uploads".DS.(date('Ymd'));
//创建保存目录(绝对路径。用于保存文件)
$saveDir = ROOT_PATH.DS.$dirName; if (!file_exists($saveDir)){
mkdir($saveDir);
} $files = request()->file();//取得上传文件名 foreach ( $files as $key => $file ) {
// 自动生成文件名
$info = $file->rule("get_rand")->validate(['ext'=>UPLOAD_EXT,'size'=>UPLOAD_SIZE])->move($saveDir,true,false); if ($info) {
//保存到数据的值
$data[$key] = $dirName .DS. $info->getFileName();
} else {
return $file->getError();
} // 压缩第一张图
if ($key == 'img0') {
$image = Image::open($info->getRealPath());
// 保存
$thumbName = $saveDir.DS.$info->getFilename(); // 绝对路径加上文件名
$save = $saveDir.DS."thumb_" . $info->getFilename();
$image->thumb(300, 200, Image::THUMB_CENTER)->save($save); $data['thumbnail'] = $dirName.DS.$thumbName;
}
}
return $data;
}
}

注意:thinkphp批量上传可能会出现同名文件覆盖的问题,因此我们重新规定了rule()方法使用的函数,在common.php写下一个随机生成函数,加上时间戳,这样重复的可能性就几乎为0了,极不易出现重名覆盖问题

同名覆盖问题可能来源于上传文件并发的转储,时间太短了,因为php是秒级别的UNIX时间戳,导致了产生了相同的时间戳,从而用thinkphp官方的文档中的上传示例代码导致了重名覆盖问题

//随机生成器
function get_rand(){
$now = $_SERVER['REQUEST_TIME'];//当前系统时间,比time()多5秒
return rand().$now;
}

ThinkPHP5上传图片并压缩为缩略图的更多相关文章

  1. C#图片切割、图片压缩、缩略图生成

    C#图片切割.图片压缩.缩略图生成的实现代码 /// 图片切割函数  /// </summary>  /// <param name="sourceFile"&g ...

  2. java 上传图片 并压缩图片大小

    Thumbnailator 是一个优秀的图片处理的Google开源Java类库.处理效果远比Java API的好.从API提供现有的图像文件和图像对象的类中简化了处理过程,两三行代码就能够从现有图片生 ...

  3. SpringMVC上传图片并压缩及剪切demo

    /** * */ package com.up.controller; import java.awt.Image; import java.awt.image.BufferedImage; impo ...

  4. java 上传图片 并压缩图片大小(转)

    Thumbnailator 是一个优秀的图片处理的Google开源Java类库.处理效果远比Java API的好.从API提供现有的图像文件和图像对象的类中简化了处理过程,两三行代码就能够从现有图片生 ...

  5. js 上传图片、压缩、旋转

    亲测 <!doctype html> <html> <head> <meta charset="utf-8"> <title& ...

  6. MVC.Net:压缩/保存图片缩略图

    通常用户上传的图片需要压缩或者生成缩略图.用System.Web.Helpers.WebImage的Resize方法可以很方便的实现这一功能.示例代码如下: /// <summary> / ...

  7. java上传图片并压缩图片大小

    Thumbnailator 是一个优秀的图片处理的Google开源Java类库.处理效果远比Java API的好.从API提供现有的图像文件和图像对象的类中简化了处理过程,两三行代码就能够从现有图片生 ...

  8. java实现上传图片并压缩图片大小功能

    缩略图压缩文件jar包 <!-- 图片缩略图 --> <dependency> <groupId>net.coobird</groupId> <a ...

  9. 上传图片并生成相关缩略图-PHP

    if(!empty($_FILES["fileField"]["name"])){//检测表单传递文件数据 $fileinfo = $_FILES[" ...

随机推荐

  1. Java并发之底层实现原理学习笔记

    本篇博文将介绍java并发底层的实现原理,我们知道java实现的并发操作最后肯定是由我们的CPU完成的,中间经历了将java源码编译成.class文件,然后进行加载,然后虚拟机执行引擎进行执行,解释为 ...

  2. python科学计算_numpy_ufunc

    ufunc简介 ufunc指universal function,是一种能够对数组中的所有元素进行操作的函数,ufunc是针对数组进行操作的函数,对一个数组进行重复的运算时,使用ufunc比math库 ...

  3. HTTP状态码、请求方法、响应头信息

    HTTP状态码 当浏览者访问一个网页时,浏览者的浏览器会向网页所在服务器发出请求.当浏览器接收并显示网页前,此网页所在的服务器会返回一个包含HTTP状态码的信息头(server header)用以响应 ...

  4. Linux(Cent OS7.2)下启动停止memcached方法及ps命令使用讲解

    Linux下,以Cent OS7.2为例,安装memcached后的启动方法很简单,这里我们使用yum源安装. 首先查找yum源版本库的memchaced安装包, yum list | grep me ...

  5. AVFoundation 框架初探究(二)

    接着第一篇总结 系列第一篇地址:AVFoundation 框架初探究(一) 在第一篇的文章中,我们总结了主要有下面几个点的知识: 1.对AVFoundation框架整体的一个认识 2.AVSpeech ...

  6. JS实现EasyUI ,Datagrid,合并单元格功能

    为了实现datagrid的合并单元格效果,datagrid的数据加载方式肯定是要写在JS文件内部的. 一:在JS内部添加Datagrid数据加载方法如下: $("#id").dat ...

  7. mysql之数据操作

    一 介绍 MySQL数据操作: DML 在MySQL管理软件中,可以通过SQL语句中的DML语言来实现数据的操作,包括 使用INSERT实现数据的插入 UPDATE实现数据的更新 使用DELETE实现 ...

  8. ES6小点心之通用弹窗

    小点心,顾名思义,开箱即食,拿来即用. 前端业务逻辑主要分为[交互效果]和[数据展示]两方面.数据展示可使用 MVVM 框架来实现.前端的交互效果常用的也就那么几种,比如弹窗,楼层定位,倒计时,下拉刷 ...

  9. Visual Studio 中添加SQLite数据源

    相关下载:https://system.data.sqlite.org/index.html/doc/trunk/www/downloads.wiki 在Visual Studio中要支持访问SQLi ...

  10. css 负边距

    负边距 可以改变 他在文档流中的尺寸 当块级元素设置 margin: -10px;  这个快 的大小没变但是他的定位的位置向上串了,压住了上面的文字   而且在他后面的文字  会爬到他身上 而前面的文 ...