日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java解析图片GPS等信息,springboot项目获得图片GPS

發(fā)布時間:2024/1/8 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java解析图片GPS等信息,springboot项目获得图片GPS 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

java解析圖片GPS等信息

文章目錄

  • java解析圖片GPS等信息
    • 1.元數(shù)據(jù)(Metadata)
      • 1.1Metadata概念解釋
      • 1.2 圖片元數(shù)據(jù)
    • 2.代碼展示
      • 2.1解析圖片信息代碼實例(有詳細注解)
      • 2.1springboot后端代碼設計
        • controller層設計
        • service接口
        • serviceImpl實現(xiàn)類
        • Result設計
        • MultipartFile轉File
        • pom依賴
        • postman測試
    • 3.參考文獻

前言:我在學習的獲取圖片信息過程中,發(fā)現(xiàn)網(wǎng)上的已有的文章要么需要VIP才能查看,要么就是講的只言片語,注解太少,對于我這種新手很不友好,特此寫這篇文章以便他人參考。

本文代碼有詳細注解,并且在文章末尾附上我所參考的文章,以及一些知識點的補充。

1.元數(shù)據(jù)(Metadata)

圖片的GPS信息存儲在圖片的元數(shù)據(jù)中,所以解析圖片GPS就是獲取圖片元數(shù)據(jù)

1.1Metadata概念解釋

? 元數(shù)據(jù)(Metadata),又稱中介數(shù)據(jù)、中繼數(shù)據(jù),為描述數(shù)據(jù)的數(shù)據(jù)(data about data),主要是描述數(shù)據(jù)屬性(property)的信息。用來支持如指示存儲位置、歷史數(shù)據(jù)、資源查找、文件記錄等功能。

元數(shù)據(jù)是關于數(shù)據(jù)的組織、數(shù)據(jù)域及其關系的信息,簡言之,元數(shù)據(jù)就是關于數(shù)據(jù)的數(shù)據(jù)。

舉個例子:

下面是契訶夫的小說《套中人》中的一段,描寫一個叫做瓦蓮卡的女子:

(她)年紀已經(jīng)不輕,三十歲上下,個子高挑,身材勻稱,黑黑的眉毛,紅紅的臉蛋--一句話,不是姑娘,而是果凍,她那樣活躍,吵吵嚷嚷,不停地哼著小俄羅斯的抒情歌曲,高聲大笑,動不動就發(fā)出一連串響亮的笑聲:哈,哈,哈!

這段話里提供了這樣幾個信息:年齡(三十歲上下)、身高(個子高挑)、相貌(身材勻稱,黑黑的眉毛,紅紅的臉蛋)、性格(活躍,吵吵嚷嚷,不停地哼著小俄羅斯的抒情歌曲,高聲大笑)。有了這些信息,我們就可以大致想像出瓦蓮卡是個什么樣的人。推而廣之,只要提供這幾類的信息,我們也可以推測出其他人的樣子。

這個例子中的"年齡"、“身高”、“相貌”、“性格”,就是元數(shù)據(jù),因為它們是用來描述具體數(shù)據(jù)/信息的數(shù)據(jù)/信息。

當然,這幾個元數(shù)據(jù)用來刻畫個人狀況還不夠精確。我們每個人從小到大,都填過《個人情況登記表》之類的東西吧,其中包括姓名、性別、民族、政治面貌、一寸照片、學歷、職稱等等…這一套元數(shù)據(jù)才算比較完備。

1.2 圖片元數(shù)據(jù)

圖片元數(shù)據(jù)(Metadata) 是嵌入到圖片文件中的一些標簽。比較像文件屬性,但是種類繁多。對于數(shù)碼圖像,目前常見的研數(shù)據(jù)有EXIF, IPTC和XMP三種:

  • EXIF:通常被數(shù)碼相機在拍攝照片時自動添加,比如相機型號、鏡頭、曝光、圖片尺寸,地理位置等信息
  • IPTF:比如圖片標題、關鍵字、說明、作者、版權等信息。主要是由人工在后期通過軟件寫入的數(shù)據(jù)。
  • XMP:XMP實際上是一種元數(shù)據(jù)存儲和管理的標準,可以將Exif,IPTC或其他的數(shù)據(jù)都按XMP統(tǒng)一的格式存放在圖像文件中。

元數(shù)據(jù)的嵌入方式因圖像格式而異,不同格式的圖像文件(如JPG, TIF, DNS等)有不同的嵌入方式。

