Primefaces,p:imageCropper 上传后无法显示图片
Primefaces, p:imageCropper could not display image after upload
我的管理仪表板基于 spring 使用 JSF 2.2 + Primefaces 5.3 构建。
我正在开发用于创建新实体的表单,其工作方式如下:
- 用户填写所有输入字段并上传图片(使用
<p:fileUpload
)。
- 然后,
<p:imageCropper
应该刷新并显示上传的要裁剪的图像。
- 用户裁剪图像,然后按提交按钮创建新实体并将图像存储在磁盘上。
现在,我卡在了第 2 步。 <p:imageCropper
未显示上传的图像。
我怀疑是否可以从托管 bean 的 StreamedContent 对象获取图像到 <p:imageCropper
图像属性,例如 <p:graphicImage
?
所以,请告诉我如何解决它?
这是我的表格:
<h:form prependId="false" id="createForm" enctype="multipart/form-data">
<p:separator />
<p:growl id="messages" showDetail="true" />
<p:outputLabel value="Create card:" />
<h:panelGrid columns="2" cellpadding="5">
<p:outputLabel value="Fill in Name:" for="cardName" />
<p:inputText id="cardName" value="#{cardController.name}"
required="false" requiredMessage="Please, enter new card Name" />
<p:outputLabel value="Fill in Description:" for="cardDescription" />
<p:inputTextarea id="cardDescription" rows="3" cols="33"
value="#{cardController.description}" />
<p:outputLabel value="Upload image:" for="cardImage" />
<p:fileUpload id="cardImage"
fileUploadListener="#{cardController.handleFileUpload}"
auto="false"
mode="advanced" dragDropSupport="false" update="messages cropped uploaded"
sizeLimit="100000" fileLimit="3"
allowTypes="/(\.|\/)(gif|jpe?g|png)$/" />
<p:outputLabel value="change size of the image:" for="cropped" />
<p:imageCropper id="cropped" value="#{cropperView.croppedImage}" image="#{cardController.image}" initialCoords="225,75,300,125"/>
<p:graphicImage id = "uploaded" value="#{cardController.image}"/>
<p:commandButton value="Create"
action="#{categoryController.create()}"
update=" createForm" />
<p:message for="cardName" />
</h:panelGrid>
</h:form>
控制器:
@Controller
@Scope("session")
public class CardController {
private CroppedImage croppedImage;
private UploadedFile uploadedFile;
private String name;
private String description;
public void handleFileUpload(FileUploadEvent event) throws IOException {
System.out.println("!!! inside file upload");
FacesMessage message = new FacesMessage("Succesful", event.getFile().getFileName() + " is uploaded.");
FacesContext.getCurrentInstance().addMessage(null, message);
uploadedFile = event.getFile();
}
public StreamedContent getImage() {
FacesContext context = FacesContext.getCurrentInstance();
if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
// So, we're rendering the HTML. Return a stub StreamedContent so that it will generate right URL.
return new DefaultStreamedContent();
}
else {
// So, browser is requesting the image. Return a real StreamedContent with the image bytes.
return new DefaultStreamedContent(new ByteArrayInputStream(uploadedFile.getContents()));
}
}
public void create() {
// shoul be logic for creating new entities
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public CroppedImage getCroppedImage() {
return croppedImage;
}
public void setCroppedImage(CroppedImage croppedImage) {
this.croppedImage = croppedImage;
}
public UploadedFile getUploadedFile() {
return uploadedFile;
}
public void setUploadedFile(UploadedFile uploadedFile) {
this.uploadedFile = uploadedFile;
}
}
所以,我这样解决了我的问题:
- 上传图片后,将其存储在磁盘上的临时目录中。
- 更新
<p:imageCropper
所在的组件。 <p:imageCropper
的 image
属性应该等于上面创建的路径(例如:value="http://localhost:8080/temp/#{bean.imageName}")。请注意,磁盘上的那个目录应该对您的 Web 容器可见(我的应用程序构建在 Spring 引导上,因此它使用嵌入式 Tomcat。因此,我安装了额外的 apache 服务器并保存了我的图像那里)。
- 裁剪图像并将其存储在磁盘上。
这是一些代码:
<p:fileUpload id="cardImage"
fileUploadListener="#{cardController.handleFileUpload}"
auto="true" mode="advanced" dragDropSupport="true"
update="messages cropped cropButton" sizeLimit="5000000"
allowTypes="/(\.|\/)(gif|jpe?g|png)$/" />
<h:panelGrid columns="2" cellpadding="5" id="cropped">
<p:outputLabel value="Crop image:" for="cropper"
rendered="#{not empty cardController.imageFilePath}" />
<p:imageCropper id="cropper"
rendered="#{not empty cardController.imageFilePath}"
value="#{cardController.image}"
image="#{cardController.hostName}/#{cardController.imageFilePath}"
aspectRatio="1.0" initialCoords="225,75,300,125" minSize="210,210" />
<p:outputLabel value="Cropped image:" for="image"
rendered="#{not empty cardController.croppedImageFileName}" />
<p:graphicImage id="image"
rendered="#{not empty cardController.croppedImageFileName}"
value="#{cardController.hostName}/images/#{cardController.categoryId}/#{cardController.levelId}/#{cardController.croppedImageFileName}" />
<p:commandButton id="cropButton"
rendered="#{not empty cardController.uploadedFile}" value="Crop"
action="#{cardController.crop()}" update="messages cropped create"
icon="ui-icon-scissors" />
<p:commandButton value="Create" id="create"
rendered="#{not empty cardController.croppedImageFileName}"
action="#{cardController.create()}"
update=":cardForm:table createForm" />
<p:message for="cardName" />
</h:panelGrid>
控制器:
public void handleFileUpload(FileUploadEvent event) throws IOException {
uploadedFile = event.getFile();
File directory = new File(rootPath + TEMP_DIRECTORY);
directory.mkdirs();
String filename = FilenameUtils.getBaseName(UUID.randomUUID().toString());
String extension = FilenameUtils.getExtension(uploadedFile.getFileName());
Path file = Files.createTempFile(directory.toPath(), filename + "-", "." + extension);
Files.copy(uploadedFile.getInputstream(), file, StandardCopyOption.REPLACE_EXISTING);
imageFilePath = TEMP_DIRECTORY + "/" + file.getFileName().toString();
FacesMessage message = new FacesMessage("Succesful", imageFilePath + " is uploaded.");
FacesContext.getCurrentInstance().addMessage(null, message);
}
public void crop() throws IOException {
if (image == null) {
return;
}
String imageName = URLUtils.slugify(StringUtils.transliterateRu2En(name));
String croppedImagePath = IMAGES_ROOT_DIRECTORY + "/" + categoryId + "/" + levelId;
File directory = new File(rootPath + croppedImagePath);
directory.mkdirs();
String filename = FilenameUtils.getBaseName(imageName);
String extension = FilenameUtils.getExtension(image.getOriginalFilename());
Path file = Files.createTempFile(directory.toPath(), filename + "-", "." + extension);
InputStream is = new ByteArrayInputStream(image.getBytes());
Files.copy(is, file, StandardCopyOption.REPLACE_EXISTING);
croppedImageFileName = file.getFileName().toString();
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Success", "Cropping finished."));
}
我的管理仪表板基于 spring 使用 JSF 2.2 + Primefaces 5.3 构建。
我正在开发用于创建新实体的表单,其工作方式如下:
- 用户填写所有输入字段并上传图片(使用
<p:fileUpload
)。 - 然后,
<p:imageCropper
应该刷新并显示上传的要裁剪的图像。 - 用户裁剪图像,然后按提交按钮创建新实体并将图像存储在磁盘上。
现在,我卡在了第 2 步。 <p:imageCropper
未显示上传的图像。
我怀疑是否可以从托管 bean 的 StreamedContent 对象获取图像到 <p:imageCropper
图像属性,例如 <p:graphicImage
?
所以,请告诉我如何解决它?
这是我的表格:
<h:form prependId="false" id="createForm" enctype="multipart/form-data">
<p:separator />
<p:growl id="messages" showDetail="true" />
<p:outputLabel value="Create card:" />
<h:panelGrid columns="2" cellpadding="5">
<p:outputLabel value="Fill in Name:" for="cardName" />
<p:inputText id="cardName" value="#{cardController.name}"
required="false" requiredMessage="Please, enter new card Name" />
<p:outputLabel value="Fill in Description:" for="cardDescription" />
<p:inputTextarea id="cardDescription" rows="3" cols="33"
value="#{cardController.description}" />
<p:outputLabel value="Upload image:" for="cardImage" />
<p:fileUpload id="cardImage"
fileUploadListener="#{cardController.handleFileUpload}"
auto="false"
mode="advanced" dragDropSupport="false" update="messages cropped uploaded"
sizeLimit="100000" fileLimit="3"
allowTypes="/(\.|\/)(gif|jpe?g|png)$/" />
<p:outputLabel value="change size of the image:" for="cropped" />
<p:imageCropper id="cropped" value="#{cropperView.croppedImage}" image="#{cardController.image}" initialCoords="225,75,300,125"/>
<p:graphicImage id = "uploaded" value="#{cardController.image}"/>
<p:commandButton value="Create"
action="#{categoryController.create()}"
update=" createForm" />
<p:message for="cardName" />
</h:panelGrid>
</h:form>
控制器:
@Controller
@Scope("session")
public class CardController {
private CroppedImage croppedImage;
private UploadedFile uploadedFile;
private String name;
private String description;
public void handleFileUpload(FileUploadEvent event) throws IOException {
System.out.println("!!! inside file upload");
FacesMessage message = new FacesMessage("Succesful", event.getFile().getFileName() + " is uploaded.");
FacesContext.getCurrentInstance().addMessage(null, message);
uploadedFile = event.getFile();
}
public StreamedContent getImage() {
FacesContext context = FacesContext.getCurrentInstance();
if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
// So, we're rendering the HTML. Return a stub StreamedContent so that it will generate right URL.
return new DefaultStreamedContent();
}
else {
// So, browser is requesting the image. Return a real StreamedContent with the image bytes.
return new DefaultStreamedContent(new ByteArrayInputStream(uploadedFile.getContents()));
}
}
public void create() {
// shoul be logic for creating new entities
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public CroppedImage getCroppedImage() {
return croppedImage;
}
public void setCroppedImage(CroppedImage croppedImage) {
this.croppedImage = croppedImage;
}
public UploadedFile getUploadedFile() {
return uploadedFile;
}
public void setUploadedFile(UploadedFile uploadedFile) {
this.uploadedFile = uploadedFile;
}
}
所以,我这样解决了我的问题:
- 上传图片后,将其存储在磁盘上的临时目录中。
- 更新
<p:imageCropper
所在的组件。<p:imageCropper
的image
属性应该等于上面创建的路径(例如:value="http://localhost:8080/temp/#{bean.imageName}")。请注意,磁盘上的那个目录应该对您的 Web 容器可见(我的应用程序构建在 Spring 引导上,因此它使用嵌入式 Tomcat。因此,我安装了额外的 apache 服务器并保存了我的图像那里)。 - 裁剪图像并将其存储在磁盘上。
这是一些代码:
<p:fileUpload id="cardImage"
fileUploadListener="#{cardController.handleFileUpload}"
auto="true" mode="advanced" dragDropSupport="true"
update="messages cropped cropButton" sizeLimit="5000000"
allowTypes="/(\.|\/)(gif|jpe?g|png)$/" />
<h:panelGrid columns="2" cellpadding="5" id="cropped">
<p:outputLabel value="Crop image:" for="cropper"
rendered="#{not empty cardController.imageFilePath}" />
<p:imageCropper id="cropper"
rendered="#{not empty cardController.imageFilePath}"
value="#{cardController.image}"
image="#{cardController.hostName}/#{cardController.imageFilePath}"
aspectRatio="1.0" initialCoords="225,75,300,125" minSize="210,210" />
<p:outputLabel value="Cropped image:" for="image"
rendered="#{not empty cardController.croppedImageFileName}" />
<p:graphicImage id="image"
rendered="#{not empty cardController.croppedImageFileName}"
value="#{cardController.hostName}/images/#{cardController.categoryId}/#{cardController.levelId}/#{cardController.croppedImageFileName}" />
<p:commandButton id="cropButton"
rendered="#{not empty cardController.uploadedFile}" value="Crop"
action="#{cardController.crop()}" update="messages cropped create"
icon="ui-icon-scissors" />
<p:commandButton value="Create" id="create"
rendered="#{not empty cardController.croppedImageFileName}"
action="#{cardController.create()}"
update=":cardForm:table createForm" />
<p:message for="cardName" />
</h:panelGrid>
控制器:
public void handleFileUpload(FileUploadEvent event) throws IOException {
uploadedFile = event.getFile();
File directory = new File(rootPath + TEMP_DIRECTORY);
directory.mkdirs();
String filename = FilenameUtils.getBaseName(UUID.randomUUID().toString());
String extension = FilenameUtils.getExtension(uploadedFile.getFileName());
Path file = Files.createTempFile(directory.toPath(), filename + "-", "." + extension);
Files.copy(uploadedFile.getInputstream(), file, StandardCopyOption.REPLACE_EXISTING);
imageFilePath = TEMP_DIRECTORY + "/" + file.getFileName().toString();
FacesMessage message = new FacesMessage("Succesful", imageFilePath + " is uploaded.");
FacesContext.getCurrentInstance().addMessage(null, message);
}
public void crop() throws IOException {
if (image == null) {
return;
}
String imageName = URLUtils.slugify(StringUtils.transliterateRu2En(name));
String croppedImagePath = IMAGES_ROOT_DIRECTORY + "/" + categoryId + "/" + levelId;
File directory = new File(rootPath + croppedImagePath);
directory.mkdirs();
String filename = FilenameUtils.getBaseName(imageName);
String extension = FilenameUtils.getExtension(image.getOriginalFilename());
Path file = Files.createTempFile(directory.toPath(), filename + "-", "." + extension);
InputStream is = new ByteArrayInputStream(image.getBytes());
Files.copy(is, file, StandardCopyOption.REPLACE_EXISTING);
croppedImageFileName = file.getFileName().toString();
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Success", "Cropping finished."));
}