新用户注册入口 老用户登录入口

[转载]servlet修改用户头像_修改头像总结

文章作者:转载 更新时间:2023-07-18 10:58:17 阅读数量:267
文章标签:头像处理个人中心修改头像用户上传图片Jcrop控件图片裁剪
本文摘要:本文详细记录了运营平台项目中个人中心模块的头像修改功能实现过程,主要包括用户通过FancyBox弹出层上传图片至服务器端(Servlet处理),利用ajaxForm插件进行文件传输及验证,并借助Jcrop控件实现图片裁剪预览。在用户选定裁剪区域后,系统根据参数对图片进行裁剪并保存为最终头像。整个过程中涵盖了从上传、处理到展示头像的关键技术环节,切实解决了用户在个人中心修改头像的需求。
转载文章

本篇文章为转载内容。原文链接:https://blog.csdn.net/weixin_39849287/article/details/111489534。

该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。

作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。

如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。

1,背景

博客停了好久,主要是最近工作太忙了,还有就是身体状况没有以前那么好了,乘着国庆长假的空档,写下这篇一直想写的文章。

运营平台是我主要致力的一个项目,这个项目分为四个大部分,个人中心,充值中心,客服中心,家长监护,最近主要忙着个人中心的重写和丰富,关于个人中心,无非就是对平台用户信息的自我管理,以及一些对用户帐号的安全保护措施,下图的菜单非常简要的说明了个人中心的功能。个人觉得最值得关注的就是密保设置和修改头像,因为之前没有处理过类似的问题,本文主要记录对头像的处理过程以及思考,希望给碰到类似问题的苦逼程序员一点借鉴。

个人中心整体功能一览

2,头像处理xmind

叽歪一句,个人碰到问题的时候,首先会分析问题,在分析问题的基础上,得到整体的解决方案,然后一步步分解步骤,去实现,首先奉上我的解决方案,也许不是最优的,但是按照个人的知识和技能水平,绝对是可以实现的。

修改头像mind

3,实现步骤

按照我的mind,首先是上传图片,先上效果图,然后给出实现的代码。首先是整体的结构图,做的比较丑,别喷哥···

修改头像整体效果图

下面按照mind一步步实现,

首先:点击修改头像,弹出一个层,

第一步:弹出上传图片的层,上传图片到服务器

对实现细节不感冒的屌丝可以看看代码(结合哥的mind看可以事半功倍):

分层实现细节

Html结构层这个可以免了,一般都可以弄出来

Js连接层

首先是弹出一个上传图片的层,然后上传图片到服务器端。 $("#editHead").bind("click", function () {

showUploadDiv();

});

function showUploadDiv() {

$("#uploadMsg").empty();

$.fancybox({

type:'inline',

width:400,

href:'#uploadUserHead'

});

}//fancybox弹出层

上传的处理代码

Servlet服务端处理层(commonupload实现)服务器端处理代码

上传的处理代码

$(function () {

$("#uploadFrom").ajaxForm({

beforeSubmit:checkImg,

error:function(data,status){

alert(status+' , '+data);

$("#uploadMsg").html('上传文件超过1M!');

},

success:function (data,status) {

try{

var msg = $.parseJSON(data);

if (msg.code == 200)

{ //如果成功提交

javascript:$.fancybox.close();

$("#uploadUserHead").hide();

var data = msg.object;

$("#editImg").attr("src", data.path).show();

$("#preview1").attr("src", data.path).show();

$(".zoom").show();

$("#width").val(data.width);

$("#height").val(data.height);

$("#oldImgPath").val(data.realPath);

$("#imgFileExt").val(data.fileExt);

var api, jcrop_api, boundx, boundy;

$('#editImg').Jcrop({

onChange:updatePreview,

onSelect:updatePreview,

aspectRatio:1,

bgOpacity:0.5,

bgColor:'white',

addClass:'jcrop-light'

}, function () {

api = this;

api.setSelect([130, 65, 130 + 350, 65 + 285]);

api.setOptions({ bgFade:true });

api.ui.selection.addClass('jcrop-selection');

var bounds = this.getBounds();

boundx = bounds[0];

boundy = bounds[1];

jcrop_api = this;

});

function updatePreview(c) {

if (parseInt(c.w) > 0) {

var rx = 80 / c.w;

var ry = 80 / c.h;

$('#preview1').css({

width:Math.round(rx * boundx) + 'px',

height:Math.round(ry * boundy) + 'px',

marginLeft:'-' + Math.round(rx * c.x) + 'px',

marginTop:'-' + Math.round(ry * c.y) + 'px'

});

}

jQuery('#x').val(c.x);

jQuery('#y').val(c.y);

jQuery('#x2').val(c.x2);

jQuery('#y2').val(c.y2);

jQuery('#w').val(c.w);

jQuery('#h').val(c.h);

}

}

if (msg.code == 204) {

$("#uploadMsg").html(msg.msg);

}

}catch (e){

$("#uploadMsg").html('上传文件超过1M!');

}

}

});

});

