Browse Source

手动上传ZIP图片压缩文件

S0025136190 1 year ago
parent
commit
ed82b27582

+ 23 - 9
Backend/sample/src/main/java/com/dji/sample/common/util/PicExifUtil.java

@@ -5,6 +5,8 @@ import com.dji.sample.component.oss.model.OssConfiguration;
 import com.dji.sample.component.oss.service.impl.OssServiceContext;
 import com.dji.sample.media.model.MediaExifDTO;
 import com.drew.imaging.ImageMetadataReader;
+import com.drew.imaging.jpeg.JpegMetadataReader;
+import com.drew.imaging.mp4.Mp4MetadataReader;
 import com.drew.metadata.Metadata;
 import com.drew.metadata.exif.*;
 import com.drew.metadata.file.FileTypeDirectory;
@@ -77,19 +79,31 @@ public class PicExifUtil {
             } else {
                 //经纬度
                 GpsDirectory gpsDirectory = metadata.getFirstDirectoryOfType(GpsDirectory.class);
-                builder.absoluteAltitude(gpsDirectory.getDouble(GpsDirectory.TAG_ALTITUDE));
-                builder.longitude(gpsDirectory.getGeoLocation().getLongitude());
-                builder.longitudeRef(gpsDirectory.getString(GpsDirectory.TAG_LONGITUDE_REF));
-                builder.latitude(gpsDirectory.getGeoLocation().getLatitude());
-                builder.latitudeRef(gpsDirectory.getString(GpsDirectory.TAG_LATITUDE_REF));
+                if(gpsDirectory !=  null) {
+                    builder.absoluteAltitude(gpsDirectory.getDouble(GpsDirectory.TAG_ALTITUDE));
+                    builder.longitude(gpsDirectory.getGeoLocation().getLongitude());
+                    builder.longitudeRef(gpsDirectory.getString(GpsDirectory.TAG_LONGITUDE_REF));
+                    builder.latitude(gpsDirectory.getGeoLocation().getLatitude());
+                    builder.latitudeRef(gpsDirectory.getString(GpsDirectory.TAG_LATITUDE_REF));
+                } else {
+                    log.info("============图片未获取到经纬度");
+                }
                 //分辨率
                 ExifIFD0Directory exifIFD0Directory = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class);
-                builder.xResolution(exifIFD0Directory.getInteger(ExifIFD0Directory.TAG_X_RESOLUTION));
-                builder.yResolution(exifIFD0Directory.getInteger(ExifIFD0Directory.TAG_Y_RESOLUTION));
+                if(exifIFD0Directory != null) {
+                    builder.xResolution(exifIFD0Directory.getInteger(ExifIFD0Directory.TAG_X_RESOLUTION));
+                    builder.yResolution(exifIFD0Directory.getInteger(ExifIFD0Directory.TAG_Y_RESOLUTION));
+                } else {
+                    log.info("============图片未获取到分辨率");
+                }
                 //图片宽高
                 ExifSubIFDDirectory exifSubIFDDirectory = metadata.getFirstDirectoryOfType(ExifSubIFDDirectory.class);
-                builder.imageWidth(exifSubIFDDirectory.getInteger(ExifSubIFDDirectory.TAG_EXIF_IMAGE_WIDTH));
-                builder.imageHeight(exifSubIFDDirectory.getInteger(ExifSubIFDDirectory.TAG_EXIF_IMAGE_HEIGHT));
+                if(exifIFD0Directory != null) {
+                    builder.imageWidth(exifSubIFDDirectory.getInteger(ExifSubIFDDirectory.TAG_EXIF_IMAGE_WIDTH));
+                    builder.imageHeight(exifSubIFDDirectory.getInteger(ExifSubIFDDirectory.TAG_EXIF_IMAGE_HEIGHT));
+                } else {
+                    log.info("============图片未获取到宽高 ");
+                }
             }
             //媒体类型
             FileTypeDirectory fileTypeDirectory = metadata.getFirstDirectoryOfType(FileTypeDirectory.class);

+ 17 - 0
Backend/sample/src/main/java/com/dji/sample/media/controller/FileController.java

@@ -147,6 +147,23 @@ public class FileController {
         return HttpResultResponse.success();
     }
 
