Save image after upload

Asked

Viewed 1,085 times

6

I am trying to save a cut image after the user uploads the image. The upload works well and I can save the image cropped too, but something strange is happening. The image is only cropped and saved if I place the image path directly in the component image attribute imageCropper, something like that:

<p:imageCropper value="#{imageCropperBean.croppedImage}" image="/imagens/prof/imageName.jpg" initialCoords="225,75,300,125" id="imageCropper"/>

If I try to get the name of the image(I get the name of the image when I upload) from mine Managed bean the imageCropper doesn’t work, something like that:

<p:imageCropper value="#{imageCropperBean.croppedImage}" image="/imagens/prof/#{imageCropperBean.currentImageName}" initialCoords="225,75,300,125" id="imageCropper"/>

Here is my code:

uploadImageCropper.xhtml

<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:h="http://xmlns.jcp.org/jsf/html"
  xmlns:p="http://primefaces.org/ui">
<h:head>
    <title>Image upload with crop</title>
</h:head>
<h:body>
    <h:form enctype="multipart/form-data">
        <p:fileUpload fileUploadListener="#{imageCropperBean.fileUploadAction}" update="imageCropper" />
        <h:panelGrid columns="2">  
            <p:imageCropper value="#{imageCropperBean.croppedImage}" image="/imagens/prof/#{imageCropperBean.currentImageName}" initialCoords="225,75,300,125" id="imageCropper"/>  
            <p:graphicImage id="localCroppedImage" value="/imagens/prof/#{imageCropperBean.newImageName}.jpg" />  
        </h:panelGrid>  
        <p:commandButton value="Crop" action="#{imageCropperBean.crop}" update="localCroppedImage"/>  
    </h:form> 
</h:body>

Imagecropperbean.java

@ManagedBean
@RequestScoped
public class ImageCropperBean {
private CroppedImage croppedImage;
private String currentImageName;
private String newImageName;

public ImageCropperBean() {
    setCurrentImageName("no_image.jpg");
    
}

public void fileUploadAction(FileUploadEvent event) {
    try {
        ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
        HttpServletResponse response = (HttpServletResponse) externalContext.getResponse();

        FacesContext aFacesContext = FacesContext.getCurrentInstance();
        ServletContext context = (ServletContext) aFacesContext.getExternalContext().getContext();

        String realPath = context.getRealPath("/");

        File file = new File(realPath + "/imagens/prof/");
        file.mkdirs();
        
        byte[] arquivo = event.getFile().getContents();
        String caminho = realPath + "/imagens/prof/" + event.getFile().getFileName();
        setCurrentImageName(event.getFile().getFileName());

        FileOutputStream fos = new FileOutputStream(caminho);
        fos.write(arquivo);
        fos.close();

    } catch (Exception ex) {
        System.out.println("Erro no upload de imagem" + ex);
    }
}   
public String crop() {
    if(croppedImage == null)
        return null;
    setNewImageName(getRandomImageName());
    ServletContext servletContext = (ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext();
    String newFileName = servletContext.getRealPath("") + File.separator + "imagens" + File.separator + "prof" + File.separator + getNewImageName() + ".jpg";

    FileImageOutputStream imageOutput;
    try {
        imageOutput = new FileImageOutputStream(new File(newFileName));
        imageOutput.write(croppedImage.getBytes(), 0, croppedImage.getBytes().length);
        imageOutput.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    return null;
}

public String getRandomImageName() {
    int i = (int) (Math.random() * 100000);

    return String.valueOf(i);
}
//getter and setters
}

2 answers

1

Vanilson, I know this question was asked over a month ago, but I decided to help people with the same problem.

The solution

Change the scope of @RequestScoped for @ViewScoped in the Managed bean and everything will work.

Explanation

Your code does the upload of the image in a request and an event ajax updates the imageCropper in another. When you update the imageCropper he tries to read the image property in a new request; in this new request the property currentImageName will have the value default (no_image.jpg) instead of the stored value in request previous by the method fileUploadAction. Using @ViewScoped the stored value will be kept between requests since there was no navigation between views.

Source: Response from Optimus.prime à that question in the Primefaces forum.

0

Caro @vanilson-Ourenco, the solution shown below is not exactly what you want because it runs on Client (Javascript) but maybe it solves your problem.

HTML

<img id="myImage" src="http://i.stack.imgur.com/HNvh8.jpg">
<script src="http://cdn.alloyui.com/2.0.0/aui/aui-min.js"></script>
<link href="http://cdn.alloyui.com/2.0.0/aui-css/css/bootstrap.min.css"
      rel="stylesheet"></link>

JS

var myCropper = {};
YUI().use('aui-image-cropper', function(Y) {
    myCropper = new Y.ImageCropper({
        cropHeight: 200,
        cropWidth: 200,
        srcNode: '#myImage',
        x: 50,
        y: 50
      }
    ).render();
  }
);
// seu código JS adicional

See the details of this Framework ALLOYUI that uses Yahoo’s YUI 3.

Image for testing: inserir a descrição da imagem aqui

Browser other questions tagged

You are not signed in. Login or sign up in order to post.