java实现手机图片分类(2021.07.07)

背景:

我有整理手机照片的习惯,将手机照片和视频导入到电脑中时的样子是这样的:

github 博客浏览

杂乱无章,影响美感!

有不少照片是以时间戳的方式命名的,如:mmexport1537331635361.jpg尽管可以利用工具进行线上转化,然后再手动命名

这样虽然可以,但是效率虐低,还显得有点愚蠢,于是我想利用代码来进行自动分类,分类后的结果是这样的:

解决办法

  • 将run.bat复制到要进行整理的文件夹下

  • 双击

路径为jar包路径,run.bat 脚本如下:

java -jar D:\MyJava\2021.5_home\6.9-photoTimeGet\demo\target\demo.jar  %~dp0
 pause

上面的几个文件就自动被分配到了2个文件夹2018、2021中,文件夹就是他们名称中包含的时间

愉快的解决!

源码

import com.drew.imaging.ImageMetadataReader;
 import com.drew.imaging.ImageProcessingException;
 import com.drew.metadata.Metadata;
 import org.apache.commons.imaging.ImageReadException;
 import org.apache.commons.imaging.ImageWriteException;
 import org.apache.commons.imaging.Imaging;
 import org.apache.commons.imaging.common.ImageMetadata;
 import org.apache.commons.imaging.formats.jpeg.JpegImageMetadata;
 import org.apache.commons.imaging.formats.jpeg.exif.ExifRewriter;
 import org.apache.commons.imaging.formats.tiff.TiffImageMetadata;
 import org.apache.commons.imaging.formats.tiff.constants.ExifTagConstants;
 import org.apache.commons.imaging.formats.tiff.write.TiffOutputDirectory;
 import org.apache.commons.imaging.formats.tiff.write.TiffOutputSet;
 ​
 import java.io.BufferedOutputStream;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 ​
 public class M {
 ​
     public static void main(String[] args){
         demo(args[0]);
         System.out.println("memeda...  " + args[0]);
         //demo("C:\\Users\\Administrator\\Desktop\\imgdemo\\2020.12-01\\D");
     }
 ​
     public  static void demo(String dirName){
         File file = new File(dirName);
         String[] list = file.list();
 ​
         for (String fileName : list) {
 ​
             try {
                 //将形如以下三类的 直接进行分到月份文件中
                 //wx_20210601_050627、sc_20210703_153148、IMG_20210629_193059
                 if(fileName.startsWith("wx_20") || fileName.startsWith("sc_") || fileName.startsWith("IMG_")|| fileName.startsWith("VID_")){
                     situation3(dirName,fileName);
                 }else
 ​
                     //4.Screenshot_20210206_150129.jpg
                     if(fileName.startsWith("Sc")){
                         int start = 11;
                         situation14(start,dirName,fileName);
                     }
                     //2.mmexport1612178190861.jpg      2021-02-01 19:16:30
                     //3.wx_camera_1617879049583.jpg
                     else if(fileName.startsWith("mm") || fileName.startsWith("wx")){
                         //获取 年月
                         int start = fileName.startsWith("wx")?10:8;
                         situation23(start,dirName,fileName);
                     }
                     //1608219722461.mp4   1608219722461.jpeg
                     else if(fileName.length()==17 || fileName.length()==18){
                         //获取 年月
                         situation23(0,dirName,fileName);
                     }else {
 ​
                         System.out.println("未知类型图片   " + fileName);
                         continue;
                     }
             }catch (Exception e){
                 System.out.println(fileName + "——————"+e);
             }
         }
     }
 ​
     private static void situation3(String dirName, String fileName) {
         //wx_20210601_050627
         //sc_20210703_153148
         //IMG_20210629_193059
         //获取 年月
         String time = fileName.split("_")[1];
         String year = time.substring(0,4);
         String month = time.substring(4,6);
         //创建文件夹
         String newdirName = dirName+"\\"+year+"\\"+month;
         File dirNew = new File(newdirName);
         if(!dirNew.exists()){
             dirNew.mkdirs();
         }
         String absPath = dirName+ "\\" + fileName;
         move_file(absPath,newdirName,fileName,null);
     }
 ​
     //2.mmexport1612178190861.jpg      2021-02-01 19:16:30
     //3.wx_camera_1617879049583.jpg
     private static void situation23(int start,String dirName, String srcName) {
         //获取 年月
         long time2 = new Long(srcName.substring(start,start+13));
 ​
         String timeStr = new SimpleDateFormat("yyyyMMdd_hhMMss").format(time2);
         String year = timeStr.substring(0,4);
         String month = timeStr.substring(4,6);
 //      创建文件夹
         String newdirName = dirName+"\\"+year+"\\"+month;
         File dirNew = new File(newdirName);
         if(!dirNew.exists()){
             dirNew.mkdirs();
         }
         String newFileName = "wx_" + timeStr+srcName.substring(srcName.lastIndexOf("."));
         String absoulteSrcPath = dirName +"\\" + srcName;
         move_file(absoulteSrcPath,newdirName,srcName,newFileName);
     }
 ​
     //4.Screenshot_20210206_150129.jpg
     private static void situation14(int start,String dirName,String fileName) {
 //        String timeStr = fileName.substring(11);
 //      获取 年月
         String year = fileName.substring(start,start+4);
         String month = fileName.substring(start+4,start+6);
 //      创建文件夹
         File dirNew = new File(dirName+"/"+year+"/"+month);
         if(!dirNew.exists()){
             dirNew.mkdirs();
         }
         //Screenshot_20210614_104229_com.google.android.apps.maps
         // 改为 sc_20210614_104229
         //changePicTime(fileAbsPath,timeStr);
         String[] s = fileName.split("_");
         String newFileName = "sc_"+ s[1] + "_" + s[2]+".jpg";
         String fileAbsPath = dirName + "/" + fileName;
         move_file(fileAbsPath,dirNew.getAbsolutePath(),fileName,newFileName);
     }
 ​
     public static String move_file(String absoulteSrcPath, String absoulteDestDir,
                                    String srcFileName,String newFileName){
         //判断当前文件夹下是否有重名的文件
         File file = new File(absoulteSrcPath);
         newFileName = newFileName == null?file.getName():newFileName;
         String[] list = new File(absoulteDestDir).list();
 ​
         if(list!=null && list.length>0){
             ArrayList<String> fileList = new ArrayList<>();
             for (String s : list) {
                 fileList.add(s);
             }
             if(fileList.contains(newFileName)){
                 newFileName = createNewName(fileList,newFileName);
             }
         }
         boolean b = file.renameTo(new File(absoulteDestDir,newFileName));
         if(b){
             System.out.println("成功----- "+srcFileName +" >> " + newFileName);
         }else {
             System.out.println("失败..... " +srcFileName);
         }
         return b?absoulteDestDir+"\\" + newFileName:null;
     }
     //生成不重名的文件名称
     public static String createNewName(ArrayList<String> fileList, String s) {
         String temp = s;
         int count =1;
         while (fileList.contains(temp)){
             temp = s.split("\\.")[0]+"_"+count+"."+s.split("\\.")[1];
             count++;
         }
         return temp;
     }
 }