+    /**
+     * 上传图片文件(zip)
+     * @param file
+     * @return
+     */
+    @PostMapping("/{workspace_id}/file/zip/upload")
+    public HttpResultResponse importZipFile(HttpServletRequest request, MultipartFile file) {
+        if (Objects.isNull(file)) {
+            return HttpResultResponse.error("没有接收到任何文件");
+        }
+        CustomClaim customClaim = (CustomClaim)request.getAttribute(TOKEN_CLAIM);
+        String workspaceId = customClaim.getWorkspaceId();
+        String creator = customClaim.getUsername();
+        fileService.importZipFile(file, workspaceId, creator);
+        return HttpResultResponse.success();
+    }
+
     /**
      * 上传文件
      * @param file

+ 2 - 0
Backend/sample/src/main/java/com/dji/sample/media/service/IFileService.java

@@ -115,4 +115,6 @@ public interface IFileService {
     void deleteByDirId(String dirId);
 
     void deleteFileById(String id);
+
+    public void importZipFile(MultipartFile file, String workspaceId, String creator);
 }

+ 152 - 21
Backend/sample/src/main/java/com/dji/sample/media/service/impl/FileServiceImpl.java

@@ -22,6 +22,7 @@ import com.dji.sample.media.model.*;
 import com.dji.sample.media.service.IFileService;
 import com.dji.sample.media.service.IMediaDirService;
 import com.dji.sample.wayline.dao.IWaylineJobMapper;
+import com.dji.sample.wayline.model.dto.WaylineFileDTO;
 import com.dji.sample.wayline.model.entity.WaylineJobEntity;
 import com.dji.sample.wayline.service.IWaylineFileService;
 import com.dji.sdk.cloudapi.device.DeviceEnum;
@@ -33,6 +34,9 @@ import com.dji.sdk.common.CoordinateUtil;
 import com.dji.sdk.common.Pagination;
 import com.dji.sdk.common.PaginationData;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.compress.archivers.ArchiveEntry;
+import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
+import org.dom4j.Document;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.MediaType;
 import org.springframework.stereotype.Service;
@@ -48,12 +52,15 @@ import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.net.URL;
 import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
 import java.time.Instant;
 import java.time.LocalDateTime;
 import java.time.ZoneId;
 import java.util.*;
 import java.util.concurrent.Executor;
 import java.util.stream.Collectors;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
 
 /**
  * @author sean
@@ -105,7 +112,9 @@ public class FileServiceImpl implements IFileService {
     private static final String DOT = ".";
     private static final String SPLIT_DOT = "\\.";
     private static final String JPEG = "JPEG";
+    private static final String JPG = "JPG";
     private static final String MP4 = "MP4";
+    private static final String ZIP_FILE_SUFFIX = ".zip";
 
     private Optional<MediaFileEntity> getMediaByFingerprint(String workspaceId, String fingerprint) {
         MediaFileEntity fileEntity = mapper.selectOne(new LambdaQueryWrapper<MediaFileEntity>()
@@ -205,41 +214,37 @@ public class FileServiceImpl implements IFileService {
         fileEntity.setFileId(UUID.randomUUID().toString());
         int result = mapper.insert(fileEntity);
         //更新exif信息
-        updateExifInfo(fileEntity,workspaceId,file);
+        updateExifInfo(fileEntity,workspaceId,file.getObjectKey(), file.getName());
         return result;
     }
 
-    private void updateExifInfo(MediaFileEntity fileEntity, String workspaceId, MediaUploadCallbackRequest file) {
+    private void updateExifInfo(MediaFileEntity fileEntity, String workspaceId,String objectKey, String fileName) {
         //生成缩略图
         fileThreadPool.execute(new Runnable() {
             @Override
             public void run() {
                 try {
-                    String objectKey = file.getObjectKey();
-
                     //生成缩略图
-                    String tObjectKey = getThumbnailObjectKey(file.getName());
+                    String tObjectKey = getThumbnailObjectKey(fileName);
                     putThumbnailImage(tObjectKey, objectKey, true);
 
                     //获取图片信息
                     MediaExifDTO exif = PicExifUtil.getPicExif(objectKey);
 
-                    if (file != null) {
-                        fileEntity.setImageWidth(exif.getImageWidth());
-                        fileEntity.setImageHeight(exif.getImageHeight());
-                        fileEntity.setXResolution(exif.getXResolution());
-                        fileEntity.setYResolution(exif.getYResolution());
-                        fileEntity.setLatitude(BigDecimal.valueOf(CoordinateUtil.checkValidVal(exif.getLatitude())).setScale(14, RoundingMode.DOWN));
-                        fileEntity.setLongitude(BigDecimal.valueOf(CoordinateUtil.checkValidVal(exif.getLongitude())).setScale(14, RoundingMode.DOWN));
-                        fileEntity.setLongitudeRef(exif.getLongitudeRef());
-                        fileEntity.setLatitudeRef(exif.getLatitudeRef());
-                        fileEntity.setMediaType(exif.getPictureType());
-                        fileEntity.setPictureType(exif.getPictureType());
-                        fileEntity.setDurationSeconds(exif.getDurationSeconds());
-
-                        mapper.update(fileEntity,
-                                new LambdaUpdateWrapper<MediaFileEntity>().eq(MediaFileEntity::getFileId, fileEntity.getFileId()));
-                    }
+                    fileEntity.setImageWidth(exif.getImageWidth());
+                    fileEntity.setImageHeight(exif.getImageHeight());
+                    fileEntity.setXResolution(exif.getXResolution());
+                    fileEntity.setYResolution(exif.getYResolution());
+                    fileEntity.setLatitude(BigDecimal.valueOf(CoordinateUtil.checkValidVal(exif.getLatitude())).setScale(14, RoundingMode.DOWN));
+                    fileEntity.setLongitude(BigDecimal.valueOf(CoordinateUtil.checkValidVal(exif.getLongitude())).setScale(14, RoundingMode.DOWN));
+                    fileEntity.setLongitudeRef(exif.getLongitudeRef());
+                    fileEntity.setLatitudeRef(exif.getLatitudeRef());
+                    fileEntity.setMediaType(exif.getPictureType());
+                    fileEntity.setPictureType(exif.getPictureType());
+                    fileEntity.setDurationSeconds(exif.getDurationSeconds());
+
+                    mapper.update(fileEntity,
+                            new LambdaUpdateWrapper<MediaFileEntity>().eq(MediaFileEntity::getFileId, fileEntity.getFileId()));
                 } catch (Exception e) {
                     e.printStackTrace();
 
@@ -912,11 +917,137 @@ public class FileServiceImpl implements IFileService {
             try {
                 mapper.deleteById(id);
                 ossService.deleteObject(OssConfiguration.bucket, entity.getObjectKey());
+                ossService.deleteObject(OssConfiguration.bucket, getThumbnailObjectKey(entity.getFileName()));
             } catch (Exception e) {
                 e.printStackTrace();
             }
         }
     }
 
+    @Override
+    public void importZipFile(MultipartFile file, String workspaceId, String creator) {
+
+        String filename = file.getOriginalFilename();
+        if (Objects.nonNull(filename) && !filename.toLowerCase().endsWith(ZIP_FILE_SUFFIX)) {
+            throw new RuntimeException("文件格式不正确.");
+        }
+        String dirName = filename.substring(0, filename.toLowerCase().indexOf(ZIP_FILE_SUFFIX));
+        MediaDirDTO dirDto = mediaDirService.getMediaDirByName(workspaceId,dirName,null);
+        if(dirDto == null) {
+            //文件夹不存在,则创建文件夹
+            if (dirDto == null) {
+                MediaDirEntity.MediaDirEntityBuilder dirBuilder = MediaDirEntity.builder();
+                dirBuilder.dirName(dirName)
+                        .workspaceId(workspaceId)
+                        .waylineName("N/A")
+                        .createTime(System.currentTimeMillis())
+                        .deviceName("N/A")
+                        .payload("N/A")
+                        .username(getUserName());
+                dirDto = mediaDirService.createDir(dirBuilder.build());
+            }
+        }
+        MediaDirDTO finalDirDto = dirDto;
+
+
+        try (ZipInputStream unzipFile = new ZipInputStream(file.getInputStream())) {
+            file.getInputStream().close();
+            ZipEntry nextEntry;
+            while ((nextEntry = unzipFile.getNextEntry()) != null) {
+
+                // 手动处理文件名的编码问题
+                log.info("===========正在处理文件====:" + nextEntry.getName());
+                String[] pathArray = nextEntry.getName().split("/");
+                String entryName = pathArray[pathArray.length - 1];
+                if (!entryName.toUpperCase().endsWith(JPG) && !entryName.toUpperCase().endsWith(MP4)) {
+                    unzipFile.closeEntry();
+                    continue;
+                }
+                // 将 InputStream 读取到字节数组中
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                byte[] buffer = new byte[1024];
+                int length;
+                try {
+                    while ((length = unzipFile.read(buffer)) != -1) {
+                        baos.write(buffer, 0, length);
+                    }
+                    unzipFile.closeEntry();
+                }catch (Exception e) {
+                    log.error("===手工上传,将 InputStream 读取到字节数组中 异常");
+                    continue;
+                }
+                InputStream inputStream = new ByteArrayInputStream(baos.toByteArray());
+                baos.close();
+                uploadOssAndSave(entryName, inputStream, finalDirDto, workspaceId);
+            }
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+    }
+
+    private void uploadOssAndSave(String entryName, InputStream inputStream, MediaDirDTO finalDirDto,String workspaceId) {
+        fileThreadPool.execute(new Runnable() {
+            @Override
+            public void run() {
+                String fileId = UUID.randomUUID().toString();
+                String objectKey = OssConfiguration.objectDirPrefix + File.separator + entryName;
+
+                try {
+
+                    ossService.putObject(OssConfiguration.bucket, objectKey, inputStream);
+
+                    log.info("手动上传文件到oss成功. {}", entryName);
+
+                    MediaFileEntity fileEntity = MediaFileEntity.builder()
+                            .dirId(Integer.valueOf(finalDirDto.getId()))
+                            .fileId(fileId)
+                            .fileName(entryName)
+                            .filePath(finalDirDto.getDirName())
+                            .workspaceId(workspaceId)
+                            .objectKey(objectKey)
+                            .subFileType(0)
+                            .isOriginal(true)
+                            .size(ossService.getObjectSize(OssConfiguration.bucket, objectKey))
+                            .createTime(System.currentTimeMillis())
+                            .updateTime(System.currentTimeMillis())
+                            .build();
+
+                    mapper.insert(fileEntity);
+
+                    //生成缩略图
+                    String tObjectKey = getThumbnailObjectKey(entryName);
+                    putThumbnailImage(tObjectKey, objectKey, true);
+
+                    //获取图片信息
+                    MediaExifDTO exif = PicExifUtil.getPicExif(objectKey);
+//                    MediaExifDTO exif = PicExifUtil.getPicExif(inputStream, entryName.endsWith(MP4));
+
+                    if(exif != null) {
+                        fileEntity.setImageWidth(exif.getImageWidth());
+                        fileEntity.setImageHeight(exif.getImageHeight());
+                        fileEntity.setXResolution(exif.getXResolution());
+                        fileEntity.setYResolution(exif.getYResolution());
+                        fileEntity.setLatitude(BigDecimal.valueOf(CoordinateUtil.checkValidVal(exif.getLatitude())).setScale(14, RoundingMode.DOWN));
+                        fileEntity.setLongitude(BigDecimal.valueOf(CoordinateUtil.checkValidVal(exif.getLongitude())).setScale(14, RoundingMode.DOWN));
+                        fileEntity.setLongitudeRef(exif.getLongitudeRef());
+                        fileEntity.setLatitudeRef(exif.getLatitudeRef());
+                        fileEntity.setMediaType(exif.getPictureType());
+                        fileEntity.setPictureType(exif.getPictureType());
+                        fileEntity.setDurationSeconds(exif.getDurationSeconds());
+
+                        mapper.update(fileEntity,
+                                new LambdaUpdateWrapper<MediaFileEntity>().eq(MediaFileEntity::getFileId, fileEntity.getFileId()));
+                    }
+                } catch (Exception e) {
+                    log.error("手动上传文件失败. {}", entryName);
+                    e.printStackTrace();
+                }
+            }
+        });
+    }
+
+
 
 }

+ 2 - 0
Backend/sample/src/main/java/com/dji/sample/media/service/impl/MediaServiceImpl.java

@@ -161,6 +161,7 @@ public class MediaServiceImpl extends AbstractMediaService implements IMediaServ
         file.getExt().setSn(device.getChildDeviceSn());
 
         String jobId = callback.getFile().getExt().getFlightId();
+        log.info("================parseMediaFile======jobId:" + jobId);
         Optional<WaylineJobDTO> jobOpt = waylineJobService.getJobByJobId(device.getWorkspaceId(),jobId);
         if(jobOpt.isPresent()) {
             file.setPath(jobOpt.get().getJobName() + " " + DateUtil.format(new Date(), DatePattern.NORM_DATETIME_FORMAT));
@@ -168,6 +169,7 @@ public class MediaServiceImpl extends AbstractMediaService implements IMediaServ
             file.setPath(device.getDeviceName() + " " + DateUtil.format(new Date(), DatePattern.NORM_DATETIME_FORMAT));
         }
         CameraModeEnum cameraModeEnum = mediaRedisService.getCameraMode(device.getDeviceSn());
+        log.info("================parseMediaFile======cameraModeEnum:" + cameraModeEnum);
         if(CameraModeEnum.PANORAMA == cameraModeEnum) {
             file.setSubFileType(MediaSubFileTypeEnum.PANORAMA);
         } else {