primefaces - Crop image and send it to jsf bean without unnecessary data transfer -
i'd upload image generated jquery cropper bean field.
client side ve found this:
<p:fileupload id="imginp" mode="simple" allowtypes="/(\.|\/)(gif|jpe?g|png)$/"/> <img id="blah" src="#" alt="your image" /> <p:imagecropper image="" /> <script> var reader = new filereader(); reader.onload = function (e) { $('#blah').attr('src', e.target.result); } function readurl(input) { if (input.files && input.files[0]) { reader.readasdataurl(input.files[0]); } } $("#imginp").change(function(){ readurl(this); }); </script> it displays image without uploading can't in cropper. use jquery cropper i'm not sure how in bean (without going through servlets, because it's not 1 time use). in other words need send img through ajax bean.
otherwise i'd use primeface has go through wire i'd avoid if possible. example i've seen image static content on server. have save image on server ? can't keep object , convert uploadedfile cropper accept ?
soomething this:
<p:fileupload mode="advanced" allowtypes="/(\.|\/)(gif|jpe?g|png)$/" fileuploadlistener="#{bean.uploadpiclistenner}" update="cropper"/> <h:panelgroup id="cropper" > <p:imagecropper image="#{bean.img}"/> </h:panelgroup> public void uploadpiclistenner(fileuploadevent e) { img = e.getfile(); requestcontext.getcurrentinstance().update("ptform:cropper"); }
it's quite simple once process understood despite misleading answers can found online. hope gonna in future.
the technique used :
pick image
once image picked, display in cropper without sending through wire.
here there few option , choosed : when user moves cropper rectangle around, coordinates of rectangle populate hidden input field.
send coordinate bean , crop on server side.
i did way because cropper jquery lib wanted use didn't transform image base 64 , gave coordinates of rectangle. if want send cropped image directly in future figured easy. did except have put cropped image string base 64 in hidden input text (instead of rectangle coordinates - explained under-) , transform on server side, that's all. (i don't know how efficient / secure however). @ least resolved issue had primefaces, not wanting send unnecessary data on wire multiple times.
1. first let's display image without sending server.
at point when image displayed if check inside src tag of img see data of image base 64:
src="data:image/jpeg;base64,/9j/4aaqskzjrgabaqeaaqabaad/2wceaayebqyfbaygbq...
<h:form id="lolo" enctype="multipart/form-data"> <p:fileupload value="#{admincreateteam.teamimg}" mode="simple" allowtypes="/(\.|\/)(gif|jpe?g|png)$/"/> <img id="blah" src="#" alt="your image" /> </h:form> <script> var reader = new filereader(); reader.onload = function (e) { $('#blah').attr('src', e.target.result); } function readurl(input) { if (input.files && input.files[0]) { reader.readasdataurl(input.files[0]); } } $("#lolo\\:imginp").change(function(){ readurl(this); }); </script> - once have done becomes bit dependent on jquery cropping library used. used cropper lib. 1 want have coordinate of cropped rectangle. coordinates data populate hidden input , send bean recrop on java side.
alternatively better solution (imo) use library crop image , give data client side base 64, populate hidden field , send bean, convert base 64 image. each of these steps quiet easy , can found on stackoverflow.
since wanted use cropper library did first way:
this added inside form:
<h:inputhidden value="#{admincreateteam.rect}"/> <p:commandbutton value="submit" action="#{admincreateteam.pictest}" ajax="false"/> this updated onload:
// hidden field gonna populated // cropping rectangle data. var $imagecrop = $('#blah').cropper({ aspectratio: 1/1, viewmode: 1, crop: function(e) { // output result data cropping image. // string data delimited / $('#lolo\\:hiddenb64').val(e.x + '/' + e.y + '/' + e.width + '/' + e.height); } }); //so image changes in cropper when new image picked reader.onload = function (e) { $imagecrop.cropper('replace',e.target.result); } crop image on java
public void pictest() { //getting coord. string data[] = rect.split("/"); try (inputstream in = new bytearrayinputstream(teamimg.getcontents())) { bufferedimage bimagefromconvert = imageio.read(in); // line under crops. it's possible there zoom figure out, didn't check yet. seemed correct on first , try. in case you'll figure out // surely parsing shouldn't here need sleep real bad. bufferedimage dest = bimagefromconvert.getsubimage((int)(double.parsedouble(data[0])), (int)(double.parsedouble(data[1])), (int)(double.parsedouble(data[2])), (int)(double.parsedouble(data[3]))); // path folder path folder = paths.get(dirs.getstring("imgteams")); string filename = "team_pic"; string extension = filenameutils.getextension(teamimg.getfilename()); path file = files.createtempfile(folder, filename + "-", "." + extension); imageio.write(dest, "jpeg", file.tofile()); } catch (exception e) { // todo auto-generated catch block e.printstacktrace(); }
Comments
Post a Comment