前段时间写项目的时候,当时写一个上传,因为当时正好在研究数据流的方式,所以采用的数据流方式来做的上传。但是后来审核项目的时候,被要求使用微信官方的JSSDK来上传图片。理由是:部分安卓机在微信浏览器的时候,input标签中的file类型被微信浏览器直接砍掉了。所以会没有任何作用。可是后来我研究发现,采用数据流的形式上传,却可以完美的避过这种缺陷,达到JSSDK的效果。下面上代码吧:
0x01 html表单
<input accept="image/*" type="file" name="main-file" id="main-file"/>
0x02 JS部分
var reader = new FileReader();
//将文件以Data URL形式读入页面.
var Data = {};
reader.readAsDataURL(document.getElementById("main-file").files[0]);
reader.onload = function () {
//将图片转为数据流并赋给Data.格式为:data:image/jpeg;base64,.......后面是base64码
Data['enctype'] = this.result;
//这两步是将这个base64数据流放到img标签中的src属性里面,做预览图
$('.ring').children().remove();
$('.ring').html('<div class=\"portrait\"> <img style=\"width: 196px;height: 196px;border-radius: 50%;\" src=' + Data['enctype'] + '> </div>');
}
0x03 PHP部分
//图片数据流处理!
public function base64DecImg($baseData, $Dir, $fileName){
// 前台访问URL API
$__URL__= 'http://g.admin.org/';
// 服务器根目录绝对路径获取API
$__root__='/home/wwwroot/img.cc';
// 上诉两个变量,依据实际情况自行修改
try{
$expData = explode(';',$baseData);
$postfix = explode('/',$expData[0]);
if( strstr($postfix[0],'image') ){
$postfix = $postfix[1] == 'jpeg' ? 'jpg' : $postfix[1];
$storageDir = $Dir.'/'.date('ymd').'/'.$fileName.'.'.$postfix;
$export = base64_decode(str_replace("{$expData[0]};base64,", '', $baseData));
$returnDir = str_replace(str_replace('/','\\',$__root__),'',$storageDir);
try{
$file = $__root__.'/'.$Dir.'/'.date('ymd').'/';
if (!is_dir($file)) mkdir($file,0777);
// 检测是否有权限操作
if (!is_writable($file)) chmod($file, 0777); // 如果无权限,则修改为0777最大权限
file_put_contents($__root__.'/'.$returnDir, $export);
// $imgfile = $__root__.'/'.$Dir.'/'.date('ymd').'/8211477463693'.'.'.$postfix;;
$imgfile = $__root__.'/'.$returnDir;
//检测是否开启exif扩展,用于旋转iphone拍照上传自动旋转
if (!function_exists('exif_read_data')) {
return;
}
$img = @imagecreatefromjpeg($imgfile);
if($img === false){
return;
}
$exif = exif_read_data($imgfile);
if (!empty($exif['Orientation'])) {
switch ($exif['Orientation']) {
case 8:
$image = imagerotate($img, 90, 0);
break;
case 3:
$image = imagerotate($img, 180, 0);
break;
case 6:
$image = imagerotate($img, -90, 0);
break;
}
}
imagedestroy($img);
if (isset($image)) {
imagejpeg($image, $imgfile);
imagedestroy($image);
}
//缩放图片
$config['image_library'] = 'gd2';
$config['source_image'] = $__root__.'/'.$returnDir;
$config['create_thumb'] = TRUE;
$config['maintain_ratio'] = TRUE;
$config['width'] = 250;
// $config['height'] = 196;
$this->load->library('image_lib', $config);
if ($this->image_lib->resize())
{
unlink($__root__.'/'.$returnDir);
return $__root__.'/'.$Dir.'/'.date('ymd').'/'.$fileName.'_thumb.'.$postfix;
}
}catch(Exception $e){
return false;
}
}
}catch(Exception $e){
return false;
}
return false;
}
0x04 结语
PHP代码部分就是一个完整的控制器,放在类里面,接收的时候采用同样的post接值,然后将这个数据流传到这个控制器,就直接返回图片地址!