2.代碼展示

2.1解析圖片信息代碼實例(有詳細注解)

方法封裝在自定義的Exif類中,前端獲取圖片傳給后端,后端在service層調用該方法

package com.haoshang.until;import com.alibaba.fastjson.JSON; 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 java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL;/*** @author 浩殤* @create 2022/12/7--22:56--周三* Exif*/ public class Exif {//主方法體,封裝在Exif類中,通過service層調用public static JSONObject analysis(File file)throws Exception{//將圖片傳入自定義方法中return printImageTags( file);}private static JSONObject printImageTags(File file) throws ImageProcessingException, IOException {String lat = "";String log = ""; // 讀取元數(shù)據(jù)Metadata metadata = ImageMetadataReader.readMetadata(file);for (Directory directory : metadata.getDirectories()) { // 打印元數(shù)據(jù)內容for (Tag tag : directory.getTags()) {String tagName = tag.getTagName(); //標簽名String desc = tag.getDescription(); //標簽信息 // System.out.println("["+tagName +"]"+ " : " + desc);//照片信息switch (tagName) {// 經(jīng)度case "GPS Longitude":lat = pointToLatlong(desc); // System.out.println("***********"+lat+"*************");break;// 緯度case "GPS Latitude":log = pointToLatlong(desc); // System.out.println("***********"+log+"*************");break;default:break;}}}System.out.println("###########################################################################");String add = getAdd(log, lat);JSONObject jsonObject = JSON.parseObject(add);//controller層設計為傳輸JSONObject類,讀者也可設計為傳輸?shù)刂纷址?/span>return jsonObject;/*輸出地址String add = getAdd(log, lat);JSONObject jsonObject = JSON.parseObject(add);JSONObject object=jsonObject.getJSONObject("result");String adds = object.getString("formatted_address");*/}/*** 經(jīng)緯度格式 轉換** @param 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();}/*** @param log 經(jīng)度** @param lat 緯度** @return*/public static String getAdd(String log, String lat) {//采用百度地圖的接口:String urlString = "http://api.map.baidu.com/geocoder?location="+log+","+lat+"&output=json";System.out.println(urlString);String res = "";try {/*URL定義:統(tǒng)一資源標識符(Uniform Resource Identifier ,URL)是采用一種特定語法標識一個資源的字符串。所標識的資源可能是服務器上的一個文件。Java的URL網(wǎng)絡類可以讓你通過URL去練級網(wǎng)絡服務器并獲取資源。*/ // 創(chuàng)建新的urlURL url = new URL(urlString); // 調用URL對象的openConnection( )來獲取HttpURLConnection對象實例:HttpURLConnection conn = (HttpURLConnection) url.openConnection();// 可以使用conn.getOutputStream().write()conn.setDoOutput(true);// 設置HTTP請求使用的方法:GET(不安全) 或者POST,PUT等,HttpURLConnection默認是進行Get請求的:conn.setRequestMethod("GET"); // 調用getInputStream()方法獲得服務器返回的輸入流,然后輸入流進行讀取BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));String line; // 解析獲得的數(shù)據(jù)while ((line = in.readLine()) != null) {res += line + "\n";}in.close();} catch (Exception e) {System.out.println("error in wapaction,and e is " + e.getMessage());}return res;} }

2.1springboot后端代碼設計

springboot上傳文件類型為MultipartFile,而解析圖片需要上傳File文件,所以代碼涉及到MultipartFile轉為File的類

代碼中的MassageMapper, PhotoMassage分別為設計的mapper和實體類pojo,但并未對數(shù)據(jù)庫進行操作,所以并未展示

controller層設計

package com.haoshang.apppro.analysis.controller;import com.alibaba.fastjson.JSONObject; import com.haoshang.apppro.analysis.service.MassageService; import com.haoshang.until.Result; import com.haoshang.until.Status; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; /*** @author 浩殤* @create 2022/12/6--19:59--周二* AnalysisController*/ @RestController @RequestMapping("/analysis") public class AnalysisController {@Autowiredprivate MassageService massageService;@PostMapping("/photo")private Result<JSONObject> analysisPhoto(@RequestParam("file") MultipartFile file){try {return massageService.analysis(file);} catch (Exception e) {e.printStackTrace();return new Result<>(Status.SYSTEM_ERROR.getCode(), Status.SYSTEM_ERROR.getMessage(),null);}}}

service接口

package com.haoshang.apppro.analysis.service;import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.extension.service.IService; import com.haoshang.apppro.analysis.entity.PhotoMassage; import com.haoshang.until.Result; import org.springframework.web.multipart.MultipartFile; /*** @author 浩殤* @create 2022/12/6--20:19--周二* MassageService*/ public interface MassageService extends IService<PhotoMassage> {Result<JSONObject> analysis(MultipartFile f) throws Exception; }

serviceImpl實現(xiàn)類

package com.haoshang.apppro.analysis.service.impl;import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.haoshang.apppro.analysis.entity.PhotoMassage; import com.haoshang.apppro.analysis.mapper.MassageMapper; import com.haoshang.apppro.analysis.service.MassageService; import com.haoshang.until.Exif; import com.haoshang.until.Result; import com.haoshang.until.Shift; import com.haoshang.until.Status; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; /*** @author 浩殤* @create 2022/12/6--20:37--周二* MassageServiceImpl*/ @Service public class MassageServiceImpl extends ServiceImpl<MassageMapper, PhotoMassage> implements MassageService {@Overridepublic Result<JSONObject> analysis( MultipartFile file) {try {File f=Shift.multipartFileToFile(file);JSONObject jsonObject=Exif.analysis(f);Shift.deleteTempFile(f);//清除緩存return new Result<>(Status.OK.getCode(), "讀取圖片信息成功",jsonObject);} catch (Exception e) {e.printStackTrace();return new Result<>(Status.SYSTEM_ERROR.getCode(), Status.SYSTEM_ERROR.getMessage(),null);// Status.SYSTEM_ERROR.getCode()是自定義的code,讀者采用自己設計的code即可}} }

Result設計

package com.haoshang.until;import lombok.Data; /*** @author 浩殤* @create 2022/11/23--20:02--周三* Result*/ @Data public class Result<T> {// 狀態(tài)碼private int code;// 返回信息private String msg;// 數(shù)據(jù)private T data;public Result() {}public Result(int code, String msg) {this.code = code;this.msg = msg;}public Result(int code, String msg, T data) {this.code = code;this.msg = msg;this.data = data;}public Result(T data) {this.data = data;}}

MultipartFile轉File

package com.haoshang.until;import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; /*** @author 浩殤* @create 2022/12/8--0:00--周四* shift*/ public class Shift {/*** MultipartFile 轉 File** @param file* @throws Exception*/public static File multipartFileToFile(MultipartFile file) throws Exception {File toFile = null;if (file.equals("") || file.getSize() <= 0) {file = null;} else {InputStream ins = null;ins = file.getInputStream();//讀入到內存toFile = new File(file.getOriginalFilename());//給File文件實體化inputStreamToFile(ins, toFile);ins.close();}return toFile;}//獲取流文件private static void inputStreamToFile(InputStream ins, File file) {try {OutputStream os = new FileOutputStream(file);//以輸出流打開file,實現(xiàn)outputStream.write向file中輸出內容int bytesRead = 0;byte[] buffer = new byte[8192];while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {os.write(buffer, 0, bytesRead);//文件寫入}os.close();ins.close();} catch (Exception e) {e.printStackTrace();}}/*** 刪除本地臨時文件* @param file*/public static void deleteTempFile(File file) {if (file != null) {File del = new File(file.toURI());del.delete();}} }

pom依賴

僅展示解析元數(shù)據(jù)類的依賴

<!--獲取元數(shù)據(jù)依賴--><dependency><groupId>com.drewnoakes</groupId><artifactId>metadata-extractor</artifactId><version>2.7.2</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.71</version></dependency>

postman測試

3.參考文獻

參考文獻:

  • Java Metadata.getDirectories方法代碼示例 - 純凈天空 (vimsky.com)
  • 圖像元數(shù)據(jù)(Metadata) 及 Exif信息分析 - 掘金 (juejin.cn)
  • http://t.csdn.cn/XOJJD(元數(shù)據(jù)理解)
  • JSONArray與JSONObject的區(qū)別 - 清華大咖 - 博客園 (cnblogs.com)
  • 通過經(jīng)緯度獲取具體省市區(qū)位置地址的Api | 程序員磊哥 (examplecode.cn)
  • 總結

    以上是生活随笔為你收集整理的java解析图片GPS等信息,springboot项目获得图片GPS的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。