两种截取方式:

1:通过服务器进行截取。

2:使用canvas 画布进行本地的截取后上传服务器。

 

准备工作

下载jcorp插件

 

html页面代码

<div class="upload-head fr">

<p class="head-set-title">头像设置</p>

<div class="head-set-pic" style="width:140px;height:140px;overflow:hidden">

<img src="/static/images/head-set.jpg" id="picImg">

</div>

<p class="pdf-max">jpg,jpeg,png,BMP大小不超过5M</p>

<div class="upload-words"><span class="reletive-area"><input class="input-file" type="file" id="upload"><input type="hidden" name ="picture" id="picture"><a class="upload-btn" href="javascript:;">上传头像</a></span>

</div>

</div>

jcorp插件的使用

首先,在改变<input type="file">的src的时候触发事件

file为上传的图片,func为截取框点击确认的时候触发的方法
 

var changeHeadPic= function(file,func)

{

        if (file.files && file.files[0])

{

var reader = new FileReader();

reader.readAsDataURL(file.files[0]);

reader.onload = function (e) {

     //将弹框中显示的图片设置为上传的图片,进行显示

$('#cutimg').removeAttr('src');

$('#cutimg').attr('src', e.target.result);

       //将头像显示的图片设置为上传的图片,进行显示

$('#picImg').removeAttr('src');

$('#picImg').attr('src', e.target.result);

       //设置弹框中显示图片的高度为自动,宽度在样式中进行设置

$('#cutimg').css({

height:"auto"

});

//调用插件,进行截取

jcrop = $.Jcrop('#cutimg',{
                    //设置截取框的大小和起始位置

setSelect: [ 50, 50, 140, 140 ],

allowSelect:false,

bgOpacity:0.6,

dragEdges:true,
                    //规定宽高比例为1 即为正方形

aspectRatio: 1,
                    //移动截取框的事件

onSelect: updateCoords,

onChange: updateCoords

});

};

 

if(jcrop != undefined)
            {

jcrop.destroy();

}

if(typeof(func) == "function")

{

$("#change-pic").data("confirmFunction",func);

}
         //显示弹框 

$("#change-pic").show();

}

}

//移动截取框的事件

var updateCoords = function (c)

{

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

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

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

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

xsize = 140;

ysize = 140;

 

var rx = xsize / (c.w);

var ry = ysize / (c.h);

 

if(jcrop != undefined) {

var bounds = jcrop.getBounds();

boundx = bounds[0];

boundy = bounds[1];

}

if(boundx && boundy)

{
                 //设置移动截取框的时候,显示头像的变化

此处是通过img外部包裹的div的样式进行的控制。

<div class="head-set-pic" style="width:140px;height:140px;overflow:hidden">

<img src="/static/images/head-set.jpg" id="picImg">

</div>

$('#picImg').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'

});

}

};

 

以上工作准备完成,图片截取的准备工作完成,接下来进行点击确认进行真实的图片截取

 

1、上传至服务器进行截取

 

获取截取图片的x,y,w,h的值,并且上传显示的图片的img的宽高,进行截取,因为jcorp的截取框是选择img标签中的宽高

 

var uploadHead = function()

{

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

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

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

var imgh = $("#cutimg").height();

var imgw = $("#cutimg").width();

var formData = new FormData();

formData.append('file', headerFile);

formData.append('x', x);

formData.append('y', y);

formData.append('w', w);

formData.append('h', h);

formData.append('imgh', imgh);

formData.append('imgw', imgw)

$.ajax({

url: "/upload/cut",

data: formData,

type: 'POST',

cache: false,

processData: false,

contentType: false

})

.done(function (data) {

console.log(data);

$("#picImg").attr("src",data);

$("#picImg").css({

width: '140px',

height: '140px',

marginLeft: '0px',

marginTop: '0px'

});

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

})

.fail(function (res) {

console.log("upload is file");

});

}

服务器端代码

@RequestMapping("/cut")

@ResponseBody

public String upLoadCut(

HttpServletRequest request,

@RequestParam(value = "x") String x,

@RequestParam(value = "y") String y,

@RequestParam(value = "h") String h,

@RequestParam(value = "w") String w,

@RequestParam(value = "imgh") int imgh,

@RequestParam(value = "imgw") int imgw,

@RequestParam(value = "file") MultipartFile imageFile) throws IllegalStateException, IOException

