Просмотр исходного кода

Merge remote-tracking branch 'origin/master' into master

zhangyuting 5 лет назад
Родитель
Сommit
aa738fa166

+ 3 - 0
.gitignore

@@ -31,3 +31,6 @@ build/
 
 ### VS Code ###
 .vscode/
+
+### Logs ###
+*.log

+ 5 - 0
pom.xml

@@ -18,6 +18,11 @@
 	</properties>
 	<dependencies>
 		<dependency>
+			<groupId>commons-io</groupId>
+			<artifactId>commons-io</artifactId>
+			<version>2.6</version>
+		</dependency>
+		<dependency>
 			<groupId>org.springframework.boot</groupId>
 			<artifactId>spring-boot-starter-jdbc</artifactId>
 		</dependency>

+ 50 - 0
src/main/java/com/mokasz/image_pool/algorithm/OpenCvService.java

@@ -0,0 +1,50 @@
+package com.mokasz.image_pool.algorithm;
+
+import org.bytedeco.javacpp.Loader;
+import org.bytedeco.opencv.opencv_java;
+import org.opencv.core.Mat;
+import org.opencv.core.MatOfByte;
+import org.opencv.img_hash.PHash;
+import org.opencv.imgcodecs.Imgcodecs;
+
+public class OpenCvService {
+    // 静态初始化 OpenCV
+    static {
+        Loader.load(opencv_java.class);
+    }
+    private final PHash pHash = PHash.create();
+    public static final int HashLength = 8;
+
+    private static void transformMatToArrayOfFloat(Mat mat, float[] floats) {
+        if (mat.width() != HashLength || mat.height() != 1) {
+            throw new RuntimeException("Matrix dimension is not 1x8");
+        }
+        for (int i = 0; i < HashLength; i++) {
+            floats[i] = (float) mat.get(0, i)[0];
+        }
+    }
+
+    public void calculatePHash (byte[] fileBytes, float[] vector) {
+        Mat input = Imgcodecs.imdecode(new MatOfByte(fileBytes), Imgcodecs.IMREAD_UNCHANGED);
+        Mat output = new Mat();
+        pHash.compute(input, output);
+        transformMatToArrayOfFloat(output, vector);
+    }
+
+    public void transformBinaryArray(float[] octets, float[] binaries) {
+        for (int i = 0; i < HashLength; i++) {
+            for (int j = 0; j < HashLength; j++) {
+                int v = (int) octets[i];
+                binaries[i * 8 + j] = (v & (1 << j)) >> j;
+            }
+        }
+    }
+
+    public String getReadableHash(float[] floats) {
+        StringBuilder stringBuilder = new StringBuilder();
+        for (int i = 0; i < HashLength; i++) {
+            stringBuilder.append(String.format("%02X", (int) floats[i]));
+        }
+        return stringBuilder.toString();
+    }
+}

+ 23 - 58
src/main/java/com/mokasz/image_pool/restful/controller/ImageController.java

@@ -1,14 +1,9 @@
 package com.mokasz.image_pool.restful.controller;
 
-import com.mokasz.image_pool.algorithm.FeatureExtractor;
+import com.mokasz.image_pool.algorithm.OpenCvService;
 import com.mokasz.image_pool.restful.entity.ImageQueryResponse;
 import com.mokasz.image_pool.restful.entity.ImageSaveResponse;