//服务器端处理代码

String tempSavePath =  ConfigurationUtils.get("user.resource.dir"); //上传的图片零时保存路径

String tempShowPath =  ConfigurationUtils.get("user.resource.url"); //用户保存的头像路径

if(tempSavePath.equals("/img"))

{

tempSavePath=sc.getRealPath("/")+tempSavePath;

}

Msg msg = new Msg();

msg.setCode(204);

msg.setMsg("上传头像失败!");

String type = request.getParameter("type");

if (!Strings.isNullOrEmpty(type) && type.equals("first")) {

request.setCharacterEncoding("utf-8");

DiskFileItemFactory factory = new DiskFileItemFactory();

ServletFileUpload servletFileUpload = new ServletFileUpload(factory);

try {

List items = servletFileUpload.parseRequest(request);

Iterator iterator = items.iterator();

while (iterator.hasNext()) {

FileItem item = (FileItem) iterator.next();

if (!item.isFormField()) {

{

File tempFile = new File(item.getName());

File saveTemp = new File(tempSavePath+"/tempImg/");

String getItemName=tempFile.getName();

String fileName = UUID.randomUUID()+"." +getItemName.substring(getItemName.lastIndexOf(".") + 1, getItemName.length());

File saveDir = new File(tempSavePath+"/tempImg/", fileName);

//如果目录不存在,创建。

if (saveTemp.exists() == false) {

if (!saveTemp.mkdir()) { // 创建失败

saveTemp.getParentFile().mkdir();

saveTemp.mkdir();

} else {

}

}

if (saveDir.exists()) {

log.info("存在同名文件···");

saveDir.delete();

}

item.write(saveDir);

log.info("上传头像成功!"+saveDir.getName());

msg.setCode(200);

msg.setMsg("上传头像成功!");

Image image = new Image();

BufferedImage bufferedImage = null;

try {

bufferedImage = ImageIO.read(saveDir);

} catch (IOException e) {

e.printStackTrace();

}

image.setHeight(bufferedImage.getHeight());

image.setWidth(bufferedImage.getWidth());

image.setPath(tempShowPath+ "/tempImg/" + fileName);

log.info(image.getPath());

image.setRealPath(tempSavePath+"/tempImg/"+ fileName);

image.setFileExt(fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length()));

msg.setObject(image);

}

} else {

log.info("" + item.getFieldName());

}

}

} catch (Exception ex) {

log.error("上传用户头像图片异常!");

ex.printStackTrace();

}

finally {

AppHelper.returnJsonAjaxForm(response, msg);

}

}

上传成功后,可以看到照片和照片的预览效果。看图:

上传头像之后的效果

Friday, October 05, 2012

第二步:编辑和保存头像

选中图中的区域,保存头像,就完成头像的修改。

修改之后的效果入下:

修改之后的头像(因为传了一张动态图片,得到的跟上图有些不同)

实现细节:

首先用了一个js控件:Jcrop,有兴趣的屌丝可以去搜一下,然后,利用上传之后的图片和之前的选定区域,完成了一个截图,保存为用户的头像。

连接层的js:

