//图片转为base64,支持网络文件
function base64EncodeImage($image_file)
{
$image_info = getimagesize($image_file);
$handle = fopen($image_file, 'r');
$image_data = '';
while (!feof($handle)) {
$image_data .= fread($handle, 1024);
}
$base64_image = 'data:' . $image_info['mime'] . ';base64,' . chunk_split(base64_encode($image_data));
return $base64_image;
}
一个ftp类:
<?php
namespace app\common;
use yii;
/**
* FTP操作类
*/
class Ftp
{
public $off; // 返回操作状态(成功/失败)
public $conn_id; // FTP连接
public $error;
/**
* 方法:FTP连接
* @FTP_HOST -- FTP主机
* @FTP_PORT -- 端口
* @FTP_USER -- 用户名
* @FTP_PASS -- 密码
*/
public function __construct($FTP_HOST, $FTP_PORT, $FTP_USER, $FTP_PASS)
{
$this->conn_id = @ftp_connect($FTP_HOST, $FTP_PORT) or die("FTP服务器连接失败");
@ftp_login($this->conn_id, $FTP_USER, $FTP_PASS) or die("FTP服务器登陆失败");
@ftp_pasv($this->conn_id, 1); // 打开被动模拟
}
/**
* 方法:上传文件
* @path-- 本地路径
* @newpath -- 上传路径
* @type-- 若目标目录不存在则新建
*/
public function up_file($info = [], $type = true)
{
if ($info['error']) {
echo "文件上传失败!";
}
if ($type) {
$this->dir_mkdirs($info['filepath']);
}
$this->off = @ftp_put($this->conn_id, $info['filepath'], $info['filetmpname'], FTP_BINARY);
if (!$this->off) {
echo "文件上传失败,请检查权限及路径是否正确!";
}
}
/**
* 生成缩略图
* @param array $info
*/
public function make_thumb($info = [])
{
$img_arr = array('gif','jpg','png','jpeg','bmp');
if(in_array($info['extend'],$img_arr)){
$thumbInfo = [];
//生成缩略图
list($picwidth,$picheight) = getimagesize($info['filetmpname']);
$blval = round($picwidth/258,2);
$jsheight = round($picheight/$blval,2);
$imgthumb = $info['fileRand'] . '_thumb.' . $info['extend'];
$newthumb = $info['uploaddir'].$imgthumb;
// $info = pathinfo($newthumb);
$image = new Image($info['filetmpname']);
$image->resize(258, $jsheight);
$image->save(UPLOAD_FILE.'temp/'.$imgthumb);
$thumbInfo['filepath'] = $newthumb;
$thumbInfo['filetmpname'] = UPLOAD_FILE.'temp/'.$imgthumb;
//上传缩略图
$this->up_file($thumbInfo);
@unlink($thumbInfo['filetmpname']);//删除is系统中存放的缩略图
}
}
/**
* 方法:移动文件
* @path-- 原路径
* @newpath -- 新路径
* @type-- 若目标目录不存在则新建
*/
public function move_file($path, $newpath, $type = true)
{
if ($type) {
$this->dir_mkdirs($newpath);
}
$this->off = @ftp_rename($this->conn_id, $path, $newpath);
if (!$this->off) {
echo "文件移动失败,请检查权限及原路径是否正确!";
}
}
/**
* 方法:复制文件
* 说明:由于FTP无复制命令,本方法变通操作为:下载后再上传到新的路径
* @path-- 原路径
* @newpath -- 新路径
* @type-- 若目标目录不存在则新建
*/
public function copy_file($path, $newpath, $type = true)
{
$downpath = "c:/tmp.dat";
$this->off = @ftp_get($this->conn_id, $downpath, $path, FTP_BINARY); // 下载
if (!$this->off) {
echo "文件复制失败,请检查权限及原路径是否正确!";
}
$this->up_file($downpath, $newpath, $type);
}
/**
* 方法:删除文件
* @path -- 路径
*/
public function del_file($path)
{
$this->off = @ftp_delete($this->conn_id, $path);
if (!$this->off) {
echo "文件删除失败,请检查权限及路径是否正确!";
}
}
/**
* 方法:生成目录
* @path -- 路径
*/
public function dir_mkdirs($path)
{
$path_arr = explode('/', $path); // 取目录数组
$file_name = array_pop($path_arr); // 弹出文件名
$path_div = count($path_arr); // 取层数
foreach ($path_arr as $val) {// 创建目录
if (@ftp_chdir($this->conn_id, $val) == FALSE) {
$tmp = @ftp_mkdir($this->conn_id, $val);
if ($tmp == FALSE) {
echo "目录创建失败,请检查权限及路径是否正确!";
exit;
}
@ftp_chdir($this->conn_id, $val);
}
}
for ($i = 1; $i <= $path_div; $i++) { // 回退到根
@ftp_cdup($this->conn_id);
}
}
/**
* 方法:关闭FTP连接
*/
public function close()
{
@ftp_close($this->conn_id);
}
/**
* @param $uploadfile $_FILES
* @param $module 模块路径
* @param int $makeThumb 是否生成缩略图
* @param string $type 其他格式支持
* @param float|int $maxSize 大小限制
* @return array
*/
public function checkfile($uploadfile, $module, $makeThumb = 0, $type = '', $maxSize = 100 * 1024 * 1024)
{
$allow_arr = array('application/pdf', 'image/gif', 'image/jpg', 'image/pjpeg', 'image/png', 'image/jpeg', 'image/bmp', 'application/vnd.ms-excel', 'text/plain', 'application/msword', 'application/octet-stream', 'application/x-zip-compressed', 'text/plain', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/x-rar-compressed');
if ($type && false === strpos($type, 'exe')) { //如果有新类型,追加进去
array_push($allow_arr, $type);
}
$extend = pathinfo($uploadfile['name']);
$extend = strtolower($extend["extension"]); //文件后缀名
if (!empty($uploadfile['error'])) {
$this->uploadError($uploadfile['error']);
} else if ($uploadfile['size'] > $maxSize) {
$this->error("上传文件超出指定大小!");
} else if (empty($uploadfile['tmp_name']) || $uploadfile['tmp_name'] == 'none') {
$this->error("没有文件被上传..");
} else if (!in_array($uploadfile['type'], $allow_arr)) {
$this->error("上传文件格式有误,该格式文件不允许被上传");
} else {
$fileRand = md5($uploadfile['name'] . time() . rand(0, 99999));
$fileRealName = $fileRand . '.' . $extend;
$upload_dir = '/' . $module . '/' . date('Y/m/d') . '/';
$upload_filepath = '/' . $module . '/' . date('Y/m/d') . '/' . $fileRealName;
}
$info = [];
$info['error'] = $this->error;
$info['filename'] = $uploadfile['name'];
$info['filerealname'] = $fileRealName;
$info['filetmpname'] = $uploadfile['tmp_name'];
$info['filepath'] = $upload_filepath;
$info['fileRand'] = $fileRand;
$info['extend'] = $extend;
$info['uploaddir'] = $upload_dir;
$info['size'] = $uploadfile['size'];
$info['module'] = $module;
$this->up_file($info);
if ($makeThumb) {
$this->make_thumb($info);
$info['thumb_path'] = '/' . $module . '/' . date('Y/m/d') . '/' . $fileRand . '_thumb.' . $info['extend'];
}
return $info;
}
/**
* 多附件
* @param $uploadfile
* @param $module
* @param int $makeThumb
* @param string $type
* @param float|int $maxSize
* @return array
*/
public function checkfileMulti($uploadfile, $module, $makeThumb = 0, $type = '', $maxSize = 100 * 1024 * 1024)
{
$allow_arr = array('application/pdf', 'image/gif', 'image/jpg', 'image/pjpeg', 'image/png', 'image/jpeg', 'image/bmp', 'application/vnd.ms-excel', 'text/plain', 'application/msword', 'application/octet-stream', 'application/x-zip-compressed', 'text/plain', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/x-rar-compressed');
if ($type && false === strpos($type, 'exe')) { //如果有新类型,追加进去
array_push($allow_arr, $type);
}
foreach ($uploadfile as $key => $val) {
$extend = pathinfo($val['name']);
$extend = strtolower($extend["extension"]); //文件后缀名
if (!empty($val['error'])) {
$this->uploadError($val['error']);
} else if ($val['size'] > $maxSize) {
$this->error("上传文件超出指定大小!");
} else if (empty($val['tmp_name']) || $val['tmp_name'] == 'none') {
$this->error("没有文件被上传..");
} else if (!in_array($val['type'], $allow_arr)) {
$this->error("上传文件格式有误,该格式文件不允许被上传");
} else {
$fileRand = md5($val['name'] . time() . rand(0, 99999));
$fileRealName = $fileRand . '.' . $extend;
$upload_dir = '/' . $module . '/' . date('Y/m/d') . '/';
$upload_filepath = '/' . $module . '/' . date('Y/m/d') . '/' . $fileRealName;
}
$info = [];
$info['error'] = $this->error;
$info['filename'] = $val['name'];
$info['filerealname'] = $fileRealName;
$info['filetmpname'] = $val['tmp_name'];
$info['filepath'] = $upload_filepath;
$info['fileRand'] = $fileRand;
$info['extend'] = $extend;
$info['uploaddir'] = $upload_dir;
$info['size'] = $val['size'];
$this->up_file($info);
if ($makeThumb) {
$this->make_thumb($info);
}
}
return $info;
}
/**
* 文件上传错误提示
*/
public function uploadError($errorcode)
{
switch ($errorcode) {
case '1':
$this->error = '上传的文件超过了php.ini中upload_max_filesize设置的大小';
break;
case '2':
$this->error = '上传文件大小超出了HTML表单的MAX_FILE_SIZE元素所指定的最大值';
break;
case '3':
$this->error = '只有部分文件被上传';
break;
case '4':
$this->error = '没有文件被上传';
break;
case '6':
$this->error = '缺少一个临时文件夹';
break;
case '7':
$this->error = '无法写入文件到磁盘';
break;
case '8':
$this->error = '文件上传停止';
break;
case '999':
default:
$this->error = '';
}
}
/**
* 下载附件
* @param $path
* @param $name
* @return bool
*/
public function download($path, $name)
{
if (empty($name)) {
$name = pathinfo($path)['basename'];
}
$file_name = $path; //服务器的真实文件名
$file_realName = urlencode($name); //数据库的文件名urlencode编码过的
$file = fopen($file_name, "r"); // 打开文件
if ($file) {
header("content-type:text/html; charset=utf-8");
// 输入文件标签
header("Pragma: public");
header("Expires: 0");
Header("Content-type: application/octet-stream;charset=gbk");
if (end(explode('.', $file_realName)) == 'xls' || end(explode('.', $file_realName)) == 'xlsx') {
header("Content-type:application/vnd.ms-excel");
}
Header("Accept-Ranges: bytes");
Header("Accept-Length: " . filesize($file_name));
Header("Content-Disposition: attachment; filename=" . $file_realName);
// 输出文件内容
ini_set('memory_limit', '50M');
$contents = '';
while (!feof($file)) {
$contents .= fread($file, 4096);
}
echo $contents;
fclose($file);
exit;
} else {
return false;
}
}
}
一个图片缩略图类:
<?php
namespace app\common;
use yii;
/**
* 图片缩略图类
*/
class Image
{
private $file;
private $image;
private $info;
public function __construct($file)
{
if (file_exists($file)) {
$this->file = $file;
$info = getimagesize($file);
$this->info = array(
'width' => $info[0],
'height' => $info[1],
'bits' => $info['bits'],
'mime' => $info['mime']
);
$this->image = $this->create($file);
} else {
exit('Error: Could not load image ' . $file . '!');
}
}
private function create($image)
{
$mime = $this->info['mime'];
if ($mime == 'image/gif') {
return imagecreatefromgif($image);
} elseif ($mime == 'image/png') {
return imagecreatefrompng($image);
} elseif ($mime == 'image/jpeg') {
return imagecreatefromjpeg($image);
}
}
public function save($file, $quality = 90)
{
$info = pathinfo($file);
if (!is_dir($info['dirname'])) {
mkdir($info['dirname'], 0777, true);
}
$extension = strtolower($info['extension']);
if (is_resource($this->image)) {
if ($extension == 'jpeg' || $extension == 'jpg') {
imagejpeg($this->image, $file, $quality);
} elseif ($extension == 'png') {
imagepng($this->image, $file);
} elseif ($extension == 'gif') {
imagegif($this->image, $file);
}
imagedestroy($this->image);
}
}
public function resize($width = 0, $height = 0)
{
if (!$this->info['width'] || !$this->info['height']) {
return;
}
$xpos = 0;
$ypos = 0;
$scale = min($width / $this->info['width'], $height / $this->info['height']);
if ($scale == 1 && $this->info['mime'] != 'image/png') {
return;
}
$new_width = (int)($this->info['width'] * $scale);
$new_height = (int)($this->info['height'] * $scale);
$xpos = (int)(($width - $new_width) / 2);
$ypos = (int)(($height - $new_height) / 2);
$image_old = $this->image;
$this->image = imagecreatetruecolor($width, $height);
if (isset($this->info['mime']) && $this->info['mime'] == 'image/png') {
imagealphablending($this->image, false);
imagesavealpha($this->image, true);
$background = imagecolorallocatealpha($this->image, 255, 255, 255, 127);
imagecolortransparent($this->image, $background);
} else {
$background = imagecolorallocate($this->image, 255, 255, 255);
}
imagefilledrectangle($this->image, 0, 0, $width, $height, $background);
imagecopyresampled($this->image, $image_old, $xpos, $ypos, 0, 0, $new_width, $new_height, $this->info['width'], $this->info['height']);
imagedestroy($image_old);
$this->info['width'] = $width;
$this->info['height'] = $height;
}
public function watermark($file, $position = 'bottomright')
{
$watermark = $this->create($file);
$watermark_width = imagesx($watermark);
$watermark_height = imagesy($watermark);
switch ($position) {
case 'topleft':
$watermark_pos_x = 0;
$watermark_pos_y = 0;
break;
case 'topright':
$watermark_pos_x = $this->info['width'] - $watermark_width;
$watermark_pos_y = 0;
break;
case 'bottomleft':
$watermark_pos_x = 0;
$watermark_pos_y = $this->info['height'] - $watermark_height;
break;
case 'bottomright':
$watermark_pos_x = $this->info['width'] - $watermark_width;
$watermark_pos_y = $this->info['height'] - $watermark_height;
break;
}
imagecopy($this->image, $watermark, $watermark_pos_x, $watermark_pos_y, 0, 0, 120, 40);
imagedestroy($watermark);
}
public function crop($top_x, $top_y, $bottom_x, $bottom_y)
{
$image_old = $this->image;
$this->image = imagecreatetruecolor($bottom_x - $top_x, $bottom_y - $top_y);
imagecopy($this->image, $image_old, 0, 0, $top_x, $top_y, $this->info['width'], $this->info['height']);
imagedestroy($image_old);
$this->info['width'] = $bottom_x - $top_x;
$this->info['height'] = $bottom_y - $top_y;
}
public function rotate($degree, $color = 'FFFFFF')
{
$rgb = $this->html2rgb($color);
$this->image = imagerotate($this->image, $degree, imagecolorallocate($this->image, $rgb[0], $rgb[1], $rgb[2]));
$this->info['width'] = imagesx($this->image);
$this->info['height'] = imagesy($this->image);
}
private function filter($filter)
{
imagefilter($this->image, $filter);
}
private function text($text, $x = 0, $y = 0, $size = 5, $color = '000000')
{
$rgb = $this->html2rgb($color);
imagestring($this->image, $size, $x, $y, $text, imagecolorallocate($this->image, $rgb[0], $rgb[1], $rgb[2]));
}
private function merge($file, $x = 0, $y = 0, $opacity = 100)
{
$merge = $this->create($file);
$merge_width = imagesx($this->image);
$merge_height = imagesy($this->image);
imagecopymerge($this->image, $merge, $x, $y, 0, 0, $merge_width, $merge_height, $opacity);
}
private function html2rgb($color)
{
if ($color[0] == '#') {
$color = substr($color, 1);
}
if (strlen($color) == 6) {
list($r, $g, $b) = array($color[0] . $color[1], $color[2] . $color[3], $color[4] . $color[5]);
} elseif (strlen($color) == 3) {
list($r, $g, $b) = array($color[0] . $color[0], $color[1] . $color[1], $color[2] . $color[2]);
} else {
return false;
}
$r = hexdec($r);
$g = hexdec($g);
$b = hexdec($b);
return array($r, $g, $b);
}
}
数据操作类:
<?php
namespace app\common;
use app\models\Attachment as AttachmentModel;
use yii;
/**
* 附件操作类
* 构造函数初始链接ftp
*/
class Attach
{
public $ftp;
public $user;
public $err;
public function __construct($FTP_HOST, $FTP_PORT, $FTP_USER, $FTP_PASS)
{
$this->ftp = new Ftp($FTP_HOST, $FTP_PORT, $FTP_USER, $FTP_PASS);
$this->user = getUserInfo();
}
/**
* @param $uploadfile $_FILES
* @param $module 模块路径
* @param int $makeThumb 是否生成缩略图
* @param string $type 其他格式支持
* @param float|int $maxSize 大小限制
* @param $id 附件表主键id
* @return array
*/
public function uploadFile($uploadfile, $module, $makeThumb = 0, $id = 0, $type = '', $maxSize = 100 * 1024 * 1024)
{
$info = $this->ftp->checkfile($uploadfile, $module, $makeThumb, $type, $maxSize);
if (!$id) { //写入
$id = $this->attachInsertToDatabase($info);
if (!$id) {
return $this->err = '写入失败';
}
} else { //更新
$res = $this->attachUpdateToDatabase($info, $id);
if (false === $res) {
return $this->err = '修改失败';
}
}
$info['fileid'] = $id;
return $info;
}
/**
* 写入数据库
* @param array $info
* @return int
*/
public function attachInsertToDatabase($info = [])
{
$file_temp['module'] = $info['module'];
$file_temp['filename'] = $info['filename'];
$file_temp['filepath'] = $info['filepath'];
$file_temp['filesize'] = $info['size'];
$file_temp['fileext'] = $info['extend'];
$file_temp['userid'] = $this->user['userid'];
$file_temp['username'] = $this->user['realname'] . '(' . $this->user['username'] . ')';
$file_temp['uploadtime'] = time();
$file_temp['uploadip'] = ip();
$file_temp['authcode'] = MD5($info['filepath']);
$attachment = new AttachmentModel();
return $attachment->addData($file_temp);
}
/**
* 更新数据库
* @param array $info
* @return int
*/
public function attachUpdateToDatabase($info = [], $id = 0)
{
$file_temp['module'] = $info['module'];
$file_temp['filename'] = $info['filename'];
$file_temp['filepath'] = $info['filepath'];
$file_temp['filesize'] = $info['size'];
$file_temp['fileext'] = $info['extend'];
$file_temp['userid'] = $this->user['userid'];
$file_temp['username'] = $this->user['realname'] . '(' . $this->user['username'] . ')';
$file_temp['uploadtime'] = time();
$file_temp['uploadip'] = ip();
$file_temp['authcode'] = MD5($info['filepath']);
$attachment = new AttachmentModel();
return $attachment->saveData('id=:id', [':id' => $id], $file_temp);
}
/**
* 删除附件
* @param $path
* @return bool
*/
public function delFile($path)
{
if (!$path) {
return false;
}
$this->ftp->del_file($path);
}
/**下载
* @param $name
* @param $path
*/
public function download($path, $name)
{
$this->ftp->download($path, $name);
}
}
一个简单的缩略图方法:
protected function getthumb($image, $newImageWidth, $newImageHeight)
{
list($imagewidth, $imageheight, $imageType) = getimagesize($image);
$imageType = image_type_to_mime_type($imageType);
switch ($imageType) {
case "image/gif":
$source = imagecreatefromgif($image);
break;
case "image/pjpeg":
case "image/jpeg":
case "image/jpg":
$source = imagecreatefromjpeg($image);
break;
case "image/png":
case "image/x-png":
$source = imagecreatefrompng($image);
break;
default:
$source = imagecreatefromjpeg($image);
break;
}
//图片路径
$arr_tmp = explode('/', $image);
$str_name = "small_".$newImageWidth."_".$arr_tmp[count($arr_tmp) - 1];
unset($arr_tmp[count($arr_tmp) - 1]);
$str_tmp = implode('/', $arr_tmp);
$image_url = $str_tmp.'/'.$str_name;
//最终路径
//$image_url = works/list_FILE.'member/avatar/'.md5($img_name).'_'.$newImageWidth.'.jpg';
$a = copy($image, $image_url); //原图 复制到 新路径中
$newImage = imagecreatetruecolor($newImageWidth, $newImageHeight);
imagecopyresampled($newImage, $source, 0, 0, 0, 0, $newImageWidth, $newImageHeight, $imagewidth, $imageheight);
imagejpeg($newImage, $image_url, '100');
chmod($image_url, 0777);
return $image_url;
}
前端操作base64图片时/正斜杠会被分割的处理:使用 ` ` 包裹起来,而且变量的单引号或者双引号也是必须的
var bigimg = `<img id="big" src='`+ img + `' width="600px" height="600px"/>`;
var bigimg = `<img id="big" src=`+ img + ` width="600px" height="600px"/>`;
注意对比 img 变量两边被单引号包裹了,不然会乱码
<script>
$('#img').click(function(){
$('#containerx').show();
$('.o-mis0428-con-roll').show();
$('.o-mis0428-roll').show();
var img = $(this).find('img').attr('ori');
var bigimg = `<img src='`+ img + `' width="600px" height="550px"/>`;
$(".o-mis-height80").html(bigimg);
});
$('.o-mis0428-con-roll').click(function(){
$('.o-mis0428-roll').hide();
$('#containerx').hide();
})
</script>