如何在HTML页面中显示来自外部文件夹的图像

时间:2019-02-03 14:07:18

标签: spring thymeleaf

我工作的一个项目,以获得从视频缩略图,然后在主页上显示它们。

缩略图是在文件夹上传中正确生成的,但是未显示在主页中。我找不到错误404。

Bellow是JeutrollServiceImp的代码,用于从视频中获取缩略图 在HTML中,我使用的图象的一硬编码名称为测试的purprose。

import com.jeutroll.dao.UserRepository;
import com.jeutroll.dao.VideoRepository;
import com.jeutroll.entities.Video;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.Java2DFrameConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
@Service
@Transactional
public class JeutrollServiceImp implements JeutrollService
{
    public static String uploadDirectory= System.getProperty("user.home") + "/uploads";
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private VideoRepository videoRepository;


    @Override
    public Page<Video> browseVideos(String aInCategory, int page, int size)
    {
        return videoRepository.listVideos(aInCategory, new PageRequest(page, size));
    }

    @Override
    public Video browseVideo(String aTitle)
    {

        return null;
    }

    @Override
    public void uploadVideo(Video aInVideo)
    {

    }

    @Override
    public com.jeutroll.entities.User findUserByEmail(String email)
    {
        return userRepository.findByEmail(email);
    }

    @Override
    public String retriveThumbnailFromVideo(String videoPath)
    {
        String thumbnailPath;
        File lImgFile = null;
        FFmpegFrameGrabber g = new FFmpegFrameGrabber(videoPath);
        try
        {
            g.start();
            // on fait défiler les 10 premières frame
            for (int i = 0; i < 100; i++)
            {
                g.grab();

            }

            Frame lFrame = g.grabImage();
            BufferedImage lBufferedImage = new Java2DFrameConverter().convert(lFrame);
            // on enregistre la 101ième
            Path path = Paths.get(uploadDirectory,"life_" + System.currentTimeMillis() + ".png" );
            //lImgFile = new File("/resources/static/life_" + System.currentTimeMillis() + ".png");
            lImgFile = new File(path.toString());

            ImageIO.write(lBufferedImage, "png", lImgFile);

            // récupération de la durée de la vidéo
            float duration = (float) g.getLengthInTime() / 1000000;

            g.stop();
        }
        catch (Exception e)
        {
            // TODO Auto-generated catch block
            System.err
                    .println("La création de la miniature n'a pas pu être effectuée!");
            e.printStackTrace();
        }
        return lImgFile.getName();
    }

    @Override
    public void uploadVideos(String aInFilePath)
    {
        //        storageService.store(file);
    }
}

WebConfigurer类别

package com.jeutroll.configuration;

import com.jeutroll.service.JeutrollServiceImp;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

