ImageController.java 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. package com.mokasz.image_pool.restful.controller;
  2. import com.mokasz.image_pool.algorithm.OpenCvService;
  3. import com.mokasz.image_pool.restful.entity.ImageQueryResponse;
  4. import com.mokasz.image_pool.restful.entity.ImageSaveResponse;
  5. import com.mokasz.image_pool.restful.service.DownloadBytes;
  6. import lombok.RequiredArgsConstructor;
  7. import lombok.extern.slf4j.Slf4j;
  8. import org.springframework.jdbc.core.JdbcTemplate;
  9. import org.springframework.web.bind.annotation.*;
  10. import org.springframework.web.multipart.MultipartFile;
  11. import java.io.IOException;
  12. import java.sql.ResultSet;
  13. import java.util.List;
  14. @Slf4j
  15. @RestController
  16. @RequestMapping("/service/image")
  17. @RequiredArgsConstructor
  18. public class ImageController {
  19. private final OpenCvService service;
  20. private final JdbcTemplate jdbcTemplate;
  21. private byte[] getFileBytes (MultipartFile file, String url) throws IOException {
  22. if (url != null) {
  23. return DownloadBytes.downloadAsBytesArray(url);
  24. } else if (file != null) {
  25. return file.getBytes();
  26. } else {
  27. throw new RuntimeException("缺少file或url");
  28. }
  29. }
  30. @PostMapping("/store")
  31. public ImageSaveResponse store(
  32. @RequestParam(value = "file", required = false) MultipartFile file,
  33. @RequestParam(value = "url", required = false) String url,
  34. @RequestParam("pool") int pool) throws IOException {
  35. float[] floats = new float[8];
  36. service.calculatePHash(this.getFileBytes(file, url), floats);
  37. log.info("size:",floats);
  38. float[] binaries = new float[64];
  39. service.transformBinaryArray(floats, binaries);
  40. String hash = service.getReadableHash(floats);
  41. jdbcTemplate.update(
  42. "INSERT INTO image_pool.image_hash VALUES (?, NOW(), ?) ON CONFLICT (hash) DO NOTHING",
  43. hash,
  44. binaries);
  45. jdbcTemplate.update(
  46. "INSERT INTO image_pool.image_to_pool VALUES (?, ?, NOW()) ON CONFLICT (hash, pool_id) DO NOTHING",
  47. hash,
  48. pool);
  49. return new ImageSaveResponse(hash, pool);
  50. }
  51. @PostMapping("/match")
  52. public List<ImageQueryResponse> match(
  53. @RequestParam(value = "file", required = false) MultipartFile file,
  54. @RequestParam(value = "url", required = false) String url,
  55. @RequestParam("pool") int pool,
  56. @RequestParam(value = "max", defaultValue = "1") float max,
  57. @RequestParam(value = "min", defaultValue = "1") float min,
  58. @RequestParam(value = "limit", defaultValue = "10") int limit)
  59. throws IOException {
  60. float[] floats = new float[8];
  61. service.calculatePHash(this.getFileBytes(file, url), floats);
  62. float[] binaries = new float[64];
  63. service.transformBinaryArray(floats, binaries);
  64. List<ImageQueryResponse> list =
  65. jdbcTemplate.query(
  66. "SELECT * FROM (SELECT hash, (64 - l2_distance(?::FLOAT2[], vector)) / 64 AS similarity FROM image_pool.image_hash WHERE hash IN (SELECT hash FROM image_pool.image_to_pool WHERE pool_id = ?) ORDER BY vector <-> ?::FLOAT2[] ASC) t WHERE similarity >=? and similarity<=? ORDER BY similarity DESC LIMIT ?",
  67. (ResultSet rs, int rowNum) ->
  68. new ImageQueryResponse(rs.getFloat("similarity"), rs.getString("hash")),
  69. binaries,
  70. pool,
  71. binaries,
  72. min,
  73. max,
  74. limit);
  75. return list;
  76. }
  77. }