我想将由jquery裁剪器生成的图像上传到bean字段。
我找到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>
它不上传就显示图像,但无法在裁切器中获得它。因此,我使用了一个jQuery裁剪器,但是随后我不确定如何在bean中获取它(无需通过servlet,因为它不是一次性使用的)。换句话说,我需要通过ajax将img发送到Bean。
否则,我将使用素面,但是如果可能的话,它必须穿过导线。从示例中,我已经看到图像是服务器上的静态内容。我真的必须将图像保存在服务器上吗?我不能将其保留为对象并将UploadedFile
转换为裁剪机将接受的内容吗?
类似这样的声音:
<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");
}
尽管可以在线上找到一些误导性的答案,但是一旦理解了该过程,实际上就非常简单。我希望这会在将来对某人有所帮助。
我使用的技术是:
[选择图像
一旦拾取图像,将其显示在裁切器中,而无需通过电线发送。
这里有几个选项,我选择了:当用户移动裁切器矩形时,矩形的坐标填充一个隐藏的输入字段。
将坐标发送到bean并在服务器端进行裁剪。
之所以这样,是因为我想使用的裁切器jquery lib并没有将图像转换为以64为底,而是给出了矩形的坐标。但是,如果有人希望将来直接发送裁剪后的图像,我认为这真的很容易。就像我所做的一样,只是您必须将裁剪后的图像作为字符串基础64放置在隐藏的输入文本中(而不是矩形坐标-在下面进行解释),然后将其转换回服务器端,仅此而已。 (但是,我不知道效率/安全性如何)。至少这解决了我的素数问题,即不想多次通过网络发送不必要的数据。
[此时显示图像时,如果检查img的src标记,您将看到它是图像的数据,以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>
或者,更好的解决方案(imo)是使用裁剪图像的库并将数据客户端作为基数64,填充一个隐藏字段并将其发送回Bean,然后将基数64转换为图像。每个步骤都很简单,可以在stackoverflow上找到。
因为我想使用裁剪器库,所以我采用了第一种方法:
这被添加到表格中:
<h:inputHidden value="#{adminCreateTeam.rect}"/>
<p:commandButton value="submit" action="#{adminCreateTeam.picTest}" ajax="false"/>
这是更新的onload:
// with this the hidden field is gonna be populated by the
// cropping rectangle data.
var $imageCrop = $('#blah').cropper({
aspectRatio: 1/1,
viewMode: 1,
crop: function(e) {
// Output the result data for cropping image.
// string with all the data delimited by /
$('#lolo\\:hiddenB64').val(e.x + '/' + e.y + '/' + e.width + '/' + e.height);
}
});
//So the image changes in the cropper when a new image is picked
reader.onload = function (e) {
$imageCrop.cropper('replace',e.target.result);
}
public void picTest() {
//getting coord.
String data[] = rect.split("/");
try (InputStream in = new ByteArrayInputStream(teamImg.getContents())) {
BufferedImage bImageFromConvert = ImageIO.read(in);
// line under this crops. It's possible there is a zoom to figure out, I didn't check yet. Seemed correct on first and only try. In any case you'll figure it out
// surely the parsing shouldn't be here but I need to 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 to the 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();
}