Check whether you are green by means of Java Technology

This morning, I saw Python recommended in CSDN get the overtime photo location address sent by my girlfriend. It was a story from the hotel. I was going to verify it and practice my hand. Finally, the installation execution pip install json reported that there was no version number specified.

In a rage, I made my big JAVA to verify the feasibility and scenario reverie. Don't talk too much nonsense. Get the hard goods first.

Dependency import

From the blog post, it's the exifrad module. I found the corresponding jar of my big java and found that the metadata extractor is still being updated officially. The latest jar is this year.

This metadata extraction jar is very powerful and supports the extraction of video information. See the official introduction:

See, the first example is written to support my big JAVA, which makes me like a chicken blood rush to the top. While supporting my colleagues' joint commissioning event work order, I also support the big liver.

<dependency>
    <groupId>com.drewnoakes</groupId>
    <artifactId>metadata-extractor</artifactId>
    <version>2.16.0</version>
</dependency>

preparation

1. Turn on GPS in outdoor open places

2. Baidu map and Beidou partner verify that they are connected to GPS positioning

3. Set the camera on position information of the phone

4. Take a picture and check the photo details

Here, you must make sure that the details of the photos taken have longitude and latitude information. If not, you can search in CSDN for your mobile phone and how to set it. By the way, CSDN's browser plug-in is really fragrant. It's just the gospel of our technical personnel. We don't have to worry about the advertising of a certain degree, which makes it difficult to find things. Moreover, it is very inclusive, and you can choose your favorite search engine.

Sample demo

Here is a demonstration of the information that can be extracted by the metadata extraction jar. By the way, transfer the obtained longitude and latitude to the address through Baidu.

Because it is a demo and there is no business, I will work directly in the test class here. No business, no secrets involved, full code.

I won't introduce the basics of Spring Boot. I recommend this practical tutorial:
https://www.javastack.cn/categories/Spring-Boot/

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 the information in the photo
     *
     * @param file Photo file
     * @throws ImageProcessingException
     * @throws Exception
     */
    private static void readImageInfo(File file) throws ImageProcessingException, Exception {
        Metadata metadata = ImageMetadataReader.readMetadata(file);

        System.out.println("---Print all details---");
        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("--Print common information---");
        
        Double lat = null;
        Double lng = null;
        for (Directory directory : metadata.getDirectories()) {
            for (Tag tag : directory.getTags()) {
                String tagName = tag.getTagName();  //Tag name
                String desc = tag.getDescription(); //Label information
                if (tagName.equals("Image Height")) {
                    System.err.println("Picture height: " + desc);
                } else if (tagName.equals("Image Width")) {
                    System.err.println("image width: " + desc);
                } else if (tagName.equals("Date/Time Original")) {
                    System.err.println("Shooting time: " + desc);
                } else if (tagName.equals("GPS Latitude")) {
                    System.err.println("latitude : " + desc);
                    System.err.println("latitude(Degree minute second format) : " + pointToLatlong(desc));
                    lat = latLng2Decimal(desc);
                } else if (tagName.equals("GPS Longitude")) {
                    System.err.println("longitude: " + desc);
                    System.err.println("longitude(Degree minute second format): " + pointToLatlong(desc));
                    lng = latLng2Decimal(desc);
                }
            }
        }
        System.err.println("--Longitude and latitude to address--");
        //Longitude and latitude to landlords using Baidu api
        convertGpsToLoaction(lat, lng);


    }

    /**
     * The longitude and latitude format is converted to degrees, minutes and seconds format. If necessary, this method can be called for conversion
     *
     * @param point Coordinate point
     * @return
     */
    public static String pointToLatlong(String point) {
        Double du = Double.parseDouble(point.substring(0, point.indexOf("°")).trim());
        Double fen = Double.parseDouble(point.substring(point.indexOf("°") + 1, point.indexOf("'")).trim());
        Double miao = Double.parseDouble(point.substring(point.indexOf("'") + 1, point.indexOf("\"")).trim());
        Double duStr = du + fen / 60 + miao / 60 / 60;
        return duStr.toString();
    }

    /***
     * Format conversion of longitude and latitude coordinates (* ° to decimal format)
     * @param gps
     */
    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("\"", "");
        double gps_dou = Double.parseDouble(a) + Double.parseDouble(b) / 60 + Double.parseDouble(c) / 60 / 60;
        return gps_dou;
    }

    /**
     * api_key: Registered Baidu api key
     * coords: Longitude and latitude coordinates
     * http://api.map.baidu.com/reverse_geocoding/v3/?ak="+api_key+"&output=json&coordtype=wgs84ll&location="+coords
     * <p>
     * Longitude and latitude to address information
     *
     * @param gps_latitude  dimension
     * @param gps_longitude accuracy
     */
    private static void convertGpsToLoaction(double gps_latitude, double gps_longitude) throws IOException {
        String apiKey = "YNxcSCAphFvuPD4LwcgWXwC3SEZZc7Ra";

        String res = "";
        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);

        res = HttpUtils.httpGet(url);
        JSONObject object = JSONObject.parseObject(res);
        if (object.containsKey("result")) {
            JSONObject result = object.getJSONObject("result");
            if (result.containsKey("addressComponent")) {
                JSONObject address = object.getJSONObject("result").getJSONObject("addressComponent");
                System.err.println("Location:" + address.get("country") + " " + address.get("province") + " " + address.get("city") + " " + address.get("district") + " "
                        + address.get("street") + " " + result.get("formatted_address") + " " + result.get("business"));
            }
        }
    }

}