public class WebConfigurer extends WebMvcConfigurerAdapter {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/uploads/**").addResourceLocations("file:/" + JeutrollServiceImp.uploadDirectory);
    }

} 

这里我使用的是磁盘上外部文件夹中已经存在的视频。

 <!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
      layout:decorator="template1.html">
<head>
    <meta charset="UTF-8">
    <title>Jeutroll</title>
</head>
<body>
<div layout:fragment="content">
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-md-offset-2 text-center">
                <h2 class="section-title uppercase"> Projets Réalisés</h2>
            </div>
        </div>
        <section class="row" th:if="${videos}">
            <div class="col-xs-12 col-sm-3 col-md-4 col-lg-4" th:each="v:${videos}">
                <a href="#" class="thumbnail"><img src="/uploads/life_1549107645227.png" alt="Image 2" width="500px " >
                    <div class="caption">
                        <span class="cat-link">categorie</span>
                        <span class="separator">|</span>
                        <span class="pub-date">6 janvier 2019</span>
                        <span class="glyphicon glyphicon-comment"></span>
                    </div>
                    <div class="rating">

                    </div>
                </a>
            </div>
        </section>
    </div>
</div>
</body>
</html>

2 个答案:

答案 0 :(得分:0)

在这个问题上停留了几个小时之后,我终于弄明白了。主要问题是我没有在WebConfigurer类中添加@EnableWebMvc。第二个是映像目录不正确。我正在Windows OS上执行我的项目,并且使用了System.getProperty(“ user.home”)+“ / uploads”;代替 System.getProperty(“ user.home”)+“ \ uploads”;

因为它是经常性的主题。我决定为这种情况写一个例子。我回家会有所帮助。 http://mkaroune.e-monsite.com/pages/spring/get-images-from-external-folder-on-disk.html

@Ahmed是,该方法返回正确的图像路径。

答案 1 :(得分:0)

我建议您看看Spring Content。通过该社区项目,您可以使用相同的编程模型将内容(例如视频之类的非结构化数据)与Spring数据实体相关联。

添加到现有项目中非常简单,它会为您提供与Spring Data相同的简单编程模型,存储的抽象(因此它可以存储在Spring Content支持的任何Storage中)以及许多其他功能具有OOTB之类的功能,例如支持视频流的REST端点。

如果您对这里感兴趣的话,我想您可以这样做(假设使用Spring Boot)。

将依赖项添加到您的项目中:-

  

pom.xml

    <!-- Java API --> 
    <dependency>
        <groupId>com.github.paulcwarren</groupId>
        <artifactId>spring-content-fs-boot-starter</artifactId>
        <version>0.5.0</version>
    </dependency>
    <!-- REST API --> 
    <dependency>
        <groupId>com.github.paulcwarren</groupId>
        <artifactId>spring-content-rest-boot-starter</artifactId>
        <version>0.5.0</version>
    </dependency>

配置文件存储:

  

StoreConfig.java

@Configuration
@EnableFilesystemStores
public class EnableFilesystemStoresConfig {

    @Bean
    File filesystemRoot() {
        try {
            return new File(JeutrollServiceImp.uploadDirectory);
        } catch (IOException ioe) {}
        return null;
    }

    @Bean
    FileSystemResourceLoader fileSystemResourceLoader() {
        return new FileSystemResourceLoader(filesystemRoot().getAbsolutePath());
    }

}

将内容与您的实体相关联:

    @Entity
    public class Video {
      @Id @GeneratedValue
      private Long id;
      ... other Spring Data fields ...

      // associate the video
      @ContentId
      private UUID contentId;

      @ContentLength
      private Long contentLength;

      @Mimetype
      private String mimeType;

      // associate thumbnails
      private Thumbnail thumbnail;
      ...
   }

   @Entity
   public class Thumbnail {
      @ContentId 
      private UUID contentId;

      @ContentLength 
      private Long contentLength;

      @MimeType 
      private String mimeType;
   }

创建视频存储和缩略图存储:

  

VideoStore.java/ThumbnailStore.java

  @StoreRestResource(path="videoContent")
  public interface VideoStore extends ContentStore<Video,UUID> {
  }

  public interface ThumbnailStore extends ContentStore<Thumbnail,UUID> {
  }

spring-content-fs-boot-starter依赖项将导致Spring Content注入基于文件系统的实现,因此您无需担心自己实现这些。而且,spring-content-rest依赖关系将导致Spring Content也注入@Controller的实现,这些实现分别将HTTP请求转发到VideoStoreThumbnailStore的方法上。

因此,您现在可以在/videoContent处使用基于REST的全功能(POST,PUT,GET,DELETE)视频服务,该服务将使用您的VideoStore来检索(和存储){{ 1}}在您的服务器上。

所以:

JeutrollServiceImp.uploadDirectory

将上传POST /videoContent/ -F "image=@/some/path/to/a/video.mp4"并将其添加到您的上传目录中。

video.mp4

将再次获取它并存储其余端点支持Range请求,因此HTML5视频控件将正常运行。

对于缩略图,您可以添加处理以生成缩略图并将其存储在带注释的存储事件处理程序中:-

GET /videoContent/{videoId}

每个视频存储后,其缩略图将通过以下方式提供:

@Configuration public class ThumbnailConfig { @Bean public StoreEventHandler thumbnailEventHandler() { return new ThumbnailEventHandler(); } @StoreEventHandler public static class ThumbnailEventHandler { @Autowired VideoRepository videoRepository; @Autowired VideoStore videoStore; @Autowired ThumbnailStore thumnailStore; @HandleAfterSetContent public void handleAfterSetContent(Video video) { BufferedImage img = // use modfied retrieveThumbnailFromVideo(videoStore.getContent(video)); Thumbnail thumbnail = new Thumbnail(); thumbnail.setMimeType("png") thumbnail.setContent(thumbnail, toInputStream(img)) video.setThumbnail(thumbnail) videoRepository.save(video); } } }

或:

GET /videoContent/{videoId}/thumbnail

在存储模仿类型时,这些URL将在您HTML的标准中用作GET /videoContent/{videoId}/thumbnail/{contentId}

所以:

成为:

HTH