如何使用Twelve Monkeys库读取JPEG文件中的多条路径?
从JPEG中提取多条路径(TwelveMonkeys + ImageMagick相关)
你当前用Paths.readPath(stream)只能拿到第一条路径,是因为这个方法默认只读取JPEG中第一个符合条件的8BIM路径元数据块。要获取所有路径,需要手动遍历JPEG的元数据,找出所有标记为8BIM:1999,2998的元数据条目,逐个解析成Shape。
用TwelveMonkeys实现多路径提取
以下是具体代码示例,通过ImageIO的元数据API遍历所有路径块:
import com.twelvemonkeys.imageio.path.Paths; import javax.imageio.ImageIO; import javax.imageio.ImageReader; import javax.imageio.metadata.IIOMetadata; import javax.imageio.metadata.IIOMetadataNode; import javax.imageio.stream.ImageInputStream; import java.io.FileInputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.awt.Shape; public class JpegPathExtractor { public static void main(String[] args) throws IOException { try (ImageInputStream stream = ImageIO.createImageInputStream(new FileInputStream("your-image.jpg"))) { ImageReader reader = ImageIO.getImageReaders(stream).next(); reader.setInput(stream); // 获取JPEG的元数据 IIOMetadata metadata = reader.getImageMetadata(0); String format = metadata.getNativeMetadataFormatName(); IIOMetadataNode root = (IIOMetadataNode) metadata.getAsTree(format); // 遍历所有8BIM元数据节点 List<Shape> allPaths = new ArrayList<>(); for (int i = 0; i < root.getLength(); i++) { IIOMetadataNode node = (IIOMetadataNode) root.item(i); if ("app13".equals(node.getNodeName())) { // 8BIM数据在APP13段 IIOMetadataNode params = (IIOMetadataNode) node.getElementsByTagName("Photoshop").item(0); if (params != null) { for (int j = 0; j < params.getLength(); j++) { IIOMetadataNode entry = (IIOMetadataNode) params.item(j); // 匹配1999,2998标记的路径条目 if ("1999".equals(entry.getAttribute("tag")) && "2998".equals(entry.getAttribute("subtag"))) { byte[] data = (byte[]) entry.getUserObject(); // 将字节数据转为输入流,读取路径 try (ImageInputStream pathStream = ImageIO.createImageInputStream(new java.io.ByteArrayInputStream(data))) { Shape path = Paths.readPath(pathStream); allPaths.add(path); } } } } } } // 输出所有路径 System.out.println("提取到" + allPaths.size() + "条路径"); for (Shape shape : allPaths) { // 处理每条路径的逻辑 } } } }
关于ImageMagick命令的说明
你使用的identify -format '%[8BIM:1999,2998:#2]'命令,本质是读取JPEG中所有8BIM:1999,2998标记的元数据块——每个块对应一条独立路径。上面的Java代码和这个命令原理一致,都是遍历所有符合标记的元数据条目,逐个解析路径。
注意:确保你的TwelveMonkeys ImageIO依赖为最新版本,避免元数据解析的兼容性问题。
内容的提问来源于stack exchange,提问作者Prashant Onkar
相关产品推荐
相关产品推荐

