JavaScript - Mqtt Sending and Reciving Image - javascript

I am currently working on a project in which I want to send an image as ByteArray to a mosquitto broker with java to the topic images.
The subscriber of these Topic is a JavaScript application, which should convert the ByteArray,made in Java, back to an Image.
The reception of the image is working well, but the image cannot be shown correctly.
What I got so far:
Java Code to Publish an Image
public void doDemo(){
try {
client = new MqttClient("tcp://192.168.56.1", "Camera1", new MemoryPersistence());
MqttConnectOptions connOpts = new MqttConnectOptions();
connOpts.setCleanSession(true);
client.connect(connOpts);
MqttMessage message = new MqttMessage();
File imgPath = new File(Reciver.class.getResource("Card_1007330_bg_low_quality_000.png").getPath());
BufferedImage bufferedImage = ImageIO.read(imgPath);
// get DataBufferBytes from Raster
WritableRaster raster = bufferedImage .getRaster();
DataBufferByte data = (DataBufferByte) raster.getDataBuffer();
message.setPayload(data.getData());
client.publish("spengergasse/building-b/2.14/images", message);
} catch (MqttPersistenceException e) {
e.printStackTrace();
} catch (MqttSecurityException e) {
e.printStackTrace();
} catch (MqttException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
client.disconnect();
} catch (MqttException e) {
e.printStackTrace();
}
}
}
JavaScript to show the image
function onMessageArrived(r_message){
console.log(r_message);
document.getElementById("ItemPreview").src = "data:image/png;base64," + convert(r_message.payloadBytes);
}
function convert(buffer) {
var binary = '';
var bytes = new Uint8Array(buffer);
var len = bytes.byteLength;
for (var i = 0; i < len; i++) {
binary += String.fromCharCode(bytes[i]);
}
return window.btoa(binary);
}
After Reciving the Image I am gettin this:
Maybe someone could help me out.
Thanks a lot :D

Give this a try:
function convert(buffer) {
var decoder = new TextDecoder('utf8');
return btoa(decoder.decode(buffer));
}

I think the best approach here is to use blobs. Instead of converting the array to base64 which is terribly slow an error prone if not done correctly, you create a blob from the input array and assign it to the .src property like this:
var blob = new Blob([r_message.payloadBytes], {type: 'image/png'});
document.getElementById("ItemPreview").src = URL.createObjectURL(blob);

Related

How to upload multiple images from front-end using JavaScript, jQuery, Ajax in JSP file and send it into Spring Boot Controller?

I am working on a spring boot web application, where I want to upload multiple images of a product at a time along with other fields (for example product name, SKU code, category, tags, subcategory, etc). I have written code for RESTful API to upload multiple images and it is working perfectly for me. I tested API using postman and it is working fine. But, I don't know how to do it from the front end. I am showing you my front-end code below, where I am sending a single image to my controller using Ajax.
$("#file").change(function(){
var formData = new FormData();
var fileSelect = document.getElementById("file");
if(fileSelect.files && fileSelect.files.length == 1) {
var file = fileSelect.files[0];
formData.set("file",file,file.name);
}else{
$("#file").focus();
return false;
}
var request = new XMLHttpRequest();
try {
request.onreadystatechange=function() {
if(request.readyState==4) {
var v = JSON.parse(request.responseText);
if(v.status==="OK") {
alert("Product Image Uploaded Successfully")
document.getElementById('imagepath').value = v.response;
}
}
}
request.open('POST',"<%=AkApiUrl.testuploadfile%>");
request.send(formData);
} catch(e) {
swal("Unable to connect to server","","error");
}
});
As I told you, the above code is to send a single file at a time. I am showing you my API controller code also:
#RequestMapping(value = AkApiUrl.testuploadfile, method = { RequestMethod.POST, RequestMethod.GET }, produces = {MediaType.APPLICATION_JSON_VALUE }) public ResponseEntity<?> testuploadfile(HttpServletRequest request, #RequestParam("files") MultipartFile[] files) {
CustomResponse = ResponseFactory.getResponse(request);
String imgurl = "NA";
try {
String path = Constants.webmedia;
String relativepath = "public/media/";
System.out.println("Here is the image: ");
List<MultipartFile> multifile = Arrays.asList(files);
if( null != multifile && multifile.size()>0) {
for (int i=0; i < multifile.size(); i++) {
String filename = files[i].getOriginalFilename();
String extension = filename.substring(filename.lastIndexOf("."), filename.length());
int r = (int )(Math.random() * 500 + 1);
SimpleDateFormat format = new SimpleDateFormat("yyyyMMddhhmmss");
Date date = new Date();
String formatdate = format.format(date);
formatdate = "ECOM" + formatdate + r;
byte[] bytes = files[i].getBytes();
BufferedOutputStream stream = new BufferedOutputStream( new FileOutputStream(new File(path + File.separator + formatdate + extension)));
stream.write(bytes);
stream.flush();
stream.close();
String newimgurl = relativepath + formatdate + extension;
imgurl = imgurl+"##"+newimgurl;
if(imgurl != null) {
CustomResponse.setResponse(imgurl);
CustomResponse.setStatus(CustomStatus.OK);
CustomResponse.setStatusCode(CustomStatus.OK_CODE);
}
}
}
} catch (Exception e) {
e.printStackTrace();
CustomResponse.setResponse(null);
CustomResponse.setStatus(CustomStatus.Error);
CustomResponse.setStatusCode(CustomStatus.Error_CODE);
CustomResponse.setResponseMessage(CustomStatus.ErrorMsg);
}
return new ResponseEntity<ResponseDao>(CustomResponse, HttpStatus.OK);
}
This API is working fine, I am getting desired response. But I do not know how should I implement this thing on the JSP page. Please, any suggestions would be appreciated.