$("#saveHead").bind("click", function () {

var width = $("#width").val();

var height = $("#height").val();

var oldImgPath = $("#oldImgPath").val();

var imgFileExt = $("#imgFileExt").val();

var x = $('#x').val();

var y = $('#y').val();

var w = $('#w').val();

var h = $('#h').val();

$.ajax({

url:'/imgCrop',

type:'post',

data:{x:x, y:y, w:w, h:h, width:width, height:height, oldImgPath:oldImgPath, fileExt:imgFileExt},

datatype:'json',

success:function (msg) {

if (msg.code == 200) {

$("#avatar").attr("src", msg.object);

forword('/nav', 'index');

}

else {

alert(msg.msg);

}

}

});

});

function checkImg() {

//限制上传文件的大小和后缀名

var filePath = $("input[name='uploadImg']").val();

if (!filePath) {

$("#uploadMsg").html("请选择上传文件!").show();

return false;

}

else {

var extStart = filePath.lastIndexOf(".");

var ext = filePath.substring(extStart, filePath.length).toUpperCase();

if (ext != ".PNG" && ext != ".GIF" && ext != ".JPG") {

$("#uploadMsg").html("图片限于png,gif,jpg格式!").show();

return false;

}

}

return true;

}

服务器端处理代码:

String savePath =  ConfigurationUtils.get("user.resource.dir"); //上传的图片保存路径

String showPath =  ConfigurationUtils.get("user.resource.url"); //显示图片的路径

if(savePath.equals("/img"))

{

savePath=sc.getRealPath("/")+savePath;

}

int userId = AppHelper.getUserId(request);

String userName=AppHelper.getUserName(request);

Msg msg = new Msg();

msg.setCode(204);

msg.setMsg("剪切图片失败!");

if (userId <= 0) {

msg.setMsg("请先登录");

return;

}

// 用户经过剪辑后的图片的大小

Integer x = (int)Float.parseFloat(request.getParameter("x"));

Integer y = (int)Float.parseFloat(request.getParameter("y"));

Integer w = (int)Float.parseFloat(request.getParameter("w"));

Integer h = (int)Float.parseFloat(request.getParameter("h"));

//获取原显示图片路径 和大小

String oldImgPath = request.getParameter("oldImgPath");

Integer width = (int)Float.parseFloat(request.getParameter("width"));

Integer height = (int)Float.parseFloat(request.getParameter("height"));

//图片后缀

String imgFileExt = request.getParameter("fileExt");

String foldName="/"+ DateUtils.nowDatetoStrToMonth()+"/";

String imgName = foldName + UUID.randomUUID()+userName + "." + imgFileExt;

//组装图片真实名称

String createImgPath = savePath + imgName;

//进行剪切图片操作

ImageCut.abscut(oldImgPath,createImgPath, x*width/300, y*height/300, w*width/300, h*height/300);

File f = new File(createImgPath);

if (f.exists()) {

msg.setObject(imgName);

//把显示路径保存到用户信息下面。

UserService userService = userServiceProvider.get();

int rel = userService.updateUserAvatar(userId, showPath+imgName);

if (rel >= 1) {

msg.setCode(200);

msg.setMsg("剪切图片成功!");

log.info("剪切图片成功!");

//记录日志,更新session

log(showPath+imgName,userName);

UserObject userObject= userService.getUserObject(userName);

request.getSession().setAttribute("userObject", userObject);

if (userObject != null && Strings.isNullOrEmpty(userObject.getHeadDir()))

userObject.setHeadDir("/images/geren_right_01.jpg");

} else {

msg.setCode(204);

msg.setMsg("剪切图片失败!");

log.info("剪切图片失败!");

}

}

AppHelper.returnJson(response, msg);

File file=new File(oldImgPath);

boolean deleteFile= file.delete();

if(deleteFile==true)

{

log.info("删除原来图片成功");

}

/**

* 图像切割(改)     *

*

* @param srcImageFile 源图像地址

* @param dirImageFile 新图像地址

* @param x            目标切片起点x坐标

* @param y            目标切片起点y坐标

* @param destWidth    目标切片宽度

* @param destHeight   目标切片高度

*/

