divclasswarpinput typefileidfileacceptimage/*onchangeupimg(this)//divimg src/script//上传图片方法functionupimg(obj){varfileDataobj.files[0];//这是我们上传的文件console.log(fileData)varformDatanewFormData();// 服务端要求参数是 pic1formData.append(image,fileData);$.ajax({url:{:url(user/upmemberphoto)},type:post,data:formData,cache:false,//上传文件不需要缓存processData:false,// 告诉jQuery不要去处理发送的数据contentType:false,// 告诉jQuery不要去设置Content-Type请求头success:function(data){// 关键清空 input 的 value允许再次上传同一文件$(#file).val()console.log(data);// 设置图片预览功能$(.head-img).attr(src,data.picAddr);}})}/scriptvue2的写法templatediv!-- 文件上传按钮 --inputtypefilereffileInputacceptimage/*changeupimg/!-- 预览图片 --img:srcpreviewImagealt预览//div/templatescript// 假设你的项目中已安装 axios或直接使用原生 fetchimportaxiosfromaxiosexportdefault{data(){return{previewImage:,// 存储预览图片地址服务器返回的}},methods:{//上传图片upimg(event){varfileDataevent.target.files[0];//这是我们上传的文件console.log(fileData)varformDatanewFormData();// 服务端要求参数是 pic1formData.append(image,fileData);$.ajax({url:{:url(user/upmemberphoto)},type:post,data:formData,cache:false,//上传文件不需要缓存processData:false,// 告诉jQuery不要去处理发送的数据contentType:false,// 告诉jQuery不要去设置Content-Type请求头success:(data){// 关键清空 input 的 value允许再次上传同一文件this.$refs.fileInput.valueconsole.log(data);// 设置图片预览功能$(.head-img).attr(src,data.picAddr);}})}}}/scriptthinkphp压缩图片插件官方地址使用Composer安装ThinkPHP5的图像处理类库composer require topthink/think-image/** * 会员照片上传 - 直接压缩保存 自动修正旋转 */publicfunctionupmemberphoto(){// 获取上传文件$filerequest()-file(image);if(!$file){return[code400,message未检测到上传文件];}$uploadPathROOT_PATH.public.DIRECTORY_SEPARATOR.uploads.DIRECTORY_SEPARATOR.member;// 确保上传目录存在if(!is_dir($uploadPath)){mkdir($uploadPath,0755,true);}// 移动到服务器先保存临时原图$info$file-move($uploadPath);if(!$info){return[code400,message文件移动失败: .$file-getError()];}// 处理路径统一使用正斜杠$saveNamestr_replace(DIRECTORY_SEPARATOR,/,$info-getSaveName());$imgPath$uploadPath./.$saveName;try{// 核心处理修正旋转 压缩保存不保留原图$this-processImage($imgPath,620,85);return[code200,message上传成功,data/uploads/member/.$saveName];}catch(\Exception$e){// 记录日志 清理失败文件\think\Log::record(图片处理失败: .$e-getMessage(),error);if(file_exists($imgPath)){unlink($imgPath);}return[code500,message图片处理失败: .$e-getMessage()];}}/** * 图片处理修正EXIF旋转 等比压缩 覆盖保存 * param string $imgPath 图片绝对路径 * param int $maxWidth 最大宽度 * param int $quality JPEG压缩质量(1-100) */privatefunctionprocessImage($imgPath,$maxWidth620,$quality85){// 1️⃣ 检查文件if(!file_exists($imgPath)){thrownew\Exception(文件不存在:{$imgPath});}// 2️⃣ 打开图片$image\think\Image::open($imgPath);if(!$image){thrownew\Exception(无法打开图片请检查GD/Imagick扩展);}// 3️⃣ 【关键】修正手机拍照的EXIF旋转问题$this-fixExifOrientation($imgPath,$image);// 4️⃣ 获取修正后的尺寸判断是否需要压缩$width$image-width();$height$image-height();// 只有当宽度超过设定值时才压缩避免小图被强行放大if($width$maxWidth){$image-thumb($maxWidth,$maxWidth,\think\Image::THUMB_SCALING);}// 5️⃣ 【关键】覆盖保存原路径不保留原图// 第三个参数 $quality 控制压缩质量越小文件越小$saveResult$image-save($imgPath,null,$quality);if(!$saveResult){thrownew\Exception(图片保存失败请检查目录权限);}}/** * 修正图片EXIF方向解决手机拍照旋转90度问题 * param string $imgPath 图片路径 * param \think\Image $image ThinkPHP Image对象 */privatefunctionfixExifOrientation($imgPath,$image){// 检查exif扩展是否启用if(!extension_loaded(exif)){return;// 没扩展就跳过至少保证流程继续}// 仅处理JPEG图片其他格式一般不含EXIF方向$mimestrtolower(mime_content_type($imgPath));if(!in_array($mime,[image/jpeg,image/jpg])){return;}$exifexif_read_data($imgPath);if(!$exif||empty($exif[Orientation])){return;}// 根据Orientation值旋转图片旋转后像素数据就正了switch($exif[Orientation]){case3:// 180°$image-rotate(180);break;case6:// 顺时针90°最常见$image-rotate(90);break;case8:// 逆时针90°$image-rotate(-90);break;// 2/4/5/7 涉及镜像翻转手机照片极少出现可按需扩展}}另外一种方法传递base64图片提交图片数据的字符串img idmemberHeadimgsrcalt/input typefileidimgopiptacceptimage/*onchangegetBase64(event)/input typehiddenidphotonamephoto///上传图片获取base64functiongetBase64(e){// 选择的文件letfilee.target.files[0];console.log(file.name)// 文件名称有需求可处理console.log(file.type)// 文件类型有需求可处理// 判断文件是否读取完毕读取完毕后执行if(window.FileReader){letreadernewFileReader();reader.readAsDataURL(file);reader.onloadfunction(e){letbase64Stringe.target.result;// 此处可对该base64进行获取赋值传入后端console.log(bese64编码,base64String);$(#photo).val(base64String)$(#memberHeadimg).attr(src,base64String)}}}tp5.0接收base64的字符串保存为文件宽度超过600的压缩并且图片不旋转90度/*判断图片是否存在 存在则保存图片路径 系统进程结束之后单独上传图片上传图片*/$photo!empty($_REQUEST[photo])?$_REQUEST[photo]:;$img_url;//图片路径$base64_imagestr_replace( ,,$photo);//post方式接收的数据, 加号会被替换为空格, 需要重新替换回来, 若不是post数据, 不需要执行//$result 是一个数组引用传递用于存储正则匹配的捕获结果。if(preg_match(/^(data:\s*image\/(\w);base64,)/,$base64_image,$result)){$image_database64_decode(str_replace($result[1],,$base64_image));$imimagecreatefromstring($image_data);if($im!false){$extstrtolower($result[2]);if($extjpeg)$extjpg;// 统一后缀// 1. 修正 JPEG 的方向EXIF Orientation if($extjpgfunction_exists(exif_read_data)){// 将图片二进制数据写入临时文件exif_read_data 需要读取文件$tempFiletmpfile();fwrite($tempFile,$image_data);$tempMetastream_get_meta_data($tempFile);$tempPath$tempMeta[uri];$exifexif_read_data($tempPath);fclose($tempFile);if(!empty($exif[Orientation])){$orientation$exif[Orientation];// 根据 Orientation 值旋转/翻转图片switch($orientation){case3:$imimagerotate($im,180,0);break;case6:$imimagerotate($im,-90,0);break;case8:$imimagerotate($im,90,0);break;// 如果需要支持镜像2,4,5,7可继续补充但绝大多数情况只用到 3,6,8}}}// 2. 尺寸压缩等比例限制最大宽度600 $max_width600;$src_wimagesx($im);$src_himagesy($im);if($src_w$max_width){$dst_w$max_width;$dst_hintval($src_h*($max_width/$src_w));$im2imagecreatetruecolor($dst_w,$dst_h);// 透明背景处理PNG/GIF 保留透明通道if($extpng){imagealphablending($im2,false);imagesavealpha($im2,true);$transimagecolorallocatealpha($im2,0,0,0,127);imagefilledrectangle($im2,0,0,$dst_w,$dst_h,$trans);}elseif($extgif){$trans_indeximagecolortransparent($im);if($trans_index0){imagepalettecopy($im,$im2);imagefill($im2,0,0,$trans_index);imagecolortransparent($im2,$trans_index);}}imagecopyresampled($im2,$im,0,0,0,0,$dst_w,$dst_h,$src_w,$src_h);imagedestroy($im);$im$im2;}// 3. 保存文件质量压缩 $dir./uploads/member/.date(Ymd);if(!is_dir($dir))mkdir($dir,0777,true);$picnamedate(his)._.rand(10000,99999);$picdir$picname...$ext;$image_url$dir./.$picdir;switch($ext){casejpg:imagejpeg($im,$image_url,80);break;casepng:imagepng($im,$image_url,6);break;casegif:imagegif($im,$image_url);break;casewebp:imagewebp($im,$image_url,80);break;default:file_put_contents($image_url,$image_data);}imagedestroy($im);$img_url$image_url;}}免费在线工具网站 https://mantools.top/