仗剑走天涯

个人站

苟若恒,何必三更起五更眠,最无益,莫过一日暴十日寒


java实现手机图片按年月进行自动分类

目录

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

背景:

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

image-20210707193216190

杂乱无章,影响美感!

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

image-20210707193346302

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

解决办法

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

  • 双击

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

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

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

image-20210707203554923

image-20210707203227464

image-20210707203312931

愉快的解决!

源码

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();
        }
    }