【问题标题】:How to display a BufferedImage in Thymeleaf如何在 Thymeleaf 中显示 BufferedImage
【发布时间】:2022-09-23 18:25:36
【问题描述】:

我目前正在尝试通过为流行的纸牌游戏 Magic the Gathering 编写一个简单的桌面模拟器来自学 Spring Boot。所以我首先要做的是从 Scryfall API 中检索卡片图像并将它们显示在 Thymeleaf 中。我知道如何对静态图像执行此操作,但我似乎无法找到一种方法来显示动态检索的图像。我目前的解决方法是为 Thymeleaf 提供 Scryfall URI,但我真正想做的是在 Thymeleaf 中显示一个 BufferedImage。所以这里是我当前的控制器代码。

package mtg;

import java.util.Map;

import org.springframework.boot.json.BasicJsonParser;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

@Controller
@RequestMapping(\"/sample\")
public class SampleCardController {

@ModelAttribute
public void addCardToModel(Model model) {
    RestTemplate rest = new RestTemplate();
    String jsonString = rest.getForObject(
            \"https://api.scryfall.com/cards/random\", String.class);
    BasicJsonParser parser = new BasicJsonParser();
    Map<String, Object> map = parser.parseMap(jsonString);
    String name = (String) map.get(\"name\");
    String uri = (String) map.get(\"uri\");
    model.addAttribute(\"cardName\", name);
    model.addAttribute(\"imageURI\", uri + \"?format=image\");
}

@GetMapping
public String showSampleCard() {
    return \"sample\";
}
}

这是 Thymeleaf 模板sample.html

<!DOCTYPE html>
<html xmlns=\"http://www.w3.org/1999/xhtml\"
      xmlns:th=\"http://www.thymeleaf.org\">
  <head>
    <title>Sample</title>
  </head>
  <body>
    <h1>Here\'s a sample card!</h1>
    <h3 th:text=\"${cardName}\"></h3>
    <img th:src=\"${imageURI}\"/>
  </body>
</html>

我真正想在控制器中做的是这样的:

package mtg;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;

import javax.imageio.ImageIO;

import org.springframework.boot.json.BasicJsonParser;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

@Controller
@RequestMapping(\"/sample\")
public class SampleCardController2 {

    @ModelAttribute
    public void addCardToModel(Model model) {
        RestTemplate rest = new RestTemplate();
        String jsonString = rest.getForObject(
                \"https://api.scryfall.com/cards/random\", String.class);
        BasicJsonParser parser = new BasicJsonParser();
        Map<String, Object> map = parser.parseMap(jsonString);
        String name = (String) map.get(\"name\");
        String imageURI = (String) map.get(\"uri\");
        BufferedImage image = null;
        try {
            image = ImageIO.read(new URL(imageURI + \"?format=image\"));
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        model.addAttribute(\"cardName\", name);
        model.addAttribute(\"image\", image);
    }

    @GetMapping
    public String showSampleCard() {
        return \"sample\";
    }

}

但我不知道如何让 Thymeleaf 显示图像。似乎对于 img 标签`您只能提供需要 URL 的 th:src 属性。对于可以使用模型属性名称的图像,是否有类似于 th:text=\"${cardName}\" 的内容?

编辑:请参阅下面的@Lee Greiner 评论以了解如何修复模板。

    标签: java spring spring-boot image thymeleaf


    【解决方案1】:

    您可以在 img 标记中插入多个 URL。在这种情况下,您可以通过执行以下操作插入正在加载的图像的 base64 表示:

    <div>
      <p>Taken from wikpedia</p>
      <img src="data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAAAUA
        AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
            9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Red dot" />
    </div>
    

    从您的代码中,从 BefferedImage 对象中获取 base64,如下所示:

    public static String imgToBase64String(final RenderedImage img, final String formatName)
    {
      final ByteArrayOutputStream os = new ByteArrayOutputStream();
    
      try
      {
        ImageIO.write(img, formatName, os);
        return Base64.getEncoder().encodeToString(os.toByteArray());
      }
      catch (final IOException ioe)
      {
        throw new UncheckedIOException(ioe);
      }
    }
    

    并将其传递给视图。

    链接 IMG tag base64 src

    BufferedImage to base64

    【讨论】:

    • 好的,也许我遗漏了一些东西,但是在您提供的 html 中,src 标记似乎包含图像作为一种字符串文字。如何将imgToBase64String 方法的返回值放入 src 标签中?
    • 正如你现在正在做的那样,在addCardToModel() 方法中,当你在做model.addAttribute("imageURI", uri + "?format=image"); 时,你不是发送uri,而是发送imgToBase64String 返回的值
    • 好的,所以如果我将返回值放在一个变量中,例如String imageString,然后我做model.addAttribute("imageString", imageString); 然后我在模板中写&lt;img src="data:image/png;base64, ${imageString}" /&gt;
    • 正是这样,它应该工作。
    • 我试过了,但我得到了org.thymeleaf.TemplateEngine : [THYMELEAF][http-nio-8080-exec-1] Exception processing template "sample": An error happened during template parsing (template: "class path resource [templates/sample.html]")。这是模板中的行:&lt;img th:src="data:image/png;base64, ${imageString}"/&gt;
    猜你喜欢
    • 2010-12-10
    • 1970-01-01
    • 1970-01-01
    • 2020-06-17
    • 1970-01-01
    • 1970-01-01
    • 2018-11-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多