1 准备工作
1.1 导入依赖
<!-- 地址定位 -->
<dependency>
<groupId></groupId>
<artifactId>metadata-extractor</artifactId>
<version>2.16.0</version>
</dependency>
1.2 照片图片
图片名和地址如上所述
2 具体实现
2.1 图片工具类
package ;
import .slf4j.Slf4j;
import ;
import .*;
import ;
import ;
import ;
import ;
import ;
/**
* 图片工具类
* @author wuKeFan
* @date 2022-08-30 15:16:07
*/
@Slf4j
public class ImageUtils {
public static void main(String[] args) throws Exception {
ArrayList<String> list = new ArrayList<>();
("C:\\Users\\1\\Desktop\\");
("C:\\Users\\1\\Desktop\\");
String path="D://1";
String resultPath = doVImageMerging2(list, path);
(resultPath);
}
//2张图片水平合并
public static String doVImageMerging2(ArrayList<String> list, String pathFile) {
// 读取待合并的文件
BufferedImage bi1 = null;
BufferedImage bi2 = null;
// 调用mergeImage方法获得合并后的图像
BufferedImage destImg = null;
try {
bi2 = getBufferedImage((0));
bi1 = getBufferedImage((1));
} catch (IOException e) {
();
}
// 调用mergeImage方法获得合并后的图像
try {
if (bi1 != null && bi2 != null) {
destImg = mergeImage(bi1, bi2, false);//true为水平,false为垂直
}
} catch (IOException e) {
();
}
// 保存图像
String savePath = pathFile + "/";//文件存放路径
String fileName = createImageName() + ".jpg";//文件名称
String fileType = "jpg";//文件格式
boolean result = saveImage(destImg, savePath, fileName, fileType);
("图片保存结果:{}", result ? "成功" : "失败");
return savePath + fileName;
}
public static BufferedImage getBufferedImage(String fileUrl) throws IOException {
File f = new File(fileUrl);
return (f);
}
/**
* 待合并的两张图必须满足这样的前提,如果水平方向合并,则高度必须相等;如果是垂直方向合并,宽度必须相等。
* mergeImage方法不做判断,自己判断。
*
* @param img1
* 待合并的第一张图
* @param img2
* 带合并的第二张图
* @param isHorizontal
* 为true时表示水平方向合并,为false时表示垂直方向合并
* @return 返回合并后的BufferedImage对象
*/
public static BufferedImage mergeImage(BufferedImage img1, BufferedImage img2, boolean isHorizontal) throws IOException {
int w1 = ();
int h1 = ();
int w2 = ();
int h2 = ();
// 从图片中读取RGB
int[] ImageArrayOne = new int[w1 * h1];
ImageArrayOne = (0, 0, w1, h1, ImageArrayOne, 0, w1); // 逐行扫描图像中各个像素的RGB到数组中
int[] ImageArrayTwo = new int[w2 * h2];
ImageArrayTwo = (0, 0, w2, h2, ImageArrayTwo, 0, w2);
// 生成新图片
BufferedImage DestImage;
// 水平方向合并
if (isHorizontal) {
// DestImage = new BufferedImage(w1+w2, h1, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d;
if (h1 >= h2) {
DestImage = new BufferedImage(w1 + w2, h1, BufferedImage.TYPE_INT_RGB);
} else {
DestImage = new BufferedImage(w2, h1, BufferedImage.TYPE_INT_RGB);//TYPE_INT_RGB
}
g2d = ();
();
(0, 0, w1 + w2, h1);
();
(0, 0, w1, h1, ImageArrayOne, 0, w1); // 设置上半部分或左半部分的RGB
(w1, 0, w2, h2, ImageArrayTwo, 0, w2);
} else { // 垂直方向合并
Graphics2D g2d;
if (w1 >= w2) {
DestImage = new BufferedImage(w1, h1 + h2, BufferedImage.TYPE_INT_RGB);//TYPE_INT_RGB
} else {
DestImage = new BufferedImage(w2, h1 + h2, BufferedImage.TYPE_INT_RGB);//TYPE_INT_RGB
}
g2d = ();
();
(0, 0, w1 + w2, h1 + h2);
();
(0, 0, w1, h1, ImageArrayOne, 0, w1); // 设置上半部分或左半部分的RGB
(0, h1, w2, h2, ImageArrayTwo, 0, w2); // 设置下半部分的RGB
}
return DestImage;
}
//随机生成图片名称
public static String createImageName() {
// 创建 GUID 对象
UUID uuid = ();
// 得到对象产生的ID
String a = ();
// 转换为大写
a = ();
// 替换 -
a = ("-", "");
return a;
}
public static boolean saveImage(BufferedImage savedImg, String saveDir, String fileName, String format) {
boolean flag = false;
// 先检查保存的图片格式是否正确
String[] legalFormats = { "jpg", "JPG", "png", "PNG", "bmp", "BMP" };
int i;
for (i = 0; i < ; i++) {
if ((legalFormats[i])) {
break;
}
}
if (i == ) { // 图片格式不支持
("不是保存所支持的图片格式!");
return false;
}
// 再检查文件后缀和保存的格式是否一致
String postfix = (('.') + 1);
if (!(format)) {
("待保存文件后缀和保存的格式不一致!");
return false;
}
String fileUrl = saveDir + fileName;
File file = new File(fileUrl);
try {
flag = (savedImg, format, file);
} catch (IOException e) {
();
}
return flag;
}
/**
* 经纬度格式 转换为 度分秒格式 ,如果需要的话可以调用该方法进行转换
*
* @param point 坐标点
* @return 返回时分秒格式
*/
public static String pointToLatLong(String point) {
double du = ((0, ("°")).trim());
double fen = ((("°") + 1, ("'")).trim());
double miao = ((("'") + 1, ("\"")).trim());
double duStr = du + fen / 60 + miao / 60 / 60;
return (duStr);
}
/***
* 经纬度坐标格式转换(* °转十进制格式)
* @param gps gps坐标
*/
public static double latLng2Decimal(String gps) {
String a = ("°")[0].replace(" ", "");
String b = ("°")[1].split("'")[0].replace(" ", "");
String c = ("°")[1].split("'")[1].replace(" ", "").replace("\"", "");
return (a) + (b) / 60 + (c) / 60 / 60;
}
}
2.2 地址处理工具类(主要逻辑代码都在这个类)
package ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import .slf4j.Slf4j;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
/**
* 图片地址工具类
* @author wuKeFan
* @date 2023-02-24 15:44:31
*/
@Slf4j
@Component
public class ImageAddressUtils {
@Resource
private RestTemplate restTemplate;
public String getPhotoAddress(String fileName) throws ImageProcessingException, IOException {
File file = new File(fileName);
Metadata metadata = (file);
//图片的所有目录信息
Iterable<Directory> directories = ();
for (Directory directory : directories) {
for (Tag tag : ()) {
("[{}] - {} = {}",
(), (), ());
}
if (()) {
for (String error : ()) {
("ERROR: {}", error);
}
}
}
Double lat = null;
Double lng = null;
for (Directory directory : directories) {
for (Tag tag : ()) {
String tagName = (); //标签名
String desc = (); //标签信息
switch (tagName) {
case "Image Height":
("图片高度: " + desc);
break;
case "Image Width":
("图片宽度: " + desc);
break;
case "Date/Time Original":
("拍摄时间: " + desc);
break;
case "GPS Latitude":
("纬度 : " + desc);
("纬度(度分秒格式) : " + (desc));
lat = ImageUtils.latLng2Decimal(desc);
break;
case "GPS Longitude":
("经度: " + desc);
("经度(度分秒格式): " + (desc));
lng = ImageUtils.latLng2Decimal(desc);
break;
}
}
}
//经纬度转地主使用百度api
if (lat != null && lng != null) {
ReverseGeocodingRequest request = ()
.token(BaiduMapConstants.BAIDU_MAP_TOKEN).output(BaiduMapConstants.OUTPUT_TYPE_JSON)
.coordinateType(BaiduMapConstants.COORDINATE_TYPE_GPS).lat(lat).lng(lng)
.build();
Map<String, Object> map = (request);
String result = (BaiduMapConstants.REVERSE_GEOCODING_URL, , map);
JSONObject resultObj = ((result));
if (resultObj != null && (("status"), 0)) {
AddressComponentResponse response = ("result").getObject("addressComponent", );
return "拍摄地点:" + () + " " + () + " " + () + " " + () + " "
+ () + " " + ("result").get("formattedAddress") + " " + ("result").get("business");
}
}
return null;
}
}
2.3 实体类和
package ;
import ;
/**
* 地址构成实体类
* @author wuKeFan
* @date 2022-08-18 14:48:28
*/
@Data
public class AddressComponentResponse {
/**
* 国家
*/
private String country;
/**
* 国家编码
*/
private int countryCode;
/**
* 国家英文缩写(三位)
*/
private String countryCodeIso;
/**
* 国家英文缩写(两位)
*/
private String countryCodeIso2;
/**
* 省名
*/
private String province;
/**
* 城市名
*/
private String city;
/**
* 城市所在级别(仅国外有参考意义。
* 国外行政区划与中国有差异,城市对应的层级不一定为『city』。
* country、province、city、district、town分别对应0-4级,
* 若city_level=3,则district层级为该国家的city层级)
*/
private int cityLevel;
/**
* 区县名
*/
private String district;
/**
* 乡镇名,需设置extensions_town=true时才会返回
*/
private String town;
/**
* 乡镇id
*/
private String townCode;
/**
* 相对当前坐标点的距离,
* 当有门牌号的时候返回数据
*/
private String distance;
/**
* 和当前坐标点的方向
*/
private String direction;
/**
* 行政区划代码
*/
private String adcode;
/**
* 街道名(行政区划中的街道层级)
*/
private String street;
/**
* 街道门牌号
*/
private String streetNumber;
}
package ;
import ;
import ;
import ;
import ;
/**
* 逆地理编码参数请求实体类
* @author wuKeFan
* @date 2022-08-18 14:29:15
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ReverseGeocodingRequest {
/**
* 用户申请注册的key,即ak
*/
private String token;
/**
* 输出格式为json或者xml
*/
private String output;
/**
* 坐标的类型,
* 目前支持的坐标类型包括:bd09ll(百度经纬度坐标)、
* bd09mc(百度米制坐标)、gcj02ll(国测局经纬度坐标,仅限中国)、wgs84ll( GPS经纬度)
*/
private String coordinateType;
/**
* 纬度
*/
private Double lat;
/**
* 经度
*/
private Double lng;
}
2.4 测试代码
package ;
import ;
import ;
import .slf4j.Slf4j;
import ;
import ;
import ;
import ;
import ;
/**
* 公共测试类
* @author wuKeFan
* @date 2023-02-20 09:53:14
*/
@Slf4j
@SpringBootTest
public class PublicTest {
@Resource
private ImageAddressUtils imageAddressUtils;
@Test
public void photoAddressTest() throws ImageProcessingException, IOException {
(("C:\\Users\\1\\Desktop\\2023_02_18_20_21_IMG_0057.JPG"));
}
}
运行结果如图: