关于图片相关的接口

146 阅读2分钟

背景

最近涉及到图片上传存储、获取等接口的开发,以此进行相关设计

思路

主要两个接口:

上传图片:读取本地图片,然后以二进制方式上传,服务端存储在对象存储上(例如S3、COS等)
获取图片:根据key名字获取图片的二进制

上传图片

public class Controller {
    @RequestMapping(path = {"/add-image"}, method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)  
    public ResData addImage(@RequestParam("image")MultipartFile image, @RequestParam("label") String label, @RequestParam("t") String t) throws Exception {  
        ResData resData = new ResData();  
        log.info("keyId:" + label);  
        log.info("t:" + t);  
        String objectName = new String();  
        if (t.equals("top")) {  
        objectName = "top_1000/top" + label + ".jpeg";  
        } else if (t.equals("bot")) {  
        objectName = "bot_1000/bot" + label + ".jpeg";  
        } else {  
        resData.code = 601;  
        resData.msg = "t is not right";  
        return resData;  
        }  
        byte[] input = image.getBytes();  
        
        amazonS3.putObject(bucketName, objectName, new ByteArrayInputStream(input), null);  
        resData.code = 200;  
        resData.msg = "ok";  
        resData.data = objectName;  
        return resData;  
    }
}

测试

package main

import (
   "bytes"
   "fmt"
   "io"
   "mime/multipart"
   "net/http"
   "os"
)

func main() {
   url := "http://localhost:8080/eve/cmdb/rest/equipment/add-image"

   // 读取图片文件
   imagePath := "golang.png"
   imageFile, err := os.Open(imagePath)
   if err != nil {
      fmt.Println("Error opening image file:", err)
      return
   }
   defer imageFile.Close()

   // 创建multipart form
   body := &bytes.Buffer{}
   writer := multipart.NewWriter(body)
   part, err := writer.CreateFormFile("image", imagePath)
   if err != nil {
      fmt.Println("Error creating form file:", err)
      return
   }

   // 将图片文件写入multipart form
   imageBytes, err := io.ReadAll(imageFile)
   if err != nil {
      fmt.Println("Error reading image file:", err)
      return
   }
   part.Write(imageBytes)
   //writer.WriteField("keyId", "20190625035")
   //writer.WriteField("t", "top")

   keyPart, err := writer.CreateFormField("keyId")
   if err != nil {
      fmt.Println("Error creating form field:", err)
      return
   }

   _, err = keyPart.Write([]byte("20190625035"))
   if err != nil {
      fmt.Println("Error writing key:", err)
      return
   }

   tPart, err := writer.CreateFormField("t")
   tPart.Write([]byte("top"))

   // 关闭multipart writer
   err = writer.Close()
   if err != nil {
      fmt.Println("Error closing multipart writer:", err)
      return
   }

   // 创建HTTP请求
   req, err := http.NewRequest("POST", url, body)
   if err != nil {
      fmt.Println("Error creating request:", err)
      return
   }
   req.Header.Set("Content-Type", writer.FormDataContentType()

   // 发送HTTP请求
   client := &http.Client{}
   resp, err := client.Do(req)
   if err != nil {
      fmt.Println("Error sending request:", err)
      return
   }
   defer resp.Body.Close()
   rBody, _ := io.ReadAll(resp.Body)

   // 输出响应状态
   fmt.Println("Response body:", string(rBody))
}

获取图片

public class Controller {
   @RequestMapping(path = {"/get-image"}, method = RequestMethod.GET, produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
    @ResponseBody
    public ResponseEntity<byte[]> getImage(@RequestParam("label") String label, @RequestParam("t") String t) throws Exception {
        List<byte[]> imageBytesList = new ArrayList<>();
        String objectName = new String();
        if (t.equals("top")) {
            objectName = "top_1000/top" + label + ".jpeg";
        } else if (t.equals("bot")) {
            objectName = "bot_1000/bot" + label + ".jpeg";
        } else {
            return null;
        }
        try {
            S3Object s3Object = amazonS3.getObject(bucketName, objectName);
            InputStream content = s3Object.getObjectContent();
            log.info("content:" + content);
            S3ObjectInputStream inputStream = s3Object.getObjectContent();
            byte[] imageBytes = IOUtils.toByteArray(inputStream);

            log.info("image bytes:" + imageBytes);
            imageBytesList.add(imageBytes);

//        HttpHeaders headers = new HttpHeaders();
//        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);

            return ResponseEntity.ok().contentType(MediaType.APPLICATION_OCTET_STREAM).body(imageBytes);
        } catch (Exception e) {
            return null;
        }

//        return  new ResponseEntity<>(imageBytesList, headers, HttpStatus.OK);
    }
}

测试

//go:build ignore
// +build ignore

package main

import (
   "fmt"
   "io"
   "net/http"
   "os"
)

func main() {
   url := "http://localhost:8080/eve/cmdb/rest/equipment/get-image"
   //keys := "golang.png"

   req, err := http.NewRequest("GET", url, nil)
   if err != nil {
      fmt.Println("Error creating request:", err)
      return
   }
   req.Header.Set("Accept", "application/octet-stream")

   q := req.URL.Query()
   q.Add("keyId", "20190625035")
   q.Add("t", "top")
   req.URL.RawQuery = q.Encode()

   client := &http.Client{}
   resp, err := client.Do(req)
   if err != nil {
      fmt.Println("Error making request:", err)
      return
   }
   defer resp.Body.Close()
   fmt.Println("resp status:", resp.StatusCode)
   data, err := io.ReadAll(resp.Body)
   fmt.Println("resp body:", data)

   if resp.StatusCode == http.StatusOK {

      if err != nil {
         fmt.Println("Error reading response body:", err)
         return
      }

      // Process the data (List of byte arrays) as needed
      fmt.Println("Received images data:", data)

      imageName := "golang_get2.png"
      err := os.WriteFile(imageName, data, 0644)
      if err != nil {
         fmt.Println("Error saving image:", err)
      } else {
         fmt.Println("Image saved:", imageName)
      }
   } else {
      fmt.Println("Error fetching images:", resp.Status)
   }
}