java - 如何使用 Vaadin 的上传方法读取图片?
问题描述
我创建了一个上传按钮,或者使用 Vaadin 14 上传按钮。就像一个魅力。完美的。但是如何访问我上传的图像?我试图阅读 Vaadin 网页上的教程,但它们只显示了我在下面发布的示例。不是如何访问图片。我想以矩阵形式获取所有像素并将它们全部转换为 0..255 灰度。
问题:
当我使用此代码上传或上传图片时,您知道使用什么方法获取图像吗?
@Data
public class PictureUpload {
private Upload upload;
public PictureUpload() {
// Add picture uploader
upload = new Upload();
addPictureUploader();
}
private void addPictureUploader() {
Div output = new Div();
MultiFileMemoryBuffer buffer = new MultiFileMemoryBuffer();
upload.setReceiver(buffer);
upload.setAcceptedFileTypes("image/jpeg", "image/png", "image/gif");
upload.addSucceededListener(event -> {
Component component = createComponent(event.getMIMEType(), event.getFileName(), buffer.getInputStream(event.getFileName()));
showOutput(event.getFileName(), component, output);
});
}
private Component createComponent(String mimeType, String fileName, InputStream stream) {
if (mimeType.startsWith("text")) {
return createTextComponent(stream);
} else if (mimeType.startsWith("image")) {
Image image = new Image();
try {
byte[] bytes = IOUtils.toByteArray(stream);
image.getElement().setAttribute("src", new StreamResource(fileName, () -> new ByteArrayInputStream(bytes)));
try (ImageInputStream in = ImageIO.createImageInputStream(new ByteArrayInputStream(bytes))) {
final Iterator<ImageReader> readers = ImageIO.getImageReaders(in);
if (readers.hasNext()) {
ImageReader reader = readers.next();
try {
reader.setInput(in);
image.setWidth(reader.getWidth(0) + "px");
image.setHeight(reader.getHeight(0) + "px");
} finally {
reader.dispose();
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
return image;
}
Div content = new Div();
String text = String.format("Mime type: '%s'\nSHA-256 hash: '%s'", mimeType, MessageDigestUtil.sha256(stream.toString()));
content.setText(text);
return content;
}
private Component createTextComponent(InputStream stream) {
String text;
try {
text = IOUtils.toString(stream, StandardCharsets.UTF_8);
} catch (IOException e) {
text = "exception reading stream";
}
return new Text(text);
}
private void showOutput(String text, Component content, HasComponents outputContainer) {
HtmlComponent p = new HtmlComponent(Tag.P);
p.getElement().setText(text);
outputContainer.add(p);
outputContainer.add(content);
}
}
更新:
我在评论中对 Lund 先生的示例代码进行了一些测试。似乎我无法使用此代码显示图片:
@Data
public class LoadExportTemplate {
private VerticalLayout subjectCounterExportButtonUploaders;
public LoadExportTemplate() {
subjectCounterExportButtonUploaders = new VerticalLayout();
Upload pictureUpload = new PictureUpload().getUpload();
Div output = new PictureUpload().getOutput();
subjectCounterExportButtonUploaders.add(pictureUpload, output);
}
}
我在哪里插入subjectCounterExportButtonUploaders
这个MainView
代码。我上传的时候看不到图片。
@Route("")
@Viewport("width=device-width, minimum-scale=1, initial-scale=1, user-scalable=yes, viewport-fit=cover")
@PreserveOnRefresh
public class MainView extends AppLayout {
/**
*
*/
private static final long serialVersionUID = 1L;
public MainView() {
// Get the components
VerticalLayout buildPredictValidateTemplate = new BuildPredictValidateTemplate().getBuildButtonPredictButtonValidateButtonTextArea();
VerticalLayout subjectCounterExportButtonUpload = new LoadExportTemplate().getSubjectCounterExportButtonUploaders();
// Create logo and drawer
Image barImage = new Image("img/barImage.png", "Fisherfaces Logo");
barImage.setHeight("55px");
addToNavbar(new DrawerToggle(), barImage);
// Create tabs and add listeners to them
Tab buildPredictValidate = new Tab("Build & Predict & Validate");
buildPredictValidate.getElement().addEventListener("click", e -> {
getContent().getChildren().forEach(component -> {
boolean visible = component.equals(buildPredictValidateTemplate);
component.setVisible(visible);
});
});
Tab loadExport = new Tab("Load & Export");
loadExport.getElement().addEventListener("click", e -> {
// Walk around from the bug
getContent().getChildren().forEach(component -> {
boolean visible = component.equals(subjectCounterExportButtonUpload);
component.setVisible(visible);
});
});
// Set the contents
setContent(new Div(buildPredictValidateTemplate, subjectCounterExportButtonUpload));
subjectCounterExportButtonUpload.setVisible(false);
// Add them and place them as vertical
Tabs tabs = new Tabs(buildPredictValidate, loadExport);
tabs.setOrientation(Tabs.Orientation.VERTICAL);
addToDrawer(tabs);
}
}
但是这个例子有效。在这里我可以在上传图片时看到它。
@Route(value = UploadView.ROUTE)
@PageTitle(UploadView.TITLE)
public class UploadView extends AppLayout{
/**
*
*/
private static final long serialVersionUID = 1L;
public static final String ROUTE = "upload";
public static final String TITLE = "Upload";
public UploadView() {
PictureUpload pictureUpload = new PictureUpload();
VerticalLayout vl = new VerticalLayout();
vl.add(pictureUpload.getUpload(),pictureUpload.getOutput());
setContent(vl);
}
}
你知道为什么吗?
解决方案
在评论中,您澄清说您想要的只是byte[]
在上传后获取图像。这是你可以做到的。
变体 1:MultiFileMemoryBuffer
MultiFileMemoryBuffer buffer = new MultiFileMemoryBuffer();
upload.setReceiver(buffer);
upload.setAcceptedFileTypes("image/jpeg", "image/png", "image/gif");
upload.addSucceededListener(event -> {
byte[] imageBytes = IOUtils.toByteArray(buffer.getInputStream(event.getFileName()));
});
变体2:成为您自己的Receiver
界面
public class UploadView implements Receiver {
private FastByteArrayOutputStream outputStream;
private Upload upload;
private Button actualUploadButton;
public UploadView(){
upload = new Upload(this);
upload.setAcceptedFileTypes("image/jpeg", "image/png", "image/gif");
upload.addSucceededListener(event -> {
// uploaded file is now in outputStream
byte[] newImageBytes = outputStream.toByteArray();
Notification.show("We have now got the uploaded images bytearray!");
});
upload.setMaxFiles(10);
actualUploadButton = new Button(getTranslation("upload-image"), VaadinIcon.UPLOAD.create());
actualUploadButton.setWidth("100%");
upload.setUploadButton(actualUploadButton);
add(upload);
}
@Override
public OutputStream receiveUpload(String s, String s1) {
return outputStream = new FastByteArrayOutputStream();
}
}
推荐阅读
- vue.js - [Vue warn] 的原因是什么:Invalid prop: custom validator check failed for prop "value"
- php - 使用 Laravel 默认身份验证验证登录中的其他用户字段
- php - 从下拉菜单中选择元素后,如何使元素出现?
- javascript - 更改克隆的 DOM 元素时 JS/jQuery 事件/数据丢失
- amazon-web-services - 使用 WAF 阻止垃圾邮件攻击
- html - HTML/CSS:获取
- react-native - React-Native 动画有一个小的停顿
- powershell - Powershell 中的 If/Else 帮助
- javascript - 在循环中将元素推入数组中,当我不推一个元素时,其余所有元素都显示为“未定义”
- jenkins - Jenkins 的 Subversion 提交后挂钩