Primefaces 图像裁剪器 croppedImage null
Primefaces image cropper croppedImage null
我在 Java EE 7 中使用 imageCropper,wildfly 8.2 下的 jsf2.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>
现在,对话框正确显示了图像,我也可以调整图像的大小,但是当我提交时,没有调用操作方法,也没有显示任何验证错误。如果我在 commandbutton 中写入 immediate="true",则会调用 action 方法但未设置 croppedImage 参数,它为 null。
请注意,图像在 ImageServlet 的帮助下来自数据库。
只是为了给你全貌。此片段是对话框的一部分,该对话框还使用 h:inputFile jsf 标记上传图像。上传部分工作正常。该文件被上传并作为字节 [] 保存在数据库中。上传完成后设置标志并显示裁剪部分。
这里是整个对话框
<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
调试ImageCropperRenderer::getConvertedValue方法后,发现如下。
该方法在第二次点击时调用,第一次点击没有任何效果。我不得不将范围更改为 sessionScope 以进行调试。我不知道为什么会这样,也不知道第一次点击按钮时会发生什么。任何修复?
ImageCropperRenderer 旨在处理存储在磁盘上的图像,而不是来自 servlet 的动态图像。这意味着我必须将图像存储在临时位置,图像裁剪器才能工作。我可能会考虑改用 jCrop。这里有什么建议吗?
UPDATE-1
上面提到的第一个问题来自以下bug
https://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-790
我可以通过一种变通方法解决此问题,在该变通方法中我明确地更新提交时的表单。
现在只剩下第二个问题,这意味着 primefaces 的图像裁剪器无法处理动态加载的图像(由 servlet 提供)。有任何想法吗 ?我也对 jCrop 等替代方案持开放态度,并希望避免将图像保存在磁盘上。
最后我放弃了 primefaces Image Cropper 并使用 jCrop (http://deepliquid.com/content/Jcrop.html) 和 Java 2d 图形实现了整个过程,以实际裁剪和调整图像大小。奇怪的是,对于这样一个常见的用例,JSF 世界几乎没有任何可能性。
请注意,所有问题都是由于上传和裁剪是在 ajax 的对话框中完成的。对于非 ajax 版本,Image Cropper (primefaces) 会起作用。
我在 Java EE 7 中使用 imageCropper,wildfly 8.2 下的 jsf2.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>
现在,对话框正确显示了图像,我也可以调整图像的大小,但是当我提交时,没有调用操作方法,也没有显示任何验证错误。如果我在 commandbutton 中写入 immediate="true",则会调用 action 方法但未设置 croppedImage 参数,它为 null。
请注意,图像在 ImageServlet 的帮助下来自数据库。
只是为了给你全貌。此片段是对话框的一部分,该对话框还使用 h:inputFile jsf 标记上传图像。上传部分工作正常。该文件被上传并作为字节 [] 保存在数据库中。上传完成后设置标志并显示裁剪部分。
这里是整个对话框
<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
调试ImageCropperRenderer::getConvertedValue方法后,发现如下。
该方法在第二次点击时调用,第一次点击没有任何效果。我不得不将范围更改为 sessionScope 以进行调试。我不知道为什么会这样,也不知道第一次点击按钮时会发生什么。任何修复?
ImageCropperRenderer 旨在处理存储在磁盘上的图像,而不是来自 servlet 的动态图像。这意味着我必须将图像存储在临时位置,图像裁剪器才能工作。我可能会考虑改用 jCrop。这里有什么建议吗?
UPDATE-1
上面提到的第一个问题来自以下bug https://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-790 我可以通过一种变通方法解决此问题,在该变通方法中我明确地更新提交时的表单。
现在只剩下第二个问题,这意味着 primefaces 的图像裁剪器无法处理动态加载的图像(由 servlet 提供)。有任何想法吗 ?我也对 jCrop 等替代方案持开放态度,并希望避免将图像保存在磁盘上。
最后我放弃了 primefaces Image Cropper 并使用 jCrop (http://deepliquid.com/content/Jcrop.html) 和 Java 2d 图形实现了整个过程,以实际裁剪和调整图像大小。奇怪的是,对于这样一个常见的用例,JSF 世界几乎没有任何可能性。
请注意,所有问题都是由于上传和裁剪是在 ajax 的对话框中完成的。对于非 ajax 版本,Image Cropper (primefaces) 会起作用。