Console printing:

Details are posted below:

com.easylinkin.bm.extractor.ImgTestCode
---Print all details---
[JPEG] - Compression Type = Baseline
[JPEG] - Data Precision = 8 bits
[JPEG] - Image Height = 4032 pixels
[JPEG] - Image Width = 3024 pixels
[JPEG] - Number of Components = 3
[JPEG] - Component 1 = Y component: Quantization table 0, Sampling factors 2 horiz/2 vert
[JPEG] - Component 2 = Cb component: Quantization table 1, Sampling factors 1 horiz/1 vert
[JPEG] - Component 3 = Cr component: Quantization table 1, Sampling factors 1 horiz/1 vert
[Exif IFD0] - Date/Time = 2021:08:20 09:39:58
[Exif IFD0] - Model = YOTA Y3
[Exif IFD0] - YCbCr Positioning = Center of pixel array
[Exif IFD0] - Resolution Unit = Inch
[Exif IFD0] - Y Resolution = 72 dots per inch
[Exif IFD0] - X Resolution = 72 dots per inch
[Exif IFD0] - Make = YOTA
[GPS] - GPS Date Stamp = 2021:08:20
[GPS] - GPS Altitude Ref = Below sea level
[GPS] - GPS Longitude Ref = E
[GPS] - GPS Longitude = 114° 24' 9.61"
[GPS] - GPS Processing Method = ASCII
[GPS] - GPS Latitude Ref = N
[GPS] - GPS Time-Stamp = 01:39:46.000 UTC
[GPS] - GPS Altitude = 21 metres
[GPS] - GPS Latitude = 30° 28' 40.67"
[Exif SubIFD] - Color Space = sRGB
[Exif SubIFD] - F-Number = f/1.9
[Exif SubIFD] - Date/Time Digitized = 2021:08:20 09:39:58
[Exif SubIFD] - Focal Length = 3.9 mm
[Exif SubIFD] - Aperture Value = f/1.9
[Exif SubIFD] - Exposure Mode = Auto exposure
[Exif SubIFD] - Sub-Sec Time Digitized = 819350
[Exif SubIFD] - Exif Image Height = 4032 pixels
[Exif SubIFD] - Focal Length 35 = 23 mm
[Exif SubIFD] - Scene Capture Type = Standard
[Exif SubIFD] - Sub-Sec Time Original = 819350
[Exif SubIFD] - Exposure Program = Unknown (0)
[Exif SubIFD] - White Balance Mode = Auto white balance
[Exif SubIFD] - Exif Image Width = 3024 pixels
[Exif SubIFD] - Sub-Sec Time = 819350
[Exif SubIFD] - Shutter Speed Value = 1/1022 sec
[Exif SubIFD] - Metering Mode = Center weighted average
[Exif SubIFD] - Date/Time Original = 2021:08:20 09:39:58
[Exif SubIFD] - Components Configuration = YCbCr
[Exif SubIFD] - Exif Version = 2.20
[Exif SubIFD] - Flash = Flash did not fire
[Exif SubIFD] - Brightness Value = 0.0
[Exif SubIFD] - ISO Speed Ratings = 103
[Exif SubIFD] - Sensing Method = One-chip color area sensor
[Exif SubIFD] - FlashPix Version = 1.00
[Exif SubIFD] - Exposure Time = 1/1023 sec
[Interoperability] - Interoperability Index = Recommended Exif Interoperability Rules (ExifR98)
[Interoperability] - Interoperability Version = 1.00
[Exif Thumbnail] - Y Resolution = 72 dots per inch
[Exif Thumbnail] - Thumbnail Length = 21538 bytes
[Exif Thumbnail] - Thumbnail Offset = 959 bytes
[Exif Thumbnail] - Compression = JPEG (old-style)
[Exif Thumbnail] - Resolution Unit = Inch
[Exif Thumbnail] - X Resolution = 72 dots per inch
[Huffman] - Number of Tables = 4 Huffman tables
[File Type] - Detected File Type Name = JPEG
[File Type] - Detected File Type Long Name = Joint Photographic Experts Group
[File Type] - Detected MIME Type = image/jpeg
[File Type] - Expected File Name Extension = jpg
[File] - File Name = IMG_20210820_093958.jpg
[File] - File Size = 5215044 bytes
[File] - File Modified Date = Friday August 20 09:39:59 +08:00 2021
--Print common information---
initialization HttpClientTest~~~start
 Picture height: 4032 pixels
 image width: 3024 pixels
 longitude: 114° 24' 9.61"
