Created
November 17, 2022 05:55
-
-
Save usbharu/2ab1616070d773337f46787754d0ee9a to your computer and use it in GitHub Desktop.
Jpegのタグを読み込む
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package io.github.usbharu.test.image.xmp; | |
import java.io.ByteArrayInputStream; | |
import java.io.File; | |
import java.io.FileInputStream; | |
import java.io.IOException; | |
import java.nio.ByteBuffer; | |
import java.nio.ByteOrder; | |
import java.nio.charset.StandardCharsets; | |
import java.util.Arrays; | |
public class XmpReader { | |
private static boolean exif = false; | |
private static boolean xmp = false; | |
private static final byte[] exifByteArray = "Exif".getBytes(); | |
private static final byte[] xmpByteArray = "http://ns.adobe.com/xap/1.0/".getBytes(); | |
public static void main(String[] args) { | |
File file = new File("path/to/image folder"); | |
for (int i = 0; i < 1; i++) { //ベンチマーク用 | |
long l = System.currentTimeMillis(); | |
for (File listFile : file.listFiles((dir, name) -> name.endsWith(".jpg"))) { | |
try { | |
read(listFile); | |
} catch (RuntimeException e) { | |
new RuntimeException(listFile.toString(), e).printStackTrace(); | |
} | |
} | |
long l1 = System.currentTimeMillis(); | |
System.out.println(l1 - l); | |
} | |
} | |
public static void read(File file) { | |
exif = false; | |
xmp = false; | |
try (FileInputStream fileInputStream = (new FileInputStream(file))) { | |
try (ByteArrayInputStream is = new ByteArrayInputStream(fileInputStream.readAllBytes())) { | |
int read = 0; | |
while ((!exif && !xmp) && (read = is.read()) != -1) { | |
if (read == 0xff) { | |
int read1 = is.read(); | |
short size = (short) (is.read() << 8 | is.read()); | |
if (read1 == 0xe1) { | |
byte[] b = new byte[size - 2]; | |
is.read(b); | |
switchApp(b); | |
} else { | |
is.skip(size); | |
} | |
} | |
} | |
} catch (IOException e) { | |
throw new RuntimeException(e); | |
} | |
} catch (IOException e) { | |
throw new RuntimeException(e); | |
} | |
} | |
private static void switchApp(byte[] appSegment) { | |
if (Arrays.equals(exifByteArray, 0, 4, appSegment, 0, 4)) { | |
exif(appSegment); | |
exif = true; | |
} else if (Arrays.equals(xmpByteArray, 0, 28, appSegment, 0, 28)) { | |
xmp(appSegment); | |
xmp = true; | |
} | |
} | |
private static void xmp(byte[] appSegment) { | |
System.out.println(new String(appSegment)); | |
} | |
private static void exif(byte[] appSegment) { | |
ByteBuffer wrap = ByteBuffer.wrap(appSegment); | |
wrap.get(6); | |
if (appSegment[6] != (byte) 0x4d && appSegment[7] != (byte) 0x4d) { | |
wrap = wrap.order(ByteOrder.LITTLE_ENDIAN); | |
} | |
wrap.position(10); | |
int ifdOffset = wrap.getInt(); | |
wrap.position(ifdOffset + 6); | |
short ifdCount = wrap.getShort(); | |
for (int i = 0; i < ifdCount; i++) { | |
readIfdField(wrap); | |
} | |
} | |
private static void readIfdField(ByteBuffer wrap) { | |
byte[] tag = new byte[2]; | |
wrap.get(tag); | |
short type = wrap.getShort(); | |
int count = wrap.getInt(); | |
int valueOffset = wrap.getInt(); | |
int nowPosition = wrap.position(); | |
if (valueOffset > wrap.limit()) { | |
return; | |
} | |
wrap.position(valueOffset + 6); | |
if (type == 1) { | |
int valueLength = type * count; | |
byte[] value = new byte[valueLength]; | |
wrap.get(value); | |
if (tag[0] == (byte) 0x9c && tag[1] == (byte) 0x9e) { | |
String s = new String(value, 0, valueLength - 2, StandardCharsets.UTF_16LE); | |
System.out.println(s); | |
} | |
} | |
wrap.position(nowPosition); | |
} | |
private static String hexToString(byte[] bytes) { | |
StringBuilder sb = new StringBuilder(); | |
for (byte aByte : bytes) { | |
sb.append(String.format("%02x", aByte)); | |
} | |
return sb.toString(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment