裁剪图像并将其发送到jsf bean,无需进行不必要的数据传输

问题描述 投票:1回答:1

我想将由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 &amp;&amp; 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");
}
jsf primefaces
1个回答
2
投票

尽管可以在线上找到一些误导性的答案,但是一旦理解了该过程,实际上就非常简单。我希望这会在将来对某人有所帮助。

我使用的技术是:

  1. [选择图像

  2. 一旦拾取图像,将其显示在裁切器中,而无需通过电线发送。

  3. 这里有几个选项,我选择了:当用户移动裁切器矩形时,矩形的坐标填充一个隐藏的输入字段。

  4. 将坐标发送到bean并在服务器端进行裁剪。

    之所以这样,是因为我想使用的裁切器jquery lib并没有将图像转换为以64为底,而是给出了矩形的坐标。但是,如果有人希望将来直接发送裁剪后的图像,我认为这真的很容易。就像我所做的一样,只是您必须将裁剪后的图像作为字符串基础64放置在隐藏的输入文本中(而不是矩形坐标-在下面进行解释),然后将其转换回服务器端,仅此而已。 (但是,我不知道效率/安全性如何)。至少这解决了我的素数问题,即不想多次通过网络发送不必要的数据。

1。首先,让我们显示图像而不将其发送到服务器。

[此时显示图像时,如果检查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 &amp;&amp; input.files[0]) {
            reader.readAsDataURL(input.files[0]);      
        }
    }

    $("#lolo\\:imgInp").change(function(){
        readURL(this);
    });
</script>
  1. 一旦完成,它就会变得有点取决于所使用的jQuery裁剪库。我使用了cropper lib。有了这个,我们希望获得裁剪矩形的坐标。通过坐标数据,我们填充了一个隐藏的输入,并将其发送回Bean,然后在Java端将其重新生成。

或者,更好的解决方案(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);  
    }

我们使用Java裁剪图像

   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();
    }
© www.soinside.com 2019 - 2024. All rights reserved.