Primefaces image cropper croppedImage null

1.7k Views Asked by At

I am using imageCropper in a Java EE 7 , jsf2.2 application under wildfly 8.2.

<p:outputPanel id="cropDlg" rendered="#{profilePicController.fileUploaded}">
                    <h:form id="cropForm">

                        <p:messages/>
                        <p:panelGrid columns="3">
                            <p:row>
                                <p:column>

                                    <p:imageCropper value="#{profilePicController.croppedImage}"
                                                    image="/images?id=#{profilePicController.imageId}"
                                                    initialCoords="0,0,200,200"
                                            />


                                    <p:graphicImage id="cropped" value="/images?id=#{profilePicController.imageId}"/>
                                </p:column>
                                <p:column>
                                    <h:commandButton value="Crop" action="#{profilePicController.cropImage}">
                                        <f:ajax execute="@form" render="dlgContent"/>
                                    </h:commandButton>
                                </p:column>
                            </p:row>
                        </p:panelGrid>
                    </h:form>
                </p:outputPanel>

Now, the dialog box shows the image correctly, I can also resize the image but when I submit , the action method is not called, there are no validation errors shown. And if I write immediate="true" in the commandbutton, the action method is called but the croppedImage parameter is not set, it is null.

Note that the image comes from database with the help of an ImageServlet.

Just to give you the whole picture. This snippet is the part of a dialogbox which also uploads the image using h:inputFile jsf tag. The upload part works fine. The file is uploaded and saved in the db as byte[]. After upload is complete the flag is set and the cropping part is displayed.

Here the whole dialog box

<p:dialog id="imgUploadDlg" widgetVar="imgUpload" header="Upload file">
            <p:panel id="dlgContent">
                <p:outputPanel rendered="#{!profilePicController.fileUploaded}">
                    <h:form id="uploadForm" enctype="multipart/form-data">
                        <p:messages/>
                        <p:panelGrid columns="3">
                            <p:row>
                                <p:column>
                                    <h:outputText value="Upload File"/>
                                </p:column>
                                <p:column>
                                    <h:inputFile id="imageFile" value="#{profilePicController.imagePart}"/>
                                    <h:commandButton value="Upload" action="#{profilePicController.uploadFile}">
                                        <f:ajax execute="@form" render="dlgContent"/>
                                    </h:commandButton>
                                </p:column>
                                <p:column>
                                    <p:panel id="sampleImg">
                                        <ui:param name="servletPath"
                                                  value="/images?id=#{profilePicController.imageId}"/>
                                        <h:graphicImage
                                                value="#{profilePicController.foundProfileImage ? servletPath : '/resources/images/profilepic.png'}"/>
                                    </p:panel>
                                </p:column>
                            </p:row>
                        </p:panelGrid>
                    </h:form>
                </p:outputPanel>
                <p:outputPanel id="cropDlg" rendered="#{profilePicController.fileUploaded}">
                    <h:form id="cropForm">

                        <p:messages/>
                        <p:panelGrid columns="3">
                            <p:row>
                                <p:column>

                                    <p:imageCropper value="#{profilePicController.croppedImage}"
                                                    image="/images?id=#{profilePicController.imageId}"
                                                    initialCoords="0,0,200,200"
                                            />


                                    <p:graphicImage id="cropped" value="/images?id=#{profilePicController.imageId}"/>
                                </p:column>
                                <p:column>
                                    <h:commandButton value="Crop" action="#{profilePicController.cropImage}">
                                        <f:ajax execute="@form" render="dlgContent"/>
                                    </h:commandButton>
                                </p:column>
                            </p:row>
                        </p:panelGrid>
                    </h:form>
                </p:outputPanel>
            </p:panel>
        </p:dialog>

UPDATE-0

After debugging the ImageCropperRenderer::getConvertedValue method, I found following.

  1. The method is called on the second click and the first click has no effect whatsoever. I had to change the scope to sessionScope for debugging. I don't know why this happens and what happens on the first click of the button. Any fixes ?

  2. The ImageCropperRenderer is designed to handle images stored on the disk and not the dynamic images coming from a servlet. This means I will have to store the image on a temporary location for the image cropper to work. I may think about using jCrop instead. Any suggestions here ?

UPDATE-1

  1. The first issue mentioned above comes from the following bug https://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-790 I could fix this with a workaround in which I update the form on submit explicitly.

  2. Now only the 2nd issue remains, this means the image cropper of primefaces cannot work with dynamically loaded images (served by a servlet). Any ideas ? I am also open for alternatives like jCrop and would like to avoid saving the image on the disk.

1

There are 1 best solutions below

2
On BEST ANSWER

Finally I gave up on the primefaces Image Cropper and implemented the whole thing using jCrop (http://deepliquid.com/content/Jcrop.html) and Java 2d graphics to actually crop and resize the images. It is strange that for such a common usecase the JSF world has very few possibilities.

Note that all the problems were due to the fact that the upload and cropping was to be done in dialog box with ajax. For a non-ajax version the Image Cropper (primefaces) would have worked.