Queries can not be applied to a response content of type 'System.Net.Http.StreamContent'. The response content must be an ObjectContent

I am trying to download a file using knockout v3.2.0, webapi, odata and get this error when I try to return the file as HttpResponseMessage.
Here is my controller code:
[EnableQuery]
public HttpResponseMessage GetAttachment([FromODataUri] int key)
{
try
{
DataAccess.Attachment a = db.Attachments.Where(x => x.AttachmentId == key).FirstOrDefault();
HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
MemoryStream memStream = new MemoryStream();
memStream.Write(a.AttachmentData, 0, a.AttachmentData.Length);
result.Content = new StreamContent(memStream);
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
result.Content.Headers.ContentDisposition.FileName = a.AttachmentName;
return result;
//return Request.CreateResponse(HttpStatusCode.OK, result);
}
catch (Exception exception)
{
Request.CreateErrorResponse(HttpStatusCode.InternalServerError, exception.Message);
return null;
}
}
That's how I am trying to download from JavaScript:
self.downloadDocument = function (attachmentId) {
var serviceRequestUrl = dbhdd.buildUrl.buildSPContextUrl("/api/Attachments(" + 1 + ")");
window.location.href = serviceRequestUrl;
};
Which gives me this error- Queries can not be applied to a response content of type 'System.Net.Http.StreamContent'. The response content must be an ObjectContent.
I am relatively new to this. Any guidance in fixing this/alternate approach will be highly appreciated.
So I removed [EnableQuery] and it worked both in IE and Chrome!

How to pass image in string format to JavaScript and write it to document

I am passing JSON string to JavaScript code which contains {"imagePath":"a.svg"} Now instead of passing the path I want to send the image as string(some byte code maybe). I will be parsing this string in JavaScript and writing this as image to document.
Convert svg string to base64 and add base64 string to json as property.
Look at example: https://jsfiddle.net/wLftvees/1/
var decodedJson = {
img:
"PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBB"+
"ZG9iZSBJbGx1c3RyYXRvciAxNS4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9u"+
...
"NSw4LjU5NS0wLjA5NSwxMC42ODIsMS45MDMiLz4NCjwvc3ZnPg0K"
};
document.getElementById('image').src = 'data:image/svg+xml;base64,' + decodedJson.img;
First: Convert your image to String
public static String encodeToString(BufferedImage image, String type) {
String imageString = null;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
ImageIO.write(image, type, bos);
byte[] imageBytes = bos.toByteArray();
BASE64Encoder encoder = new BASE64Encoder();
imageString = encoder.encode(imageBytes);
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
return imageString;
}
Second: Convert String to image
public static BufferedImage decodeToImage(String imageString) {
BufferedImage image = null;
byte[] imageByte;
try {
BASE64Decoder decoder = new BASE64Decoder();
imageByte = decoder.decodeBuffer(imageString);
ByteArrayInputStream bis = new ByteArrayInputStream(imageByte);
image = ImageIO.read(bis);
bis.close();
} catch (Exception e) {
e.printStackTrace();
}
return image;
}
Now you can use 2 function and switch to Javascript to get Image. ^^

