Skip to content

Instantly share code, notes, and snippets.

@usbharu
Created November 17, 2022 05:55
Show Gist options
  • Save usbharu/2ab1616070d773337f46787754d0ee9a to your computer and use it in GitHub Desktop.
Save usbharu/2ab1616070d773337f46787754d0ee9a to your computer and use it in GitHub Desktop.
Jpegのタグを読み込む
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