longitude(Degree minute second format): 114.40266944444446
 latitude : 30° 28' 40.67"
latitude(Degree minute second format) : 30.477963888888887
 Shooting time: 2021:08:20 09:39:58
--Longitude and latitude to address--
[url]http://api.map.baidu.com/reverse_geocoding/v3/?ak=YNxcSCAphFvuPD4LwcgWXwC3SEZZc7Ra&output=json&coordtype=wgs84ll&location=30.477963888888887,114.40266944444446
 initialization HttpClientTest~~~end
 Location: 9 Guanshan, Software Park Road, Hongshan District, Wuhan City, Hubei Province, China,Optics Valley heaven and earth

I won't explain the extracted content above. I should understand it. If I don't understand it, I can translate it into English or check the API to see what it prints.

I won't demonstrate other documents. If you are interested, you can try it yourself.

The AK of my baidu map will be put here first to facilitate everyone's verification, so as not to say I cheat. Anyway, I use it for free.

Finally, the picture can be sent either compressed into a compressed packet or copied out of the mobile phone with a data cable. I first sent it through wechat, and basically all the information has been erased (you can also see the longitude and latitude information by viewing the picture details on the computer).

Also, I have an Apple phone. In fact, I can take photos with geographical location information. I need to open the location in privacy and authorize the camera.

Summary and derived ideas

How to say this, it's still very good. If it is used in our work, we think it can replace our previous patrol inspection. When we arrive at the patrol inspection position, we can take a picture, and then cooperate with the machine code. We are not afraid that you will let others take pictures on behalf of us. There are also work attendance sheets, field work, etc.

In addition, I also think of the kids who love to take photos outside. Put your photos on cloud storage, and then if there are unscrupulous service providers, you can basically draw your track through the time of your uploaded photos...

Well, that's it. In fact, the biggest feeling here is that if I don't know A, I won't think of B. If I had known the information that pictures can carry, or the information that camera software can get, I might have done something earlier......

Original link: https://blog.csdn.net/zwrlj527/article/details/119823407

Copyright notice: This is the original article of CSDN blogger "fat brother 1930", which follows the CC 4.0 BY-SA copyright agreement. Please attach the original source link and this notice for reprint.

Recent hot article recommendations:

1.1000 + Java interview questions and answers (2021 latest version)

2.Stop playing if/ else on the full screen. Try the strategy mode. It's really fragrant!!

3.what the fuck! What is the new syntax of xx ≠ null in Java?

4.Spring Boot 2.5 heavy release, dark mode is too explosive!

5.Java development manual (Songshan version) is the latest release. Download it quickly!

Feel good, don't forget to like + forward!

Posted on Wed, 03 Nov 2021 17:35:52 -0400 by bishnu.bhatta