提问者:小点点

如何在Thymeleaf中显示BufferedImage


我目前正在尝试自学Spring Boot,为流行的纸牌游戏Magic the Ga的桌面模拟器编写一个简单的桌面模拟器。所以我想做的第一件事是从ScryfallAPI中检索纸牌图像并将它们显示在Thymeleaf中。我知道如何为静态图像做到这一点,但我似乎找不到一种方法来显示动态检索的图像。我目前的解决方法是为Thymeleaf提供ScryfallURI,但我真正想做的是在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的评论。


共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标签base64 src

BufferedImage到base64