打包

直接参考这个,有2点需要注意

  • 路径直接选在src下就行

  • main函数要选 src/main下的,不能选择test文件夹下的,不然报错。。

jar包百度云 提取码:6666

待优化,修改拍摄的时间

 //    "C:\\Users\\Administrator\\Desktop\\demo\\d.jpg"
 //    "1999:01:01 01:01:01"
 //    将照片变为  20201006_120000.jpg 命名的照片,同时将照片的拍摄时间修改
 public static void changePicTime(String fileAbsPath,String timeStr){
         String newAbsPath = new File(fileAbsPath).getParent()+"\\"+timeStr.replace(" ","_").replace(":","")+".jpg";
 ​
         //读文件
         File file = new File(fileAbsPath);
         boolean exists = file.exists();
         try {
             //获取ImageMetadata对象实例
             ImageMetadata metadata = Imaging.getMetadata(file);
             //强转为JpegImageMetadata
             JpegImageMetadata jpegMetadata = (JpegImageMetadata) metadata;
             if(jpegMetadata == null){
                 System.out.println(fileAbsPath + " 无法解析该照片...");
                 return;
             }
             //获取TiffImageMetadata
             TiffImageMetadata exif = jpegMetadata.getExif();
             //转换为Tiff的流
             TiffOutputSet out = exif.getOutputSet();
             //获取TiffOutputDirectory
             TiffOutputDirectory exifDirectory = out
                     .getOrCreateExifDirectory();
             //移除拍摄时间
             exifDirectory.removeField(ExifTagConstants.EXIF_TAG_DATE_TIME_ORIGINAL);
             exifDirectory.removeField(ExifTagConstants.EXIF_TAG_DATE_TIME_DIGITIZED);
             //初始化当前时间
             //String date = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss").format(new Date());
             //添加拍摄时间,格式为yyyy:MM:dd HH:mm:ss
             exifDirectory.add(ExifTagConstants.EXIF_TAG_DATE_TIME_ORIGINAL, timeStr);
             exifDirectory.add(ExifTagConstants.EXIF_TAG_DATE_TIME_DIGITIZED,timeStr);
             //新建输出流保存文件
 ​
             BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(newAbsPath));
             //写图片
             new ExifRewriter().updateExifMetadataLossless(file, bos, out);
 ​
         } catch (ImageReadException e) {
             e.printStackTrace();
         } catch (IOException e) {
             e.printStackTrace();
         } catch (ImageWriteException e) {
             e.printStackTrace();
         }finally {
             file.delete();
         }
     }

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值