java - 如何使用 Vaadin 的上传方法读取图片?

标签 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:成为您自己的接收者接口(interface)

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();
    }
}

关于java - 如何使用 Vaadin 的上传方法读取图片?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61711647/

相关文章:

vaadin - Component.setVisible() 方法如何工作?

java - Vaadin 树形网格条件格式

java - 如何进行页面导航?

Java-Vaadin 如何设置变量包含任何类型的字段?

java - 将 TimeUnit 转换为 ChronoUnit?

Java 的属性 : differences between . propertyNames() 和 .stringPropertyNames()?

java - 在 JComboBox 中选择不同的选项时覆盖 JLabels?

java - 如何在JPA(Spring Data JPA)中实现简单的全文搜索?

java - 如何将 Vaadin 8 Grid 的高度设置为未定义?

java - xercesImpl.jar 在类路径上时 NetBeans Web 服务客户端出现问题