{

String ckResult = null;

// 判断是否是multipart类型的请求。

if (request instanceof MultipartHttpServletRequest) {

           //获取文件名称

String fileName = imageFile.getOriginalFilename();

//获取文件后缀

            String suffix = fileName.substring(fileName.lastIndexOf(".")+1, fileName.length()).toLowerCase();

    //上传路径

File dir = new File(remoteDir + remoteSubDir);

if(!dir.exists()){

dir.mkdirs();

}

//重命名文件名称

String saveName = UUID.randomUUID().toString()+"_src.jpg";

//设置上传路径以及名称

File file = new File(dir,saveName);

//将一个通道和另一个通道直接相连接

//设置上传文件与需要保存的文件通道相连

imageFile.transferTo(file);

String srcImagePath = remoteDir + remoteSubDir + saveName;

//设置截取大小

    int imageX = Integer.parseInt(x);

            int imageY = Integer.parseInt(y);

            int imageH = Integer.parseInt(h);

            int imageW = Integer.parseInt(w);

            //截取并且上传图片返回文件读取路径

            ckResult = uploadService.uploadImgCut(imgh,imgw,srcImagePath, suffix, imageX, imageY, imageH, imageW);

}

     return ckResult;

}

/**

* 截取图片 返回文件

* @param srcImageFile 原图片地址

* @param srcImageName 原图片名称

* @param x 截取时的x坐标

* @param y 截取时的y坐标

* @param desWidth 截取的宽度

* @param desHeight 截取的高度

*/

public String uploadImgCut(int imgh, int imgw,String srcImagePath,String suffix, int x, int y, int desWidth,int desHeight){

try {

Image img;

ImageFilter cropFilter;

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

int srcWidth = imgw;

int srcHeight = imgh;

if (srcWidth >= desWidth && srcHeight >= desHeight) {

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

cropFilter = new CropImageFilter(x, y, desWidth, desHeight);

img = Toolkit.getDefaultToolkit().createImage(

new FilteredImageSource(image.getSource(), cropFilter));

BufferedImage tag = new BufferedImage(desWidth, desHeight,

BufferedImage.TYPE_INT_RGB);

Graphics g = tag.getGraphics();

g.drawImage(img, 0, 0, null);

g.dispose();

//设置最新文件名称(截取之后的图片)

String tempName = UUID.randomUUID().toString();

File file = new File(remoteDir+Constants.FilePath.HEAD+tempName+"."+suffix);

//输出文件

ImageIO.write(tag, suffix, file);

//删除源文件

deleteFile(srcImagePath);

//返回文件读取路径

return remoteUrl+Constants.FilePath.HEAD+tempName+"."+suffix;

}

} catch (Exception e) {

e.printStackTrace();

}

return null;

}

public void deleteFile(String sPath) {

File file = new File(sPath);

// 路径为文件且不为空则进行删除

if (file.isFile() && file.exists()) {

file.delete();

}

}

 

 

2、本地截取后上传服务器

//头像截取并且上传事件

var uploadHead = function()

{

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

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

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

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

var imgh = $("#cutimg").height();

var imgw = $("#cutimg").width();

 

//创建第一块画布,将图片真实宽高设置为cutimg元素的宽高,以方便进行截取

var canvas=$('<canvas ></canvas>')[0];

var ctx=canvas.getContext('2d');

var img = new Image();

img.src = $("#picImg").attr("src");

ctx.drawImage(img,0,0,imgw,imgh);

 

//创建第二块画布(需要上传至服务器的图片),进行截取

var canvas1 = $('<canvas width="140" height="140"></canvas>')[0];

var ctx1 = canvas1.getContext('2d');

var img1 = new Image();

img1.src = canvas.toDataURL("image/png");

ctx1.drawImage(img1,x,y,w,h,0,0,140,140);

//此处为测试代码,显示截取后的图片

// $("#aa").html(

// canvas1

// );

 

//以下代码执行上传

var data=canvas1.toDataURL();

// dataURL 的格式为 “data:image/png;base64,****”,逗号之前都是一些说明性的文字,我们只需要逗号之后的就行了

data=data.split(',')[1];

data=window.atob(data);

var ia = new Uint8Array(data.length);

for (var i = 0; i < data.length; i++) {

ia[i] = data.charCodeAt(i);

};

// canvas.toDataURL 返回的默认格式就是 image/png

var blob=new Blob([ia], {type:"image/png"});

 

//进行截取

var formData = new FormData();

formData.append('file', blob);

formData.append('subpath','head');

$.ajax({

url: "/upload/cut",

data: formData,

type: 'POST',

cache: false,

processData: false,

contentType: false

})

.done(function (data) {

console.log(data);

$("#picImg").attr("src",data);

$("#picImg").css({

width: '140px',

height: '140px',

marginLeft: '0px',

marginTop: '0px'

});

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

})

.fail(function (res) {

console.log("upload is file");

});

}

