Javier Vallori Amoros
Javier Vallori Amoros

Reputation: 13

Upload a cropped image in GWT

I'm developing a web application where user selects an image, cropps it and finally uploads it to the server. So with a FileUpload widget, I allow the user to select the image source, getting its path and with the constructor

Image(java.lang.String url, int left, int top, int width, int height);

I get the cropped image object.

But now, I don't know how to upload to the server the image. Does anybody know a solution?

Upvotes: 1

Views: 886

Answers (1)

amaurs
amaurs

Reputation: 1642

You can find a good example on how to upload files to the server here.

EDIT

What you need to do is to upload the image to the server, retrieve it in the client, do the cropping visually in the client, send the cropping parameters to the server, and finally doing the actual cropping in the server. This is how I manage to do it starting from the project mentioned above:

vPanel.add(new Button("Submit", new ClickHandler() {
    public void onClick(ClickEvent event) {
           form.submit();
    }
}));

once the user selects an image, we upload it with the FileUpload, and in the server we save it in a directory:

List<FileItem> items = fileUpload.parseRequest(request);
Iterator<FileItem> iter = items.iterator();
while (iter.hasNext()) {
    FileItem item = (FileItem) iter.next();    
    File file = new File(<images-path>,fileName);
    Streams.copy(item.getInputStream(),new FileOutputStream(file), true);        
}

we need to have a service to retrieve the uploaded image so we add a servlet that takes a get method and returns an image:

protected void doGet(HttpServletRequest req,
        HttpServletResponse resp) throws ServletException,
        IOException
{
    resp.setContentType("image/jpeg");
    ServletOutputStream out = resp.getOutputStream();
    BufferedInputStream  bis= new BufferedInputStream(new FileInputStream(<images-path>+req.getParameter("name")));
    BufferedOutputStream bos = new BufferedOutputStream(resp.getOutputStream());
    int ch;
    while((ch=bis.read())!=-1)
    {
        bos.write(ch);
    }
    bis.close();
    bos.flush();
    bos.close();
    out.close();
}

back in the client when the upload has been completed, we want to retrieve a copy of the uploaded image so we add a form submit handler. I am using this gwt cropping library for the visual step:

form.addSubmitCompleteHandler(new FormPanel.SubmitCompleteHandler()
{
    public void onSubmitComplete(SubmitCompleteEvent event)
    {
        Element label = DOM.createLabel();
        label.setInnerHTML(event.getResults());
        String result = label.getInnerText(); // result contains the name of the image in the server
        final GWTCropper crop = new GWTCropper(GWT.getModuleBaseURL()+"image?name="+result);
        crop.setAspectRatio(1);
        vPanel.add(crop);
    }
}

now we have to add a cropping service that lets the actual cropping to happen in the server I use a RCP service to do it:

public class CropServiceImpl extends RemoteServiceServlet implements CropService {
    public Boolean crop(String name, int x, int y, int width, int height)
    {
        try
        {
            BufferedImage outImage = ImageIO.read(new File("<images-path>"+name));
            BufferedImage cropped = outImage.getSubimage(x, y, width, height);
            ImageIO.write(cropped, "jpg", new File("<images-path>","cropped"+name));
            return true;
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        return false;
    }
}

finally, back in the client, we call the method inside a button action with the parameters that we get from the cropping:

vPanel.add(new Button("Crop", new ClickHandler()
{
    public void onClick(ClickEvent event)
    {
        cropService.crop(getName(), (int) crop.getSelectionXCoordinate(),
                (int) crop.getSelectionYCoordinate(), (int) crop.getSelectionWidth(),
                (int) crop.getSelectionHeight(), new AsyncCallback<Boolean>()
                {
                    public void onFailure(Throwable arg0)
                    {
                        // something went wrong with the call
                    }
                    public void onSuccess(Boolean arg0)
                    {
                    if (arg0)
                        {
                            // the cropped file now lives in the server
                        }
                        else
                        {
                            // an error happened in the server
                        }
                    }
                });
    }
}));

and there you go, sorry for the long post, hope it helps.

Upvotes: 4

Related Questions