我目前正在尝试自学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的评论。
您可以在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