Send image from one device to another through node.js in android

I want to send image from one device to another so i have created that thing through node.js. i have converted the image into base64 and then into string and then send it to node.js server and decoded that string into another device and everythig works perfect. I have used socket.io. Now the problem arises as i have received the string as json response from node.js the full response is not getting half of response is being trimmed somewhere. So basically i am not getting full JSONRESPONSE. Here is my node.js code.
onLine[data.to].emit('newPrivateMessage1',{from:name, img:data.img.toString('base64'), type:'Private Msg1'})
And here is my first device from where i am sending image.
JSONObject json1 = new JSONObject();
String filepath = Environment.getExternalStorageDirectory().toString()+"/1.png";
File file = new File(filepath);
String itemname = getIntent().getStringExtra("itemname");
try {
#SuppressWarnings("resource")
FileInputStream imageInFile = new FileInputStream(file);
byte imageData[] = new byte[(int) file.length()];
Log.e("TAG", "IMAGEFATABYTE:::" + imageData);
imageInFile.read(imageData);
String imageDataString = android.util.Base64.encodeToString(imageData, 0);
json1.put("img", imageDataString);
json1.put("to", itemname);
Log.e("TAG", "MESSAGE:::" + json1);
socket.emit("privateMessage1", json1);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Here is my second device to get response from json
String josn = getIntent().getStringExtra("pvtjson");
Log.e("TAG5", "IMAGEJSON" + josn);
try {
JSONObject jobj = new JSONObject(josn);
jobj.get("img");
byte[] decodedString = Base64.decode(jobj.get("img").toString(), Base64.DEFAULT);
Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
iv.setImageBitmap(decodedByte);
} catch (JSONException e) {
e.printStackTrace();
}

writing pdf from javascript/cordova

In our mobile application (cordova+html4) we have a requirement to display the PDF from a stream. We have a service which returns pdf stream. We would like to store that stream to a temp folder location of the mobile and display the PDF.
The below sample java sample java code does the exact thing what I need. But how can I achive this functionality on java script? I mean reading a binary stream in java script.
String fileURL = "https://1/////4/xyz";
String saveDir = "D:/Works";
try {
URL url = new URL(fileURL);
HttpURLConnection httpConn = (HttpURLConnection) url
.openConnection();
httpConn.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
httpConn.setRequestProperty("TOKEN",
"ghZtxnPfpJ63FgdT/59V+5zFTKHRdwm6rIfGJC+0B5W5CJ9pG33od7l+/L6S8R56");
int responseCode = httpConn.getResponseCode();
System.out.println("Reseponse Code = " + responseCode);
if (responseCode == HttpURLConnection.HTTP_OK) {
String fileName = "";
String disposition = httpConn
.getHeaderField("Content-Disposition");
String contentType = httpConn.getContentType();
int contentLength = httpConn.getContentLength();
if (disposition != null) {
// extracts file name from header field
int index = disposition.indexOf("filename=");
if (index > 0) {
fileName = disposition.substring(index + 10,
disposition.length() - 1);
}
} else {
// extracts file name from URL
fileName = fileURL.substring(fileURL.lastIndexOf("/") + 1,
fileURL.length());
}
System.out.println("Content-Type = " + contentType);
System.out.println("Content-Disposition = " + disposition);
System.out.println("Content-Length = " + contentLength);
System.out.println("fileName = " + fileName);
// opens input stream from the HTTP connection
InputStream inputStream = httpConn.getInputStream();
String saveFilePath = saveDir + File.separator + fileName;
// opens an output stream to save into file
FileOutputStream outputStream = new FileOutputStream(
saveFilePath);
int bytesRead = -1;
byte[] buffer = new byte[BUFFER_SIZE];
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.close();
inputStream.close();
System.out.println("File downloaded");
} else {
System.out
.println("No file to download. Server replied HTTP code: "
+ responseCode);
}
httpConn.disconnect();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Thre's two libraries that you may want to have a look at :
jsPDF if you're trying to generate pdf from javascript and
pdf.js if you're trying to implement a pdf viewer in your interface.
One of those two should do the trick for you.

Categories