How to properly send an Image from React to Java? - java

I'm making a program that captures webcam images and I need to be able to send them to a backend for text detection and image recognition.
I'm using react webcam for the screenshots. Component is declared like this:
<Webcam
mirrored="false"
audio={false}
screenshotFormat="image/jpeg"
ref={props.webcam}
style={{
marginLeft: "auto",
marginRight: "auto",
display: "block",
paddingTop: "10px",
paddingBottom: "10px",
}}
/>
then, I invoke webcamRef.current.getScreenshot() to get the Image as a Base64 encoding. bytes are sent to a java backend with the following logic:
var formData = new FormData();
formData.append("file", props.image);
formData.append("user", props.user);
axios
.post("http://localhost:8080/api/storeImage", formData, {
headers: { "Content-Type": "multipart/formdata" },
})
.catch((err) => {
throw err;
});
Everything works fine up to this point. Problem arises when I try to create an ImageBuffer from the java backend:
Contoller:
#PostMapping("/api/storeImage")
#ResponseBody
public String storeImage(#RequestParam("file") String file, #RequestParam Long user) throws IOException, InvalidDniException {
return service.storeImage(file, user);
}
Service:
public String storeImage(String source, Long user) throws IOException, InvalidDniException {
byte[] decodedSource = Base64.getMimeDecoder().decode(source);
BufferedImage image = ImageIO.read(new ByteArrayInputStream(decoded)); <-- this returns null ...
I need the BufferedImage to crop and extract information from the captured screenshot. Every answer I've found on similar questions do not seem to work here.

Turns out I had to remove this prefix: data:image/jpeg;base64 from the String received.

Related

How to get image in response with postman

I have an endpoint to get the image i uploaded earlier, it works but not well
I don't know if i can get the image in response
my controller endpoint:
#PreAuthorize("hasAuthority('user:write')")
#GetMapping(value = "{messageId}/files/{file_name}")
public FileSystemResource getFile(#PathVariable("messageId") Integer id,#PathVariable("file_name") String fileName) throws FileNotFoundException {
return new FileSystemResource(messageService.getImage(id,fileName));
}
Response headers:
Postman example to save image
Click on 'Save Response', then 'Save to a file' with the extension you need.
Luck!

Spring RestTemplate upload binary file

Image
I want to write a client code to consume an API. The API is expecting a text file. When I select the binary file option in the postman tool and select any text file from my local it worked. how to implement this in spring ?. I have tried MULTIPART_FORM_DATA but no luck.
If You mean file
#RestController
public class FileContentController {
#RequestMapping(value="/up", method = RequestMethod.POST)
public ResponseEntity<?> upload(#RequestParam("file") MultipartFile file)
throws IOException {
String contentType=file.getContentType());
InputStream i=file.getInputStream();
return new ResponseEntity<>(HttpStatus.OK);
}
return null;
}
also spring boot has multi part confs, you should enable it and set size and tempdir
,In Earlier version spring boot need to add:
spring.servlet.multipart.max-file-size=128KB
spring.servlet.multipart.max-request-size=128KB
spring.servlet.multipart.enabled=true
spring.servlet.multipart.location=${java.io.tmpdir}
However in your client code you should not set content-type application/json in your header post request
simple fetch should be such
const input = document.getElementById('uploadInput');
const data = new FormData();
data.append('file', input.files[0]);
var resp = await fetch('upload/', {
method: 'POST',
body: data
});
if (!resp.ok) {
throw new Error(`HTTP error! status: ${resp.status}`);
}
if (resp.ok) {
await this.images();
}

How to detect file type for upload in spring controller picture/video

I have two entities photo and video, basically i need a controller that can upload both picture and video. an eg scenario is i execute the controller it opens my file and if i select a video it is handled as an mp4 with the video entity and if i select a picture it uses the photo entity and handles it as an image. Both entities have Multipartfile attribute to denote image and video.
Baically i have seen this link that has an answer for uploading a video
How to Implement HTTP byte-range requests in Spring MVC
Another example would be in social apps we use one click to upload either a photo or a video
This is what i have currently
#RequestMapping(value = "/Upload", method = RequestMethod.POST)
public String FileUpload(HttpServletRequest request,
#RequestParam("fileUpload") MultipartFile[] fileUpload) throws Exception {
}
I would like to use the MultipartFileSender from the above link but not sure how handle it with two different enities one for video and photo
currently i have this
#RequestMapping(value = "/upload", method = RequestMethod.POST)
public String Post(#Nullable Photo photo, #Nullable Video video,
HttpServletRequest request, HttpServletResponse response) {
String ext1 = FilenameUtils.getExtension("/path/to/file/foo.txt");
if(ext1.matches("png")) {
MultipartFile bookImage = photo.getImage();
try {
byte[] bytes = bookImage.getBytes();
String name = photo.getId() + ".png";
BufferedOutputStream stream =
new BufferedOutputStream(
new FileOutputStream(new File("src/main/resources/static/image/book/" + name)));
stream.write(bytes);
stream.close();
photoRepository.save(photo);
} catch (Exception e) {
e.printStackTrace();
}
} else {
/*
*/
MultipartFile videoFile = video.getVideo();
/**
* not sure how to continue about this
the class bellow MultipartFileSender can be found here https://stackoverflow.com/questions/28427339/how-to-implement-http-byte-range-requests-in-spring-mvc i am using that because i need a byte range request for the video upload
*/
MultipartFileSender.fromFile(File( ))
.with(request)
.with(response)
.serveResource();
}
return null;
}
There are different ways to do this. I have done something similar, but I kinda used some tricks to get to a result similar to yours.
1- create 2 separate array list with all possible video and image extensions
1 - Create a method that would get your media's file extension
2 - create a method that would compare the file extension you get against your lists of arrays that includes all possible video and image extensions.
This way you will separate between what is video and image and handle them differently. Hope this helps !

Render thumbnail in Angular4

I am trying to render an image which I got from a Java service as InputStream, re-send it through NodeJS Express server and finally render it in Angular4
Here's what I do:
Java Jersey service:
#GET
#Path("thumbnail")
#ApiOperation(
value = "Gets document preview",
notes = "Gets document preview"
)
#ApiResponses(value = {
#ApiResponse(code = 200, message = "Preview of the document")
})
#Consumes(MediaType.MULTIPART_FORM_DATA)
#Produces("image/png")
public Response getDocThumbnail(
#ApiParam(value = "Entity UUID", required = true) #FormDataParam("uuid") String uuid
) throws RepositoryException, UnknowException, WebserviceException, PathNotFoundException, DatabaseException, AutomationException, AccessDeniedException, ConversionException, IOException {
RawDocument rawDocument = docCtrl.getDocThumbnail(uuid);
return Response
.ok(rawDocument.getInputStream(), "image/png")
.header("Content-Disposition", "attachment; filename=\" " + rawDocument.getName() + "\"")
.build();
}
the controller looks like:
public RawDocument getDocThumbnail(String uuid) throws IOException, AccessDeniedException, PathNotFoundException, WebserviceException, RepositoryException, DatabaseException, ConversionException, AutomationException, UnknowException {
return new RawDocument(
okmWebSrv.getOkmService().getThumbnail(uuid, ThumbnailType.THUMBNAIL_LIGHTBOX),
"whatever"
);
}
Basically it's call to OpenKM SDK to retreive document's thumbnail
This Java endpoint is called from NodeJS Express 4.15 that is pre-processing some requests for this Java backend.
Here's what I do:
...compose request options...
const vedica_res = await rp(options);
let buffered = new Buffer(vedica_res, 'binary');
res.writeHead(200, {
'Content-Type': 'image/png',
'Content-disposition': 'attachment;filename=' + 'thumb.png',
'Content-Length': buffered.length
});
return res.end(buffered, 'binary');
Finally with Angular4 being the initiator of this roundtrip I am trying to render the image like so:
this.rest.send('http://localhost:4200/vedica/api/document/thumbnail', RequestMethod.Get,
{uuid: '19516ea1-657e-4b21-8564-0cb87f29b064'}, true).subscribe(img => {
// this.preview = img
var urlCreator = window.URL;
var url = urlCreator.createObjectURL(img);
this.thumb.nativeElement.src = url;
})
The 'img' received is a Blob {size: 81515, type: "image/png"}. Console shows no errors but renders no image in the <img #thumb/> tag. But I can see that it sets the src=blob:http%3A//localhost%3A3000/4cf847d5-5af3-4c5a-acbc-0201e60efdb7 for it. Image just has a broken image icon.
When I try to read a cached response in a new tab, its accessible but renders nothing again.
Can you point out what I'm doing wrong? Have tried a lot, but no luck.
I think the problem is not the stream is closed early, the problem I think will be in the way is downloaded, take a look here:
https://docs.openkm.com/kcenter/view/sdk4j-1.1/document-samples.html#getContent
From the server side ( inde middle between OpenKM and your user interface ) the problem usualy is:
//response.setContentLength(is.available()); // Cause a bug, because at this point InputStream still has not its real size.
And you should use
response.setContentLength(new Long(doc.getActualVersion().getSize()).intValue());
resolved this by replacing request-promise with bare request package for making this request to the java BE and piping reply right into the wrapping response of the angular FE:
let reply = request(options);
reply.pipe(res);

Retrieve pdf file stream from server

By following this link PLUNKER . I want to show pdf file in new window, but I want to read the pdf file from server
My service code
#RequestMapping(value = "/retrievePDFFile", method = RequestMethod.GET)
public #ResponseBody
InputStream retrievePDFFile() throws FileNotFoundException
{
InputStream inputStream = new FileInputStream("/resources/AngularJS 2013.pdf");
return inputStream;
}
My angular controller
$http({
method : "GET",
url : "/service/retrievePDFFile"
}).success(function(data) {
console.log(data);
}).error(function(data, status) {
console.log(data);
});
I got the pdf input stream from server like this..
How to read this, and open as a PDF file in new tab or window..
Thanks
After lot of searching I achieved the goal by little bit change in my controller code
$http.get('/retrievePDFFiles', {responseType: 'arraybuffer'})
.success(function (data) {
var file = new Blob([data], {type: 'application/pdf'});
var fileURL = URL.createObjectURL(file);
window.open(fileURL);
});

Categories

Resources