-import org.bytedeco.javacpp.Loader;
-import org.bytedeco.opencv.opencv_java;
-import org.opencv.core.Mat;
-import org.opencv.core.MatOfByte;
-import org.opencv.img_hash.PHash;
-import org.opencv.imgcodecs.Imgcodecs;
+import com.mokasz.image_pool.restful.service.DownloadBytes;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -23,69 +18,38 @@ import java.util.List;
 @RestController
 @RequestMapping("/service/image")
 public class ImageController {
-  // 静态初始化 OpenCV
-  static {
-    Loader.load(opencv_java.class);
-  }
 
   private final Logger logger = LoggerFactory.getLogger(this.getClass());
-  private final PHash pHash = PHash.create();
+  private final OpenCvService service = new OpenCvService();
   @Autowired private JdbcTemplate jdbcTemplate;
 
-  private void calculate(byte[] fileBytes, float[] vector) {
-    Mat input = Imgcodecs.imdecode(new MatOfByte(fileBytes), Imgcodecs.IMREAD_UNCHANGED);
-    Mat output = new Mat();
-    pHash.compute(input, output);
-    transformMatToArrayOfFloat(output, vector);
-  }
-
-  private void transformMatToArrayOfFloat(Mat mat, float[] floats) {
-    if (mat.width() != 8 || mat.height() != 1) {
-      throw new RuntimeException("Matrix dimension is not 1x8");
-    }
-    for (int i = 0; i < 8; i++) {
-      floats[i] = (float) mat.get(0, i)[0];
-    }
-  }
-
-  private void transformBinaryArray(float[] octets, float[] binaries) {
-    for (int i = 0; i < 8; i++) {
-      for (int j = 0; j < 8; j++) {
-        int v = (int) octets[i];
-        binaries[i * 8 + j] = (v & (1 << j)) >> j;
-      }
-    }
-  }
-
-  private String getReadableHash(float[] floats) {
-    StringBuilder stringBuilder = new StringBuilder();
-    for (int i = 0; i < 8; i++) {
-      stringBuilder.append(String.format("%02X", (int) floats[i]));
-    }
-    return stringBuilder.toString();
-  }
-
   @GetMapping("/")
   public ImageSaveResponse index() throws IOException {
     return new ImageSaveResponse("ok", 0);
   }
 
-  @PostMapping("/store2")
-  public ImageSaveResponse store2(@RequestParam("file") MultipartFile file) throws IOException {
-    FeatureExtractor.compute(file.getBytes());
-    return new ImageSaveResponse("OK", 1L);
+  private byte[] getFileBytes (MultipartFile file, String url) throws IOException {
+    if (url != null) {
+      return DownloadBytes.downloadAsBytesArray(url);
+    } else if (file != null) {
+      logger.info("File size: {} Name: {}", file.getSize(), file.getOriginalFilename());
+      return file.getBytes();
+    } else {
+      throw new RuntimeException("缺少file或url");
+    }
   }
 
   @PostMapping("/store")
   public ImageSaveResponse store(
-      @RequestParam("file") MultipartFile file, @RequestParam("pool") int pool) throws IOException {
-    logger.info("File size: {} Name: {}", file.getSize(), file.getOriginalFilename());
+      @RequestParam(value = "file", required = false) MultipartFile file,
+      @RequestParam(value = "url", required = false) String url,
+      @RequestParam("pool") int pool) throws IOException {
     float[] floats = new float[8];
-    calculate(file.getBytes(), floats);
+    service.calculatePHash(this.getFileBytes(file, url), floats);
     float[] binaries = new float[64];
-    transformBinaryArray(floats, binaries);
+    service.transformBinaryArray(floats, binaries);
     logger.info("{}", binaries);
-    String hash = getReadableHash(floats);
+    String hash = service.getReadableHash(floats);
     int updated =
         jdbcTemplate.update(
             "INSERT INTO image_pool.image_hash VALUES (?, NOW(), ?) ON CONFLICT (hash) DO NOTHING",
@@ -96,21 +60,22 @@ public class ImageController {
         "INSERT INTO image_pool.image_to_pool VALUES (?, ?, NOW()) ON CONFLICT (hash, pool_id) DO NOTHING",
         hash,
         pool);
-    return new ImageSaveResponse(hash, 1L);
+    return new ImageSaveResponse(hash, pool);
   }
 
   @PostMapping("/match")
   public List<ImageQueryResponse> match(
-      @RequestParam("file") MultipartFile file,
+      @RequestParam(value = "file", required = false) MultipartFile file,
+      @RequestParam(value = "url", required = false) String url,
       @RequestParam("pool") int pool,
       @RequestParam(value = "max", defaultValue = "1") float max,
       @RequestParam(value = "min", defaultValue = "1") float min,
       @RequestParam(value = "limit", defaultValue = "10") int limit)
       throws IOException {
     float[] floats = new float[8];
-    calculate(file.getBytes(), floats);
+    service.calculatePHash(this.getFileBytes(file, url), floats);
     float[] binaries = new float[64];
-    transformBinaryArray(floats, binaries);
+    service.transformBinaryArray(floats, binaries);
     logger.info("{}", floats);
     List<ImageQueryResponse> list =
         jdbcTemplate.query(

+ 1 - 1
src/main/java/com/mokasz/image_pool/restful/entity/ImageSaveResponse.java

@@ -5,5 +5,5 @@ import lombok.Data;
 @Data
 public class ImageSaveResponse {
     private final String hash;
-    private final long copies;
+    private final int pool_id;
 }

+ 0 - 0
src/main/java/com/mokasz/image_pool/restful/service/.gitkeep


+ 12 - 0
src/main/java/com/mokasz/image_pool/restful/service/DownloadBytes.java

@@ -0,0 +1,12 @@
+package com.mokasz.image_pool.restful.service;
+
+import org.apache.commons.io.IOUtils;
+
+import java.io.IOException;
+import java.net.URL;
+
+public class DownloadBytes {
+    public static byte[] downloadAsBytesArray (String url) throws IOException {
+        return IOUtils.toByteArray(new URL(url));
+    }
+}