Backend Development 12 min read

Extracting Image EXIF GPS Metadata with Java metadata‑extractor and Baidu Reverse Geocoding

This article demonstrates how to use the Java metadata‑extractor library to read EXIF GPS information from photos, convert the coordinates to a human‑readable address via Baidu's reverse‑geocoding API, and provides a complete runnable example with Maven dependency and utility code.

Java Architect Essentials
Java Architect Essentials
Java Architect Essentials
Extracting Image EXIF GPS Metadata with Java metadata‑extractor and Baidu Reverse Geocoding

The author, a self‑described "architect who writes code and poetry," shares a practical tutorial that starts with a humorous anecdote about trying a Python script and ending up using Java for metadata extraction.

Dependency Import

The required library is <dependency> <groupId>com.drewnoakes</groupId> <artifactId>metadata-extractor</artifactId> <version>2.16.0</version> </dependency> . This JAR can also extract video metadata and is actively maintained.

Preparation

Before running the demo, ensure that the device has GPS enabled, the map app (Baidu/BeiDou) is connected, and the camera is set to record location data.

Demo Code

The following Java class reads a JPEG file, prints all metadata, extracts common fields (image size, capture time, GPS latitude/longitude), converts DMS coordinates to decimal, and calls Baidu's reverse‑geocoding API to obtain the address.

package com.easylinkin.bm.extractor;

import com.alibaba.fastjson.JSONObject;
import com.drew.imaging.ImageMetadataReader;
import com.drew.imaging.ImageProcessingException;
import com.drew.metadata.Directory;
import com.drew.metadata.Metadata;
import com.drew.metadata.Tag;
import com.easylinkin.bm.util.HttpUtils;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.io.IOException;

/**
 * @author zhengwen
 */
@Slf4j
public class ImgTestCode {
    public static void main(String[] args) throws Exception {
        File file = new File("C:\\Users\\zhengwen\\Desktop\\test\\IMG_20210820_093958.jpg");
        readImageInfo(file);
    }

    /**
     * Extract photo information
     */
    private static void readImageInfo(File file) throws ImageProcessingException, Exception {
        Metadata metadata = ImageMetadataReader.readMetadata(file);
        System.out.println("---打印全部详情---");
        for (Directory directory : metadata.getDirectories()) {
            for (Tag tag : directory.getTags()) {
                System.out.format("[%s] - %s = %s\n", directory.getName(), tag.getTagName(), tag.getDescription());
            }
            if (directory.hasErrors()) {
                for (String error : directory.getErrors()) {
                    System.err.format("ERROR: %s", error);
                }
            }
        }
        System.out.println("--打印常用信息---");
        Double lat = null;
        Double lng = null;
        for (Directory directory : metadata.getDirectories()) {
            for (Tag tag : directory.getTags()) {
                String tagName = tag.getTagName();
                String desc = tag.getDescription();
                if (tagName.equals("Image Height")) {
                    System.err.println("图片高度: " + desc);
                } else if (tagName.equals("Image Width")) {
                    System.err.println("图片宽度: " + desc);
                } else if (tagName.equals("Date/Time Original")) {
                    System.err.println("拍摄时间: " + desc);
                } else if (tagName.equals("GPS Latitude")) {
                    System.err.println("纬度 : " + desc);
                    System.err.println("纬度(度分秒格式) : " + pointToLatlong(desc));
                    lat = latLng2Decimal(desc);
                } else if (tagName.equals("GPS Longitude")) {
                    System.err.println("经度: " + desc);
                    System.err.println("经度(度分秒格式): " + pointToLatlong(desc));
                    lng = latLng2Decimal(desc);
                }
            }
        }
        System.err.println("--经纬度转地址--");
        convertGpsToLoaction(lat, lng);
    }

    /** Convert DMS to decimal */
    public static double latLng2Decimal(String gps) {
        String a = gps.split("°")[0].replace(" ", "");
        String b = gps.split("°")[1].split("'")[0].replace(" ", "");
        String c = gps.split("°")[1].split("'")[1].replace(" ", "").replace("\"", "");
        return Double.parseDouble(a) + Double.parseDouble(b) / 60 + Double.parseDouble(c) / 3600;
    }

    /** Reverse‑geocode using Baidu */
    private static void convertGpsToLoaction(double gps_latitude, double gps_longitude) throws IOException {
        String apiKey = "YNxcSCAphFvuPD4LwcgWXwC3SEZZc7Ra";
        String url = "http://api.map.baidu.com/reverse_geocoding/v3/?ak=" + apiKey + "&output=json&coordtype=wgs84ll&location=" + gps_latitude + "," + gps_longitude;
        System.err.println("【url】" + url);
        String res = HttpUtils.httpGet(url);
        JSONObject object = JSONObject.parseObject(res);
        if (object.containsKey("result")) {
            JSONObject result = object.getJSONObject("result");
            if (result.containsKey("addressComponent")) {
                JSONObject address = result.getJSONObject("addressComponent");
                System.err.println("拍摄地点:" + address.getString("country") + " " + address.getString("province") + " " + address.getString("city") + " " + address.getString("district") + " " + address.getString("street") + " " + result.getString("formatted_address") + " " + result.getString("business"));
            }
        }
    }
}

Console Output

The program prints all EXIF tags, then shows selected fields such as image dimensions, capture time, latitude/longitude in both DMS and decimal formats, and finally the reverse‑geocoded address (e.g., "中国 湖北省 武汉市 洪山区 软件园路 …").

Summary and Ideas

The author suggests that this technique can replace manual location‑check processes in field work, attendance, and inspection scenarios. He also warns that photos uploaded to cloud storage may unintentionally expose users' movement trails.

Overall, the tutorial provides a complete, ready‑to‑run example for extracting geographic metadata from images using Java, converting coordinates, and obtaining readable addresses via Baidu API.

Javaimage processingGPSBaidu APIexifmetadata-extractor
Java Architect Essentials
Written by

Java Architect Essentials

Committed to sharing quality articles and tutorials to help Java programmers progress from junior to mid-level to senior architect. We curate high-quality learning resources, interview questions, videos, and projects from across the internet to help you systematically improve your Java architecture skills. Follow and reply '1024' to get Java programming resources. Learn together, grow together.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.