Dynamics365: How to convert binary image to actual image - javascript

I'm working on an app using nodejs and ionic that communicate with Dynamics 365.
My problem is that I don't understand the return of the image.
According to the contact EntityType documentation
entityimage Edm. Binary Shows the default image for the record
Here's what returns the CRM for the image:
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
What is this format ? How can I convert it so I can display an image ?
EDIT 1
I have tried this way
var img = document.createElement('img');
img.src = 'data:image/jpeg;base64,' + btoa('your-binary-data');
document.body.appendChild(img);
but doesn't work

There is an example here for working with entity images here. It's C#, but the same basic principles apply.
Retrieves the records with the entityimage attribute and saves the
resized files.
//Retrieve and download the binary images
string binaryImageQuery = String.Format(#"<fetch mapping='logical'>
<entity name='{0}'>
<attribute name='sample_name' />
<attribute name='entityimage' />
</entity>
</fetch>",_customEntityName.ToLower());
EntityCollection binaryImageResults = _serviceProxy.RetrieveMultiple(new FetchExpression(binaryImageQuery));
Console.WriteLine("Records retrieved and image files saved to: {0}", Directory.GetCurrentDirectory());
foreach (Entity record in binaryImageResults.Entities)
{
String recordName = record["sample_name"] as String;
String downloadedFileName = String.Format("Downloaded_{0}", recordName);
byte[] imageBytes = record["entityimage"] as byte[];
var fs = new BinaryWriter(new FileStream(downloadedFileName, FileMode.Append, FileAccess.Write));
fs.Write(imageBytes);
fs.Close();
Console.WriteLine(downloadedFileName);
}

All I had to do was
let img = "data:image/png;base64,"+ "binary-data";

Related

How to convert a string to file with UTF-32LE encoding in JS?

Based on this thread I tried to create a blob with utf 32 encoding and BOM of FF FE 00 00(UTF-32LE representation) as follows:
var BOM = new Uint8Array([0xFF,0xFE,0x00,0x00]);
var b = new Blob([ BOM, "➀➁➂ Test" ]);
var url = URL.createObjectURL(b);
open(url);
But the file content gets corrupted and gets changed to a different language. What is the correct way to convert a string to a file with utf-32le format?
Edit:
Im trying this in browser environment
Note: I'm assuming you're doing this in a browser, since you used Blob and Node.js only recently got Blob support, and you referenced a question doing this in a browser.
You're just setting the BOM, you're not handling converting the data. As it says in MDN's documentation, any strings in the array will be encoded using UTF-8. So you have a UTF-32LE BOM followed by UTF-8 data.
Surprisingly (to me), the browser platform doesn't seem to have a general-purpose text encoder (TextEncoder just encodes UTF-8), but JavaScript strings provide a means of iterating through their code points (not just code units) and getting the actual Unicode code point value. (If those terms are unfamiliar, my blog post What is a string? may help.) So you can get that number and convert it into four little-endian bytes. DataView provides a convenient way to do that.
Finally, you'll want to specify the charset in the blob's MIME type (the BOM itself isn't sufficient). I expected text/plain; charset=UTF-32LE to work, but it doesn't, at least not in Chromium browsers. There's probably some legacy reason for that. text/html works (on its own), but we may as well be specific and do text/html; charset=UTF-32LE.
See comments:
function getUTF32LEUrl(str) {
// The UTF-32LE BOM
const BOM = new Uint8Array([0xFF,0xFE,0x00,0x00]);
// A byte array and DataView to use when converting 32-bit LE to bytes;
// they share an underlying buffer
const uint8 = new Uint8Array(4);
const view = new DataView(uint8.buffer);
// Convert the payload to UTF-32LE
const utf32le = Array.from(str, (ch) => {
// Get the code point
const codePoint = ch.codePointAt(0);
// Write it as a 32-bit LE value in the buffer
view.setUint32(0, codePoint, true);
// Read it as individual bytes and create a plain array of them
return Array.from(uint8);
}).flat(); // Flatten the array of arrays into one long byte sequence
// Create the blob and URL
const b = new Blob(
[ BOM, new Uint8Array(utf32le)],
{ type: "text/html; charset=UTF-32LE"} // Set the MIME type
);
const url = URL.createObjectURL(b);
return url;
}
Beware, though, that the specification "prohibits" browsers from supporting UTF-32 (either LE or BE) for HTML:
13.2.3.3 Character encodings
User agents must support the encodings defined in Encoding, including, but not limited to, UTF-8, ISO-8859-2, ISO-8859-7, ISO-8859-8, windows-874, windows-1250, windows-1251, windows-1252, windows-1254, windows-1255, windows-1256, windows-1257, windows-1258, GBK, Big5, ISO-2022-JP, Shift_JIS, EUC-KR, UTF-16BE, UTF-16LE, UTF-16BE/LE, and x-user-defined. User agents must not support other encodings.
Note: The above prohibits supporting, for example, CESU-8, UTF-7, BOCU-1, SCSU, EBCDIC, and UTF-32. This specification does not make any attempt to support prohibited encodings in its algorithms; support and use of prohibited encodings would thus lead to unexpected behavior. [CESU8] [UTF7] [BOCU1] [SCSU]
You might be better off with one of the UTF-16s, given that you're using window.open to open the result. (For downloading, UTF-32 is fine if you really want a UTF-32 file.)
Sadly, Stack Snippets won't let you open a new window, but here's a full example you can copy and paste to run locally:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<title>UTF-32 Conversion</title>
<link rel="shortcut icon" href="favicon.png">
<style>
body, html {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
</style>
</head>
<body>
<input type="button" value="Open" id="open">
<input type="button" value="Download" id="download">
<script type="module">
function getUTF32LEUrl(str, mimeType) {
// The UTF-32LE BOM
const BOM = new Uint8Array([0xFF,0xFE,0x00,0x00]);
// A byte array and DataView to use when converting 32-bit LE to bytes;
// they share an underlying buffer
const uint8 = new Uint8Array(4);
const view = new DataView(uint8.buffer);
// Convert the payload to UTF-32LE
const utf32le = Array.from(str, (ch) => {
// Get the code point
const codePoint = ch.codePointAt(0);
// Write it as a 32-bit LE value in the buffer
view.setUint32(0, codePoint, true);
// Read it as individual bytes and create a plain array of them
return Array.from(uint8);
}).flat(); // Flatten the array of arrays into one long byte sequence
// Create the blob and URL
const b = new Blob(
[ BOM, new Uint8Array(utf32le)],
mimeType // Set the MIME type
);
const url = URL.createObjectURL(b);
return url;
}
document.getElementById("open").addEventListener("click", () => {
const str = "➀➁➂ Test";
const url = getUTF32LEUrl(str, { type: "text/html; charset=UTF-32LE" });
window.open(url);
});
document.getElementById("download").addEventListener("click", () => {
const str = "➀➁➂ Test";
const url = getUTF32LEUrl(str, { type: "text/plain; charset=UTF-32LE" });
const a = document.createElement("a");
a.download = "utf-32_file.txt";
a.href = url;
a.click();
document.body.removeChild(a);
});
</script>
</body>
</html>
I tried something like this...
var fs = require('fs');
var iconv = require('iconv-lite');
var str = '你好,世界';
var buf = iconv.encode(str, 'utf-32le');
fs.writeFileSync('test.txt', buf);

Javascript string to Base64 UTF-16BE

I'm trying to convert a string into BASE64 and a charset of utf-16 Big Endian in order to send it using an sms API.
I'm not being able to do so in Javascript.
This is the original js string I want to send in the sms:
const originalString = 'Teste 5% áàÁÀ éèÉÈ íìÍÌ óòÓÒ úùÚÙ çÇ ãà ?!,;';
Using btoa(originalString) I get VGVzdGUgNSUyNSDh4MHAIOnoycgg7ezNzCDz8tPSIPr52tkg58cg48MgPyEsOw== that is not what I need...
I used an online converter to that purpose and this is the correct value:
AFQAZQBzAHQAZQAgADUAJQAgAOEA4ADBAMAAIADpAOgAyQDIACAA7QDsAM0AzAAgAPMA8gDTANIAIAD6APkA2gDZACAA5wDHACAA4wDDACAAPwAhACwAOw==
I tested sending an sms with it and it works fine.
To get the UTF-16 version of the string, we need to map all its characters to their charCodeAt(0) value.
From there, we can build an Uint16Array that would hold an UTF-16LE text file.
We just need to swap all the items in that Uint16Array to get the UTF-16BE version.
Then it's just a matter to encode that to base64.
const originalString = 'Teste 5% áàÁÀ éèÉÈ íìÍÌ óòÓÒ úùÚÙ çÇ ãà ?!,;';
const expectedString = "AFQAZQBzAHQAZQAgADUAJQAgAOEA4ADBAMAAIADpAOgAyQDIACAA7QDsAM0AzAAgAPMA8gDTANIAIAD6APkA2gDZACAA5wDHACAA4wDDACAAPwAhACwAOw==";
const codePoints = originalString.split('').map( char => char.charCodeAt(0) );
const swapped = codePoints.map( val => (val>>8) | (val<<8) );
const arr_BE = new Uint16Array( swapped );
// ArrayBuffer to base64 borrowed from https://stackoverflow.com/a/42334410/3702797
const result = btoa(
new Uint8Array(arr_BE.buffer)
.reduce((data, byte) => data + String.fromCharCode(byte), '')
);
console.log( 'same strings:', result === expectedString );
console.log( result );
This isn't easy as the encoding UTF16BE has little to no support in javascript.
The challenge is converting the string into a buffer of bytes; once you have it in a buffer, converting it to base64 is easy. One way you can do this is by using a library to add support for UTF16BE, like iconv-lite.
Here is an example you can run in node:
const iconv = require('iconv-lite');
const originalString = 'Teste 5% áàÁÀ éèÉÈ íìÍÌ óòÓÒ úùÚÙ çÇ ãà ?!,;';
const buffer = iconv.encode(originalString, 'utf16be');
console.log(buffer.toString('base64'));
You can see a demo of it here: https://repl.it/#RobBrander/SelfishForkedAlphatest
Also, here is a great explanation of base64 encoding of UTF16BE: https://crawshaw.io/blog/utf7

Exception when converting to image from Base-64 string

I am trying to send a Highcharts chart via image on ASP.NET button click.
What I am trying to do is:
Convert the chart to base64 image, the code is the following :
var chart = $('#main-content').highcharts();
EXPORT_WIDTH = 1000;
var render_width = EXPORT_WIDTH;
var render_height = render_width * chart.chartHeight / chart.chartWidth;
var svg = chart.getSVG({
exporting: {
sourceWidth: chart.chartWidth,
sourceHeight: chart.chartHeight
}
});
var contentToSend = 'data:image/svg+xml;base64,' + window.btoa(svg);
var hdnField = document.getElementById("MainContent_ChartImage");
hdnField.value = contentToSend;
Next step is taking the base64 image value, convert it to image an attach it to the mail, the code is:
string textImage = ChartImage.Value;
var imageData = Convert.FromBase64String(HttpUtility.UrlDecode(data));
System.Net.Mail.LinkedResource res;
AlternateView htmlView;
using (MemoryStream ms = new MemoryStream(imageData, true))
{
ms.Position = 0;
ms.Write(imageData, 0, imageData.Length);
ms.Seek(0, SeekOrigin.Begin);
res = new System.Net.Mail.LinkedResource(ms);
htmlView = AlternateView.CreateAlternateViewFromString("<html><body><img src='cid:imageReport' width='100%' ></body></html>", null, "text/html");
res.ContentId = "imageReport";
htmlView.LinkedResources.Add(res);
MailMessage mailMsg = new MailMessage();
SmtpClient client = new SmtpClient();
// ...
mailMsg.IsBodyHtml = true;
mailMsg.AlternateViews.Add(htmlView);
client.Send(mailMsg);
}
but the method Convert.FromBase64String throws an exception
{"The input is not a valid Base-64 string as it contains a non-base 64
character, more than two padding characters, or an illegal character
among the padding characters. "}
However when I remove 'data:image/svg+xml;base64,' then convert it, it doesn't throw an exception but the image will not appear. What should I do?
Thank you
Get rid of the beginning part of the string: "data:image/svg+xml;base64," that part is not base64, just the remainder is. You don't need to use HttpUtility.UrlDecode either.
You should specify the TransferEncoding as Base64:
res.TransferEncoding = System.Net.Mime.TransferEncoding.Base64;
However with all that said, there are some strong caveats to using SVG in email. So you may want to consider a different format such as JPG or PNG. If that's the route you take, you will need to use a library to convert formats.
After many researches I found the solution , the main problem was that not all client email support data URI :
What is Data URI support like in major email client software?
i was trying to open the mail from the outlook 2016 however it is not supported , when i opened from hotmail.com it worked..
the code is :
MailMessage mailMsg = new MailMessage();
SmtpClient client = new SmtpClient();
var imageData = Convert.FromBase64String(data);
var contentId = Guid.NewGuid().ToString();
var linkedResource = new LinkedResource(new MemoryStream(imageData), "image/svg+xml");
linkedResource.ContentId = contentId;
linkedResource.TransferEncoding = TransferEncoding.Base64;
var body = string.Format("<img src=\"cid:{0}\" />", contentId);
var htmlView = AlternateView.CreateAlternateViewFromString(body, null, "text/html");
htmlView.LinkedResources.Add(linkedResource);
mailMsg.AlternateViews.Add(htmlView);

Reading contents of an uploaded file

I have a JSP page, where an editor (ACE editor) is based on a DIV tag.
1. User upload a file (ex: my.txt)
2. This file is saved in the servlet (WEB-INF/my.txt)
Now, I want to open this file, copy it's contents to a variable in Java Script and populate the DIV tag.
How do I do this?
Based on an answer below, I've understood that once I get the contents of the file I can populate my DIV tag by using
var MyDiv1 = document.getElementById('DIV1');
MyDiv1.innerHTML = yourFileContent;
This solves the second part of the problem, now how to I open that file and copy its contents to a var in JS?
====================================EDIT==========================================
From the answers below, I've done the following steps
Step1: Getting the file contents, I take 4 input files so I've included a file counter to identify which file is being uploaded and when the 4th inpiut file is uploaded its contents are being stored to a string variable.
Servlet.java
response.setContentType("text/html");
String LINE = "<br>";
String filename = "/WEB-INF/myfile.txt";
fileTxt = "";
ServletContext context = getServletContext();
InputStream is = context.getResourceAsStream(filename);
if (is != null)
{
InputStreamReader isr = new InputStreamReader(is);
BufferedReader reader = new BufferedReader(isr);
PrintWriter writer = response.getWriter();
String text = "";
while ((text = reader.readLine()) != null) {
fileTxt = text + LINE;
writer.print(fileTxt);
HttpSession session = request.getSession(true);
session.setAttribute("FileText", "fileTxt");
}
}
Step2 : Submitting the forms for upload and right after submitting accessing the variable to populate ,
my.jsp
document.myform.submit();
var name = '<%= session.getAttribute("FileText") %>';
var div = document.getElementById("editor");
div.innerHTML = name;
PS: This still displays a null value, working on it and waiting fr answers.

Base64 Image from encoding to display

I am trying to display an image on a web page that I get from Visual C++ via a pluggin.
std::string DIBtoURI(LPBITMAPINFOHEADER lpbmih){
int width = lpbmih->biWidth;
int height = lpbmih->biHeight; // height < 0 if bitmap is top-down
if (height < 0)
height = -height;
// Populate the pixels array.
unsigned char *bitmap = (unsigned char *) lpbmih +
sizeof(BITMAPINFOHEADER);
HBITMAP f = CreateBitmap(width,height,1,24,bitmap);
BITMAP bit;
GetObject(f, sizeof(BITMAP), &bit);
// Allocate memory.
BYTE* pBitmapData = new BYTE[ bit.bmWidth*bit.bmHeight ];
ZeroMemory( pBitmapData, bit.bmWidth*bit.bmHeight );
// Get bitmap data.
GetBitmapBits(f, bit.bmWidth*bit.bmHeight, pBitmapData );
std::string tee = base64_encode(pBitmapData,bit.bmWidth*bit.bmHeight);
return tee;
}
In my function, you can see I get a BITMAPINFOHEADER (from Twain), I create a BITMAP from it, and then I use a base64 encoder I have found on google : http://www.adp-gmbh.ch/cpp/common/base64.html
I get a string I give to the web page and I'm trying to do
var src="image/jpeg;base64," + string_from_cpp
But it doesn't work !
I compared the string I get with my code, and what I get with a online encoder, and it's different, mine is very short.
What am I doing wrong? Header problem ? I don't know how to encode the header of my image ?
You calculated the image size in the wrong way. Please try:
((((bit.bmWidth * 24)+ 31)/32)*4)*bit.bmHeight

Categories

Resources