服务器端代码

@RequestMapping("")

@ResponseBody

public String upLoad(HttpServletRequest request,

HttpServletResponse response,

@RequestParam(value = "file") MultipartFile multipartFile,

@RequestParam(value = "subpath") String subpath)

{

logger.debug("Enter method: upLoad()");

String ckResult = null;

// 判断是否是multipart类型的请求。

if (request instanceof MultipartHttpServletRequest) {

//转换为MultipartHttpServletRequest

// MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;

//获取文件

// MultipartFile multipartFile = multipartRequest.getFile("file");

String fileName = multipartFile.getOriginalFilename();

String suffix = fileName.substring(fileName.lastIndexOf(".")+1, fileName.length()).toLowerCase();

//上传文件

try {

ckResult = uploadService.upload(multipartFile.getBytes(), suffix ,subpath);

} catch (IOException e) {

logger.error("Exit method: fileUpload().error the message is [" +e.getMessage()+ "]");

} catch (Exception e) {

logger.error("Exit method: fileUpload().error the message is [" +e.getMessage()+ "]");

}

}

logger.debug("Exit method: fileUpload().");

return ckResult;

}

 

@Override

public String upload(byte[] bytes, String suffix, String subpath) throws Exception {

log.debug("upload process begin...");

String path = "";

String tempName = UUID.randomUUID().toString();

String filePath ="";

//【重要】此处需要设置图片上传的路径以及显示的路径

 

log.debug("the file's raw path is [ "+filePath+" ]");

//上传文件

uploadFileToRemote(bytes, filePath);

log.debug("UPLOAD SUCCESS ! and the file's real internet path is [ "+path+" ]");

return path;

}

 

/**

* 根据传入的byte[]将文件上传到服务器的某个固定路径下

* @param bytes 文件字节流

* @param folderName 远程文件夹名称

* @param fileName 文件名

* @return 拼接的文件的网络路径

*/

public static void uploadFileToRemote(byte[] bytes,String filePath){

//检查文件夹是否存在

int index = filePath.lastIndexOf("/");

String folderName = filePath.substring(0,index+1);

File folder = new File(folderName);

if(!folder.exists()){

folder.mkdirs();

}

//输出文件

File destFile = new File(filePath);

OutputStream out = null;

try {

//检查文件是否存在

if(!destFile.exists()){

destFile.createNewFile();

}

//输出流

out = new FileOutputStream(destFile);

out.write(bytes);

out.flush();

} catch (Exception e) {

log.error("UPLOAD FAILURE ! ,the error is [ "+e+" ]");

}

finally{

//关闭流

try {

if(null != out){

out.close();

}

} catch (IOException e) {

log.error("UPLOAD FAILURE ! REASON: close outputStream failed the error is [ "+e+" ]");

}

}

}

 

此方法需要为什么要创建2个画布的原因(本人的理解)

jcorp插件并没有改变图片的真实大小,获取到截取的X,Y,W,H都是显示的img元素的大小,

如果不创建另外的画布,将图片的大小进行压缩,那么截取的图片就会使上传图片的原始大小,截取会出现错位,

所以需要将图片进行压缩到截取弹框中显示图片的img的大小。

 


使用jcorp进行图片截取的两种方式

点击上传头像按钮,显示如下
使用jcorp进行图片截取的两种方式

选择图片后,显示如下
使用jcorp进行图片截取的两种方式

移动截取框位置,显示如下
使用jcorp进行图片截取的两种方式
点击确认按钮,显示如下
使用jcorp进行图片截取的两种方式

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2022-01-01
  • 2022-03-01
  • 2022-01-05
  • 2021-08-22
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-01-07
  • 2022-12-23
  • 2021-12-09
  • 2021-07-31
相关资源
相似解决方案