public static void abscut(String srcImageFile, String dirImageFile, int x, int y, int destWidth, int destHeight) {

try {

Image img;

ImageFilter cropFilter;

// 读取源图像

BufferedImage bi = ImageIO.read(new File(srcImageFile));

int srcWidth = bi.getWidth(); // 源图宽度

int srcHeight = bi.getHeight(); // 源图高度

if (srcWidth >= destWidth && srcHeight >= destHeight) {

Image image = bi.getScaledInstance(srcWidth, srcHeight, Image.SCALE_DEFAULT);

// 改进的想法:是否可用多线程加快切割速度

// 四个参数分别为图像起点坐标和宽高

// 即: CropImageFilter(int x,int y,int width,int height)

cropFilter = new CropImageFilter(x, y, destWidth, destHeight);

img = Toolkit.getDefaultToolkit().createImage(new FilteredImageSource(image.getSource(), cropFilter));

BufferedImage tag = new BufferedImage(destWidth, destHeight, BufferedImage.TYPE_INT_RGB);

Graphics g = tag.getGraphics();

g.drawImage(img, 0, 0, null); // 绘制缩小后的图

g.dispose();

// 输出为文件

ImageIO.write(tag, "JPEG", new File(dirImageFile));

}

} catch (Exception e) {

e.printStackTrace();

}

}

最后一个处理的比较好的地方就是图片的存储路径问题:

我在服务器端的nginx中做了一个图片的地址映射,把图片放到了跟程序不同的路径中,每次存储图片都是存到图片路径中,客户端拿到图片的地址确实经过nginx映射过的地址。

还有就是关于限制上传图片的大小的问题:

我在服务器端显示了资源的最大大小为1M,当上传的资源超过1M,服务器自动报错413,通过异常处理,可以在客户端得到正确的提示信息。

4,总结优点和不足。

关于修改头像,这么做下来确实达到了目的,用户可以从容的修改头像,性能也还可以。但是,上传图片的大小判断是依靠服务器端来判断的,等待的时间比较久,改进的方向是使用flash控件来限制,使用flash来上传,也不会出现弹出层,这样比较大众化,更容易为用户接受一点。我会不断改进。

本篇文章为转载内容。原文链接:https://blog.csdn.net/weixin_39849287/article/details/111489534。

该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。

作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。

如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。

相关阅读
文章标题:[转载][洛谷P1082]同余方程

更新时间:2023-02-18
[转载][洛谷P1082]同余方程
文章标题:[转载]webpack优化之HappyPack实战

更新时间:2023-08-07
[转载]webpack优化之HappyPack实战
文章标题:[转载]oracle 同时更新多表,在Oracle数据库中同时更新两张表的简单方法

更新时间:2023-09-10
[转载]oracle 同时更新多表,在Oracle数据库中同时更新两张表的简单方法
文章标题:[转载][Unity] 包括场景互动与射击要素的俯视角闯关游戏Demo

更新时间:2024-03-11
[转载][Unity] 包括场景互动与射击要素的俯视角闯关游戏Demo
文章标题:[转载]程序员也分三六九等?等级差异,一个看不起一个!

更新时间:2024-05-10
[转载]程序员也分三六九等?等级差异,一个看不起一个!
文章标题:[转载]海贼王 动漫 全集目录 分章节 精彩打斗剧集

