|
|
@@ -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(
|