Is this a valid base64 string of jpeg?
data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD
That characters in question are the '/9j/' after the 'base64,'
I'm guessing it could be to do with compression as it's JPEG.
As when compared to a base64 string of a png, the pattern is different, i.e. the character pattern is different from above.
data:image/png;base64,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
The origin of my problem is that i'm base64 encoding an array of canvases into .jpeg's and .png's - the .png's output fine whereas the .jpeg's always output as black boxes.
I'm capturing the images using html2canvas (javascript), they are 'images' of html nodes, I have played around with transparency issues, like setting the background of the dom nodes to white.
All of the jpeg images I am encoding have this '/9j/' pattern, i'm generating them in a loop so it may well be a common property all the images have.
I can't seem to find a decent tool online to validate base64 strings either.
Let's check:
$ echo -n '/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgICAgMCAgID' | base64 --decode | file -
/dev/stdin: JPEG image data, JFIF standard 1.01
So it's recognized as a valid JPEG header (this doesn't necessarily mean that the entire JPEG data is valid, though, but at least it looks like a JPEG).
The difference between the JPEG data and the PNG data is because the file formats are different. Also, / is a valid character in Base64.
You can do a js check. Not sure how efficient it will be.
function checkImage( str ) {
var _img = document.createElement( 'img' );
_img.onerror = function() {
reportError(str);
}
_img.src = str;
}
function reportError(str) {
alert('Invalid image :' + str)
}
Hope it helps.
The file type can be identified by magic number. With a JPEG the magic number is “ff d8 ff” at offset 0. If you encode this to Base64, you'll always get “/9j/”
First we have to specify what is valid:
An totally legit image with no errors when gets rendered to image.
As long as it can show something visually, ignore the errors.(may have resolution or size issues but we don't care.)
In the first case, we can use onerror to bind events.The function checks if the base64 string can be converted to a <img> without any error. It will not only catch all the broken images but also the ones can be displayed but have errors.
let checkImage = (str) => {
let img = new Image();
img.src = str;
img.onerror = () => { //do something }
}
Or if we just want something can be rendered as image no matter what errors it gives us, we can ignore the errors and directly check if the size of the image is available.
let checkImage = (str) => {
let img = new Image();
img.src = str;
img.onload= () => {
if(img.width==0 || img.height==0){ //do something}
}
}
Related
I am wondering if there is a way to use binary photo that i get from a server.
So for example I have this kind of url mybackend.com/get_image?id=1 and as a response I get a photo.
This is the response that I console.log:
�PNG
IHDR
ռ��IDATx�� ���
U��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“E>�|�(�Q��G��“�HL}/�MwIEND�B`�
This value that i logged is binary i guess.
When I set <img src="mybackend.com/get_image?id=1" /> it works because browser first makes GET network call and makes this binary show probably under the hood.
I found bunch of answers regarding this and it usually says that I need to convert this into base64 and than insert it into src attribute. But they don't bring me near to showing photo.
Thanks
const base64Image = btoa(binaryImage);
const imageTag = `<img src="data:image/png,${base64Image}" />`
btoa has a caveat - the binary must have a specific string representation. The MDN article explains how to work around this:
// convert a Unicode string to a string in which
// each 16-bit unit occupies only one byte
function toBinary(string) {
const codeUnits = new Uint16Array(string.length);
for (let i = 0; i < codeUnits.length; i++) {
codeUnits[i] = string.charCodeAt(i);
}
return String.fromCharCode(...new Uint8Array(codeUnits.buffer));
}
// a string that contains characters occupying > 1 byte
const myString = "☸☹☺☻☼☾☿";
const converted = toBinary(myString);
const encoded = btoa(converted);
console.log(encoded); // OCY5JjomOyY8Jj4mPyY=
Though it may be easier to simply use a library which can do this out of the box, such as js-base64
<script src="https://cdn.jsdelivr.net/npm/js-base64#3.6.0/base64.min.js"></script>
Base64.fromUint8Array(binaryImage);
I have a base64 encoding of a PNG image (the string starts with data:image/png;base64,). My understanding is that this a base64 representation of the image encoded in PNG. Is there a way to get the "raw" pixel by pixel binary of the image using Node.js?
Try this. First remove "data:image/png;base64," from the string. i.e
const img = base64Data.replace(/^data:image\/png;base64,/, "");
Then convert the image from base64.
const imgBuf = Buffer.from(img, 'base64');
At this point we have the image in binary. We can then get the pixels. Try with this module https://github.com/scijs/get-pixels.
const getPixels = require("get-pixels");
getPixels(imgBuf, "image/png", function(err, pixels) {
if (err) {
console.log("Bad image path")
return
}
console.log("got pixels")
});
I think you can acheive that by doing so:
var b64str;
var buf = new Buffer(b64str, 'base64');
As Buffer objects are used to represent a fixed-length sequence of bytes
I have a BMP image and I need to send it to a device via TCP/IP. We already have the C library in our company, which can handle this, but I need to do it in JavaScript. Unfortunately, I don't have access to the source code of the library, nor to the device system.
This is a Base64 string of a sample image (a black&white checkmark):
Qk2+AAAAAAAAAD4AAAAoAAAAIAAAACAAAAABAAEAAAAAAIAAAADEDgAAxA4AAAAAAAAAAAAAAAAAAP///wD//////+H////A////gH///wB///4AP//8AD//+AAf//AAD//gAA//yAAH/5wAB/+8EAP/fjAB/394Af+++AD/vPwAf8P+AH///gA///9AH///v5///7/P///fx///7+P//+/z///38f//+/n///38///+/f///v3///97////hw==
I use window.atob and I am encoding it into HEX. I use this JS function:
function toHex(str) {
var result = '';
for (var i = 0; i < str.length; i++) {
result += str.charCodeAt(i).toString(16);
}
return result;
}
var str = window.atob(base64img);
var result = toHex(str);
It gives me this result, which is almost expected result:
424dbe00000003e0002800020000200001010000080000c4e00c4e00000000000000ffffff0ffffffffffe1ffffffc0ffffff807fffff07ffffe03ffffc03ffff801ffff00fffe00fffc807ff9c07ffbc103ff7e301ff7f781ffbef80ffbcfc07fc3fe07ffffe03fffff401fffffbf9fffffbfcfffffdfc7ffffefe3ffffeff3fffff7f1fffffbf9fffffdfcfffffefdfffffefdffffff7bffffff87
The library sends the exact same image correctly (the device accepts the message). This is how it looks like (copied from log):
be00424dbe000000000000003e000000280000002000000020000000010001000000000080000000c40e0000c40e0000000000000000000000000000ffffff00ffffffffffe1ffffffc0ffffff807fffff007ffffe003ffffc003ffff8001ffff0000fffe0000fffc80007ff9c0007ffbc10101003ff7e3001ff7f7801ffbef800ffbcfc007fc3fe007ffffe003fffff401fffffbf9fffffbfcfffffdfc7ffffefe3ffffeff3fffff7f1fffffbf9fffffdfcfffffefdfffffefdffffff7bffffff87
So this is what I need to get from Base64 in my JavaScript. Is it even possible? Or am I missing something?
Documentation for the library says the image has to be 2B binary data (Little Endian). I don't understand it. Should I encode the image any other way?
One option would be encode each byte separately to ensure correct endianness.
img = "Qk2+AAAAAAAAAD4AAAAoAAAAIAAAACAAAAABAAEAAAAAAIAAAADEDgAAxA4AAAAAAAAAAAAAAAAAAP///wD//////+H////A////gH///wB///4AP//8AD//+AAf//AAD//gAA//yAAH/5wAB/+8EAP/fjAB/394Af+++AD/vPwAf8P+AH///gA///9AH///v5///7/P///fx///7+P//+/z///38f//+/n///38///+/f///v3///97////hw=="
str = atob(img)
buf = []
function hex(str, pos) {
return ('000' + (str.charCodeAt(pos) || 0).toString(16)).substr(-2);
}
for (var i = 0; i < str.length; i+= 4) {
buf.push(hex(str, i+2));
buf.push(hex(str, i+3));
buf.push(hex(str, i+0));
buf.push(hex(str, i+1));
}
console.log(buf.join(''))
This doesn't match your desired output exactly, are you sure it corresponds to the given base64 string?
On the other side, your initial output looks better, 424d are correct bytes to start a BMP file (BM signature), while be00 are not.
This is a Base64 string of a sample image (a black&white checkmark)...
It gives me this result, which is almost expected result:
424dbe00000003e0002800020000200001010000080000c4e00c4e00000000000000ffffff0ffffffffffe1ffffffc0ffffff807fffff07ffffe03ffffc03ffff801ffff00fffe00fffc807ff9c07ffbc103ff7e301ff7f781ffbef80ffbcfc07fc3fe07ffffe03fffff401fffffbf9fffffbfcfffffdfc7ffffefe3ffffeff3fffff7f1fffffbf9fffffdfcfffffefdfffffefdffffff7bffffff87
What do you mean by "almost expected result"?, those bytes make the image below (save as .bmp).
Your expected "a black&white checkmark" image :
PS:
The correct .bmp file has 190 bytes. Your library version (copied from logs) gives result of 194 bytes.
The library's version of bytes has a beginning 2-byte short for file size. That is BE 00 (= 190 when read as endian of 00 BE) followed by rest of Bitmap file bytes (190 total bytes). This makes total of 190 bytes + the 2 bytes of short. Then it adds these two mysterious 10 and 10 bytes starting at position 114. Grand total of 194 bytes.
To me... the library is corrupting the already fine image bytes, but you say the device accepts it?
Does it accept the "almost expected result" hex bytes too?
I'm using the following to convert an image to a base64 encoded string. On the client website in javascript:
var reader = new FileReader();
reader.onloadend = function () {
data64 = reader.result;
};
reader.readAsDataURL(myFile);
Now I pass this data to the server, which does the following:
var data = Convert.FromBase64String(data64);
However this results in a format exception:
The format of s is invalid. s contains a non-base-64 character, more than two padding characters, or a non-white space-character among the padding characters.
My input file is one of the sample images found on Windows 7 -> My Pictures/Sample Pictures/Tulips.jpeg
How can I attempt to debug what is causing the problem for such a large result output?
Okay, I have worked around this by using reader.readAsBinaryString instead and then converting this using btoa.
This seems to be accepted fine in Convert.FromBase64String
I experienced the same issue and founds out that my complete dataurl contained not only padding characters at the end, but also padding characters in the middle of the dataurl.
I used the following code to fix the base64string (but it still has a bug):
private static string getCleanedBase64String(string base64String)
{
string tempString = base64String.Replace("_", "/").Replace("-", "+").Replace("=", "");
return tempString + new string('=', (4 - tempString.Length % 4) % 4);
}
I tried like this when handling chinese, but the output is messy code garbled:
var a = "你好";
undefined
a
"你好"
a = unescape(encodeURIComponent(a));
"ä½ å¥½"
a
"ä½ å¥½"
compared to handling English:
var a = "Hello";
undefined
a
"Hello"
a = unescape(encodeURIComponent(a));
"Hello"
Here is my whole code:
var content = $("div#test").html();
content = unescape(encodeURIComponent( content ));
content = window.btoa(content);
content = "data:image/svg+xml;filename:{{ request.session.access_token.uid }}.svg;base64," + content;
UPDATED:
What I am trying to do is encoding a generated SVG as data url for user to download. I solved this problem by converting SVG to canvas (using CanVG) first and use html2canvas to generate base64 ... finally it works ...
Try roundtripping this, and it works fine:
decodeURIComponent(escape(window.atob(window.btoa(unescape(encodeURIComponent("東京"))))))
Whether or not some intermediate result appears to be garbled is not relevant.
The problem with the window.btoa(decodeURIComponent(escape(unescape(encodeURIComponent("東京"))))) in one of the comments is the calls are not balanced and not in the right order.