更新时间:2024-01-12
[转载]海贼王 动漫 全集目录 分章节 精彩打斗剧集
名词解释
作为当前文章的名词解释,仅对当前文章有效。
ServletServlet是一种Java技术,用于开发Web应用程序的服务器端组件。在文章中,Servlet被用来处理用户上传头像的请求,接收并解析HTTP请求中的图片数据,然后在服务器端进行临时保存、尺寸获取、格式判断等一系列操作,并将处理结果返回给客户端。
AjaxFormAjaxForm是一个jQuery插件,专门用于实现表单异步提交和文件上传功能。在文中,作者使用ajaxForm插件来封装用户的头像上传表单,通过AJAX方式将图片发送到服务器端,同时支持文件大小校验等前置处理以及成功后的回调函数执行。
JcropJcrop是一个基于JavaScript的图像裁剪插件,它提供了一种直观、交互式的图像选择与裁剪界面。在本文所描述的场景中,用户在上传头像后,利用Jcrop选择需要保留的部分,该插件能够实时显示裁剪区域及预览效果,最终将选定区域的数据发送给服务器完成头像的精确裁剪与更新。
FancyBoxFancyBox是一款流行且易用的jQuery轻量级插件,用于实现网页上的图片弹出展示、iframe内容加载等功能。在文章中,作者运用FancyBox来创建一个弹出层,用户点击修改头像时,会通过Fancybox弹出一个包含上传图片表单的界面,从而实现在不跳转页面的情况下完成头像上传的操作流程。
延伸阅读
作为当前文章的延伸阅读,仅对当前文章有效。
在深入探讨了运营平台项目中个人中心头像修改功能的实现细节后,我们不难发现,随着移动互联网和社交网络的飞速发展,用户对于个性化设置的需求日益增强,头像作为用户在线身份的重要标识,其上传与编辑功能的设计显得尤为重要。近期,多家知名社交平台和技术博客都针对用户头像处理技术进行了升级优化。
例如,Facebook在2022年推出了一项新的图像处理技术,允许用户在上传头像时实时预览多种滤镜效果及裁剪比例,极大提升了用户体验。该技术背后运用了先进的图像识别算法与深度学习技术,确保即使在网络环境不稳定的情况下,也能实现快速、准确的图像处理。
另外,微信团队也于近期发布了关于小程序内用户头像处理接口的更新公告,提供了更灵活、便捷的头像上传与编辑API,开发者可以基于此构建更为丰富的个性化设置功能。此举不仅简化了开发流程,也为用户提供更多样化的头像定制选项。
此外,从安全性和隐私保护角度出发,欧盟GDPR等相关法规对用户数据处理提出了严格要求,这也促使各平台在设计头像上传功能时,必须兼顾到用户信息的安全存储与传输。众多企业开始采用加密上传、权限控制等手段,确保用户头像数据的安全性。
综上所述,在当前互联网环境下,用户头像处理技术正不断迭代创新,以满足日益增长的个性化需求和严格的隐私保护规范。无论是大型社交平台的技术突破,还是各类开发框架对头像上传功能的优化改进,都为我们提供了丰富的实践案例与参考思路,值得广大开发者持续关注并深入研究。
知识学习
实践的时候请根据实际情况谨慎操作。
随机学习一条linux命令:
history | tail -n 10 - 查看最近十条历史记录。
随便看看
拉到页底了吧,随便看看还有哪些文章你可能感兴趣。
RabbitMQ实战中因API版本问题导致消息丢失的排查与修复 03-12 jQuery元素滚动动画库插件-ScrollMagic 02-09 属性级联同步与实体管理:Hibernate实战案例详解 01-27 jQuery超酷3D包装盒封面旋转特效 05-16 ElSteps组件动态改变当前步骤时样式更新滞后问题的Vue.js解决方案 02-22 java中处理异常的方式和语句 01-13 AI助手的工作原理与限制:无法按特定要求撰写的原因及信息处理分析 12-27 代码写的html网红钟表 12-18 简约大气文艺工作者作品展示网站模板 09-21 本次刷新还10个文章未展示,点击 更多查看。
ClickHouse系统重启情境下的数据丢失风险与应对:写入一致性、同步模式及备份恢复策略实践 08-27 jQuery带放大镜的迷你幻灯片插件 08-16 简约手机UI设计公司网站模板下载 04-30 绿色经典响应式主机服务器托管网站模板 04-25 PostgreSQL中应对密码过期警告:安全更改密码的步骤与注意事项 04-17 docker改tag(docker改配置文件) 03-17 [转载]蓝桥 利息计算(Java) 03-11 jquery文字动画特效插件animatext 01-22 大气简洁手机电子产品展示柜台前端模板 01-22 [转载]ubuntu用户和权限介绍 01-10 可爱毛绒玩具网上商城响应式网站模板 01-05
时光飞逝
"流光容易把人抛,红了樱桃,绿了芭蕉。"