Search code examples
javaspring-bootmultipartform-databufferedimageresttemplate

How to convert BufferedImage to a MultiPart file without saving file to disk?


I want to make a service call that takes in the following Request Parameter in a rest service. This method uploads file to an image server.

 @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public ResponseEntity<String> uploadFile(
            @RequestParam("file") MultipartFile file) {

Following is the code where the call to the service is being made - I read an image in a BufferedImage object from a image url

     BufferedImage subImage= ImageIO.read(new URL(<some image url goes here>));
     File outputFile = new File("C:\\" + "myimage" + ".jpg");

    ImageIO.write(subImage, "jpg", outputFile);

    MultiValueMap<String, Object> body = new LinkedMultiValueMap<String, Object>();
    String url="http://serviceurl/upload";

    body.add("file", outputFile);

    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.MULTIPART_FORM_DATA);

    HttpEntity<MultiValueMap<String, Object>> entity = new HttpEntity<MultiValueMap<String, Object>>(body, headers);

    restTemplate.exchange(url, HttpMethod.POST, entity, String.class);

AS you can see, a file is first being created and saved to the disk. How can I avoid this step and just use BufferedImage object (I do not want to save the file to the local disk).

Tried the solution below but it seems to me that you cannot achieve this without saving file on your disk. Is that true?


Solution

  • you can do it in this way.. I have created an implementation class of MultipartFile and I am using that newly created class to create a MultipartFile file.

    MultipartFile Implementation

    public class MultipartImage implements MultipartFile {
    
    
    private byte[] bytes;
    String name;
    String originalFilename;
    String contentType;
    boolean isEmpty;
    long size;
    
    public MultipartImage(byte[] bytes, String name, String originalFilename, String contentType,
            long size) {
        this.bytes = bytes;
        this.name = name;
        this.originalFilename = originalFilename;
        this.contentType = contentType;
        this.size = size;
        this.isEmpty = false;
    }
    
    @Override
    public String getName() {
        return name;
    }
    
    @Override
    public String getOriginalFilename() {
        return originalFilename;
    }
    
    @Override
    public String getContentType() {
        return contentType;
    }
    
    @Override
    public boolean isEmpty() {
        return isEmpty;
    }
    
    @Override
    public long getSize() {
        return size;
    }
    
    @Override
    public byte[] getBytes() throws IOException {
        return bytes;
    }
    
    @Override
    public InputStream getInputStream() throws IOException {
        // TODO Auto-generated method stub
        return null;
    }
    
    @Override
    public void transferTo(File dest) throws IOException, IllegalStateException {
        // TODO Auto-generated method stub
    
    }
    }
    

    Converting Jpg to MultipartFile

    BufferedImage originalImage = ImageIO.read(new File("path to file"));
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ImageIO.write( originalImage, "jpg", baos );
    baos.flush();
    
    MultipartFile multipartFile = new MultipartImage(baos.toByteArray());
    

    OR

    if you dont want to create an implementation of MultipartFile class your own you can use org.springframework.mock.web.MockMultipartFile from spring

    Example:

     MultipartFile multipartFile = MockMultipartFile(fileName, baos.toByteArray());