我有一个包含一些细节的JPEG图像。
我通过编码从图像中提取了一些元数据,如下所示:
public class Test {
public static void main(String[] args){
test1();
}
public static void test1(){
File file = new File("DSC_0410.JPG");
System.out.println(file.getAbsolutePath());
try {
extractDetails(file);
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
private static void extractDetails(File file) throws IOException {
ImageInputStream is = ImageIO.createImageInputStream( new BufferedInputStream(new FileInputStream(file)));
Iterator<ImageReader> readers = ImageIO.getImageReadersByMIMEType("image/jpeg");
IIOImage image = null;
if (readers.hasNext()) {
ImageReader reader = readers.next();
reader.setInput(is, true);
image = reader.readAll(0, null);
IIOMetadata metadata = image.getMetadata();
String[] names = metadata.getMetadataFormatNames();
for (int i = 0; i < names.length; i++) {
System.out.println("Format name: " + names[ i]);
Node n = (metadata.getAsTree(names[i]));
System.out.println(n.getNodeValue());
showTree(n);
}
}
}
private static void showTree(Node node){
System.out.println(node.getNodeValue());
NodeList childs = node.getChildNodes();
if(childs.getLength()==0)
return;
for(int i=0; i<childs.getLength(); i++){
System.out.print("\t");
showTree(childs.item(i));
}
}
但输出null:
null
null
null
null
null
null
null
null
null
null
null
null
null
null
null
Format name: javax_imageio_1.0
null
null
null
null
null
null
null
null
来自here的另一个代码示例输出了一些metada但不是我想要的数据(lat,lon,alt,如图所示):
Format name: javax_imageio_jpeg_image_1.0
<javax_imageio_jpeg_image_1.0>
<JPEGvariety/>
<markerSequence>
<unknown MarkerTag="225"/>
<dqt>
<dqtable elementPrecision="0" qtableId="0"/>
<dqtable elementPrecision="0" qtableId="1"/>
</dqt>
<sof process="0" samplePrecision="8" numLines="4032" samplesPerLine="6048" numFrameComponents="3">
<componentSpec componentId="1" HsamplingFactor="2" VsamplingFactor="1" QtableSelector="0"/>
<componentSpec componentId="2" HsamplingFactor="1" VsamplingFactor="1" QtableSelector="1"/>
<componentSpec componentId="3" HsamplingFactor="1" VsamplingFactor="1" QtableSelector="1"/>
</sof>
<dht>
<dhtable class="0" htableId="0"/>
<dhtable class="1" htableId="0"/>
<dhtable class="0" htableId="1"/>
<dhtable class="1" htableId="1"/>
</dht>
<sos numScanComponents="3" startSpectralSelection="0" endSpectralSelection="63" approxHigh="0" approxLow="0">
<scanComponentSpec componentSelector="1" dcHuffTable="0" acHuffTable="0"/>
<scanComponentSpec componentSelector="2" dcHuffTable="1" acHuffTable="1"/>
<scanComponentSpec componentSelector="3" dcHuffTable="1" acHuffTable="1"/>
</sos>
</markerSequence>
</javax_imageio_jpeg_image_1.0>
Format name: javax_imageio_1.0
<javax_imageio_1.0>
<Chroma>
<ColorSpaceType name="YCbCr"/>
<NumChannels value="3"/>
</Chroma>
<Compression>
<CompressionTypeName value="JPEG"/>
<Lossless value="FALSE"/>
<NumProgressiveScans value="1"/>
</Compression>
<Dimension>
<ImageOrientation value="normal"/>
</Dimension>
</javax_imageio_1.0>
我想从JPEG图像中提取纬度,经度和海拔高度。请帮忙!
答案 0 :(得分:3)
从here下载apache sanselan
库并使用它。提取包含GPS元数据的所有元数据的完整示例:
import java.io.File;
import java.io.IOException;
import java.util.List;
import org.apache.sanselan.ImageReadException;
import org.apache.sanselan.Sanselan;
import org.apache.sanselan.common.IImageMetadata;
import org.apache.sanselan.common.ImageMetadata.Item;
import org.apache.sanselan.common.RationalNumber;
import org.apache.sanselan.formats.jpeg.JpegImageMetadata;
import org.apache.sanselan.formats.tiff.TiffField;
import org.apache.sanselan.formats.tiff.TiffImageMetadata;
import org.apache.sanselan.formats.tiff.constants.ExifTagConstants;
import org.apache.sanselan.formats.tiff.constants.GPSTagConstants;
import org.apache.sanselan.formats.tiff.constants.TiffTagConstants;
import org.apache.sanselan.formats.tiff.constants.TagInfo;
public class MetadataExample {
public static void metadataExample(final File file) throws ImageReadException,
IOException {
// get all metadata stored in EXIF format (ie. from JPEG or TIFF).
final IImageMetadata metadata = Sanselan.getMetadata(file);
// System.out.println(metadata);
if (metadata instanceof JpegImageMetadata) {
final JpegImageMetadata jpegMetadata = (JpegImageMetadata) metadata;
// Jpeg EXIF metadata is stored in a TIFF-based directory structure
// and is identified with TIFF tags.
// Here we look for the "x resolution" tag, but
// we could just as easily search for any other tag.
//
// see the TiffConstants file for a list of TIFF tags.
System.out.println("file: " + file.getPath());
// print out various interesting EXIF tags.
printTagValue(jpegMetadata, TiffTagConstants.TIFF_TAG_XRESOLUTION);
printTagValue(jpegMetadata, TiffTagConstants.TIFF_TAG_DATE_TIME);
printTagValue(jpegMetadata,
ExifTagConstants.EXIF_TAG_DATE_TIME_ORIGINAL);
//printTagValue(jpegMetadata, ExifTagConstants.EXIF_TAG_DATE_TIME_DIGITIZED);
printTagValue(jpegMetadata, ExifTagConstants.EXIF_TAG_ISO);
printTagValue(jpegMetadata,
ExifTagConstants.EXIF_TAG_SHUTTER_SPEED_VALUE);
printTagValue(jpegMetadata,
ExifTagConstants.EXIF_TAG_APERTURE_VALUE);
printTagValue(jpegMetadata,
ExifTagConstants.EXIF_TAG_BRIGHTNESS_VALUE);
printTagValue(jpegMetadata,
GPSTagConstants.GPS_TAG_GPS_LATITUDE_REF);
printTagValue(jpegMetadata, GPSTagConstants.GPS_TAG_GPS_LATITUDE);
printTagValue(jpegMetadata,
GPSTagConstants.GPS_TAG_GPS_LONGITUDE_REF);
printTagValue(jpegMetadata, GPSTagConstants.GPS_TAG_GPS_LONGITUDE);
System.out.println();
// simple interface to GPS data
final TiffImageMetadata exifMetadata = jpegMetadata.getExif();
if (null != exifMetadata) {
final TiffImageMetadata.GPSInfo gpsInfo = exifMetadata.getGPS();
if (null != gpsInfo) {
final String gpsDescription = gpsInfo.toString();
final double longitude = gpsInfo.getLongitudeAsDegreesEast();
final double latitude = gpsInfo.getLatitudeAsDegreesNorth();
System.out.println(" " + "GPS Description: "
+ gpsDescription);
System.out.println(" "
+ "GPS Longitude (Degrees East): " + longitude);
System.out.println(" "
+ "GPS Latitude (Degrees North): " + latitude);
}
}
// more specific example of how to manually access GPS values
final TiffField gpsLatitudeRefField = jpegMetadata
.findEXIFValueWithExactMatch(GPSTagConstants.GPS_TAG_GPS_LATITUDE_REF);
final TiffField gpsLatitudeField = jpegMetadata
.findEXIFValueWithExactMatch(GPSTagConstants.GPS_TAG_GPS_LATITUDE);
final TiffField gpsLongitudeRefField = jpegMetadata
.findEXIFValueWithExactMatch(GPSTagConstants.GPS_TAG_GPS_LONGITUDE_REF);
final TiffField gpsLongitudeField = jpegMetadata
.findEXIFValueWithExactMatch(GPSTagConstants.GPS_TAG_GPS_LONGITUDE);
if (gpsLatitudeRefField != null && gpsLatitudeField != null
&& gpsLongitudeRefField != null
&& gpsLongitudeField != null) {
// all of these values are strings.
final String gpsLatitudeRef = (String) gpsLatitudeRefField.getValue();
final RationalNumber gpsLatitude[] = (RationalNumber[]) (gpsLatitudeField
.getValue());
final String gpsLongitudeRef = (String) gpsLongitudeRefField
.getValue();
final RationalNumber gpsLongitude[] = (RationalNumber[]) gpsLongitudeField
.getValue();
final RationalNumber gpsLatitudeDegrees = gpsLatitude[0];
final RationalNumber gpsLatitudeMinutes = gpsLatitude[1];
final RationalNumber gpsLatitudeSeconds = gpsLatitude[2];
final RationalNumber gpsLongitudeDegrees = gpsLongitude[0];
final RationalNumber gpsLongitudeMinutes = gpsLongitude[1];
final RationalNumber gpsLongitudeSeconds = gpsLongitude[2];
// This will format the gps info like so:
//
// gpsLatitude: 8 degrees, 40 minutes, 42.2 seconds S
// gpsLongitude: 115 degrees, 26 minutes, 21.8 seconds E
System.out.println(" " + "GPS Latitude: "
+ gpsLatitudeDegrees.toDisplayString() + " degrees, "
+ gpsLatitudeMinutes.toDisplayString() + " minutes, "
+ gpsLatitudeSeconds.toDisplayString() + " seconds "
+ gpsLatitudeRef);
System.out.println(" " + "GPS Longitude: "
+ gpsLongitudeDegrees.toDisplayString() + " degrees, "
+ gpsLongitudeMinutes.toDisplayString() + " minutes, "
+ gpsLongitudeSeconds.toDisplayString() + " seconds "
+ gpsLongitudeRef);
}
System.out.println();
final List<Item> items = jpegMetadata.getItems();
for (int i = 0; i < items.size(); i++) {
final Item item = items.get(i);
System.out.println(" " + "item: " + item);
}
System.out.println();
}
}
private static void printTagValue(final JpegImageMetadata jpegMetadata,
final TagInfo tagInfo) {
final TiffField field = jpegMetadata.findEXIFValueWithExactMatch(tagInfo);
if (field == null) {
System.out.println(tagInfo.name + ": " + "Not Found.");
} else {
System.out.println(tagInfo.name + ": "
+ field.getValueDescription());
}
}
}
我的图片ali.JPG
的输出是这样的:
file: ali.JPG
XResolution: 300
Date Time: '2011:02:28 21:58:07'
Date Time Original: '2011:02:28 21:58:07'
ISO: 100
Shutter Speed Value: Not Found.
Aperture Value: Not Found.
Brightness Value: Not Found.
GPS Latitude Ref: 'N'
GPS Latitude: 30, 130380/10000 (13.038), 0
GPS Longitude Ref: 'E'
GPS Longitude: 50, 111843/10000 (11.184), 0
GPS Description: [GPS. Latitude: 30 degrees, 13.038 minutes, 0 seconds N, Longitude: 50 degrees, 11.184 minutes, 0 seconds E]
GPS Longitude (Degrees East): 50.186405
GPS Latitude (Degrees North): 30.2173
GPS Latitude: 30 degrees, 13.038 minutes, 0 seconds N
GPS Longitude: 50 degrees, 11.184 minutes, 0 seconds E
item: Make: 'NIKON CORPORATION'
item: Model: 'NIKON D3X'
item: Orientation: 1
item: XResolution: 300
item: YResolution: 300
item: Resolution Unit: 2
item: Software: 'Ver.1.01'
item: Modify Date: '2011:02:28 21:58:07'
item: Artist: ''
item: YCbCr Positioning: 2
item: Copyright: ''
item: Exif Offset: 348
item: GPSInfo: 33880
item: Exposure Time: 10/1600 (0.006)
item: FNumber: 10
item: Exposure Program: 3
item: ISO: 100
item: Exif Version: 48, 50, 50, 49
item: Date Time Original: '2011:02:28 21:58:07'
item: Create Date: '2011:02:28 21:58:07'
item: Components Configuration: 1, 2, 3, 0
item: Compressed Bits Per Pixel: 4
item: Exposure Compensation: -1
item: Max Aperture Value: 3
item: Metering Mode: 5
item: Light Source: 0
item: Flash: 0
item: Focal Length: 24
item: Maker Note: 78, 105, 107, 111, 110, 0, 2, 16, 0, 0, 77, 77, 0, 42, 0, 0, 0, 8, 0, 48, 0, 1, 0, 7, 0, 0, 0, 4, 48, 50, 49, 48, 0, 2, 0, 3, 0, 0, 0, 2, 0, 0, 0, 100, 0, 4, 0, 2, 0, 0, 0... (32866)
item: UserComment: ''
item: Sub Sec Time: '16'
item: Sub Sec Time Original: '16'
item: Sub Sec Time Digitized: '16'
item: Flashpix Version: 48, 49, 48, 48
item: Color Space: 1
item: Exif Image Width: 6048
item: Exif Image Length: 4032
item: Interop Offset: 33850
item: Sensing Method: 2
item: File Source: 3
item: Scene Type: 1
item: CFAPattern: 0, 2, 0, 2, 0, 1, 1, 2
item: Custom Rendered: 0
item: Exposure Mode: 0
item: White Balance: 0
item: Digital Zoom Ratio: 1
item: Focal Length In 3 5mm Format: 24
item: Scene Capture Type: 0
item: Gain Control: 0
item: Contrast: 0
item: Saturation: 0
item: Sharpness: 0
item: Subject Distance Range: 0
item: Interop Index: 'R98'
item: Interop Version: 48, 49, 48, 48
item: Interop Index: 'N'
item: Interop Version: 30, 130380/10000 (13.038), 0
item: Unknown Tag (0x3): 'E'
item: Unknown Tag (0x4): 50, 111843/10000 (11.184), 0
item: Unknown Tag (0x5): 0
item: Unknown Tag (0x6): 1,545
item: Unknown Tag (0x7): 12, 58, 3
item: Unknown Tag (0x8): '10'
item: Unknown Tag (0x12): ''
item: Unknown Tag (0x1d): '2011:02:28'
item: Compression: 6
item: XResolution: 300
item: YResolution: 300
item: Resolution Unit: 2
item: Jpg From Raw Start: 34232
item: Jpg From Raw Length: 9285
item: YCbCr Positioning: 2
答案 1 :(得分:0)
使用http://commons.apache.org/proper/commons-imaging
下载jar您可以在此处查看所有可用标记:https://commons.apache.org/proper/commons-imaging/javadocs/api-release/org/apache/sanselan/formats/tiff/constants/AllTagConstants.html
以下是您如何获得制造商和模型的示例:
String fullFileName="D:/test/photos - orig/lg/20170204_143925.jpg";
File file = new File(fullFileName);
// get all metadata stored in EXIF format (ie. from JPEG or TIFF).
final IImageMetadata metadata = Imaging.getMetadata(file);
if (metadata instanceof JpegImageMetadata) {
final JpegImageMetadata jpegMetadata = (JpegImageMetadata) metadata;
String manufacturer = jpegMetadata.findEXIFValueWithExactMatch(TiffTagConstants.TIFF_TAG_MAKE).getStringValue();
String model = jpegMetadata.findEXIFValueWithExactMatch(TiffTagConstants.TIFF_TAG_MODEL).getStringValue();
System.out.println("Manufacturer: "+ manufacturer+", Model: " + model);
}