I want to use an API to compress images. It says the input can as well be a buffer (string with binary), for example:
$sourceData = file_get_contents("unoptimized.jpg");
$resultData = \Tinify\fromBuffer($sourceData)->toBuffer();
In my understanding, they use file_get_contents to create that buffer from a file.
In my case, I already got an canvas image using a React application. To make the API call, I create a data URI, using .toDataURL() looking something like this:
data:image/png;base64,iVBORw0KGgoAAAANSUh... // lots of letters
So can I just use this data URI instead of file_get_contents, because both commands actually do the same in different languages, or is there a difference? Like:
$sourceData = 'data:image/png;base64,iVBORw0KGgoAAAANSUh...'
\Tinify\fromBuffer($sourceData)->toBuffer();
API Reference: https://tinypng.com/developers/reference/php
file_get_contents returns the content of a file as string, and that string exactly represents the content of the file.
.toDataURL() gives you a data url. The data:image/png;base64, part tells that the following data represents a png and that the data is base64 encoded.
To get the same data representation as you get with file_get_content you would need to decode the iVBORw0KGgoAAAANSUh...
So yes, both give you the content of a file, but they don't do that in the same way.
To toBlob on the other hand will return a Buffer containing the data in the same representation as file_get_contents would do.
Assuming you have a PNG file named input.png, the following two pieces of code produce the same result:
Read the image data from the PNG file:
$sourceData = file_get_contents('input.png');
Read the image data from a data: URL generated from the PNG file:
// Generate the 'data:' URL
$url = 'data:image/png;base64,'.base64_encode(file_get_contents('input.png'));
// Read the image data from the 'data:' URL
$sourceData = file_get_contents($url);
The second piece of code works only if fopen wrappers are enabled on the server where the file_get_contents() is executed.
It doesn't make much sense to use the second fragment of code in a single script (because it does a redundant encoding and decoding) but it makes a lot of sense if the encoding and restoring (decoding) happen in different scripts.
They can be part of the same application (the script that encodes the data stores it in the database, the other script loads from the database, restores the image data and uses it) or the decoding could happen in a remote application that sends the data URL over the Internet to be decoded and used by a different application.
Related
Attempting to pass Base64 image data in Url to web page on same domain. Query string works correctly for text strings, but receiving error -VM8:2759 crbug/1173575, non-JS module files deprecated - when attaching the base64 data.
var url = "somepage.html?name=" + encodeURIComponent("sometext") + "&image=" + base64Data;
Base64 data was initially fetched from a php script, and being forwarded from one webpage to another - same domain. Image file does not exist on the server.
Using gigantic query strings can be problematic, because different browsers have different rules, and in your case, the base64 blob image string could be compromised by URL encoding etc.
https://stackoverflow.com/a/812962/1772933
It's really best practice to use POST to send this quantity of data.
I am using a library to recieve attachments (image) from salesforce using OAuth and a proxy. Without the library (and the proxy) I am able to the same using XHR, but I have to use the library because I need the proxy.
In chrome debugger I can see image is downloaded fine, but I can't get it to work in my code. Data looks like:
So far methods I have tried:
btoa(unescape(encodeURIComponent(file.body)));- produces a base64 that does not work. decoding it using online tools gives me back the same string.
escape(file.body) - using this as base64 also does not work.
Converting to a blob.
var blob = new Blob([file.body], {type : "image/png"});
urlCreator.createObjectURL(blob);
The url it points to displays nothing, and if I remove {type : "image/png"} the url points to a page displaying same binary string.
Long story short this looks like someone read the image with readAsText() which mangles ("interprets") binary into utf8, instead of utf16. You need to get the server to return the data in arraybuffer or blob format ideally, or even base64, these preserve binary.
Long version with snippet. (those question marks symbols in the snippet show the lost information, compare it to the binary where they are not question marks in utf16):
https://stackoverflow.com/a/56523118/2962797
I would create an <img /> element, equal its src attribute to the image data you received. Now you have the image.
If you want to extract it or convert it to PNG, I would apply this another answer process.
I'm trying to process image and pass image data from a NodeJS app to hit an API wrote in PHP.
I use fs.readFileSync to read the image file (I'm using PNG here). The API only takes string as file content to upload. It seems like PHP file_get_contents doesn't have a specified encoding as I tried mb_detect_encoding($fileContent) and outputs false and the fileContents starts like \x89PNG\r.
I'm using Node v8 and it seems like i have to use some encoding to convert Buffer to string. I tried couple of encoding like base64, binary and the fileContent starts like \xc2\x89PNG\r or \xef\xbf\xbdPNG\r.
What is the equivalent of PHP file_get_contents in NodeJS? How can I get the right format of image data?
Thanks!
If I understood you right, you want to read an image file using nodeJS and send the image as a string to an API which is built using PHP. Have you tried first encoding it to base64 and casting it as string ?
var fs = require('fs');
// read binary data
var png= fs.readFileSync(pathToImageFile);
// convert binary data to base64 encoded string
var imageString = new Buffer(png).toString('base64');
Then send the imageString as a string, hope this helps!
At work we are trying to upload files from a web page to a web service using html 5/javascript in the browser end and C# in the web service. But have some trouble with encoding of some sort.
As for the javascript we get the file's binary data with help from a FileReader.
var file = ... // gets the file from an input
var fileReader = new FileReader();
fileReader.onload = dataRecieved;
fileReader.readAsBinaryString(file);
function dataRecieved() {
// Here we do a normal jquery ajax post with the file data (fileReader.result).
}
Wy we are posting the data manually and not with help from XmlHttpRequest (or similar) is for easier overall posting to our web service from different parts of the web page (it's wrapped in a function). But that doesn't seem to be the problem.
The code in the Web Service looks like this
[WebMethod]
public string SaveFileValueFieldValue(string value)
{
System.Text.UnicodeEncoding encoder = new UnicodeEncoding();
byte[] bytes = encoder.GetBytes(value);
// Saves file from bytes here...
}
All works well, and the data seems to be normal, but when trying to open a file (an image as example) it cannot be opened. Very basic text files seems to turn out okay. But if I upload a "binary" file like an image and then open both the original and the uploaded version in a normal text editor as notepad to see what differs, it seems to be wrong with only a few "invisible" characters and something that displays as a new line a few bytes in from from the start.
So basicly, the file seems to encode just a few bytes wrong somewhere in the conversions.
I've also tried to create an int array in javascript from the data, and then again transformed to a byte[] in the web service, with the exact same problem. If I try to convert with anything else than unicode (like UTF-8), the data turns out completly different from the original, so I think om on the right track here, but with something slightly wrong.
The request itself is text, so binary data is lost if you send the wrong enc-type.
What you can do is encode the binary to base64 and decode it on the other side.
To change the enc-type to multi-part/mixed and set boundaries (just like an e-mail or something) you'd have to assemble the request yourself.
Using a web service, I was able to retrieve some data from a MySQL Database. The database has an image saved in it, which had the file type of BLOB. This is what my web service returns when it comes to the image:
<image>
/9j/4AAQSkZJRgABAQEAYABgAAD/7TaeUGhvd.....RRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQB//Z
</image>
Now I am having trouble making my JavaScript application convert this data and then display it as an image. I researched on it a bit and found a couple of tutorials online but somehow they did not work for me....can anyone please help me with this issue? What is the simplest way I can convert BLOB data to an image? Thanks in advance!
Assuming the blob has base64 encoded PNG data, you can use data-uri to set data directly to image e.g.
var imgdata = "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="
$('#myimg').attr('src', "data:image/png;base64,"+imgdata)
Assumption here is that data returned from server is base64 encoded, but if that is not the case you can see various options but ultimately you may have to do proper conversion in server side, in that case why not just return the url to image and create a API on server side to return images from blob
Here is a jsfiddle in action http://jsfiddle.net/anuraguniyal/4DEtH/5/
Edit:
I am not sure what language you use server side but process will be same for each language e.g.
>>> s='\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x05\x00\x00\x00\x05\x08\x06\x00\x00\x00\x8do&\xe5\x00\x00\x00\x1cIDAT\x08\xd7c\xf8\xff\xff?\xc3\x7f\x06 \x05\xc3 \x12\x84\xd01\xf1\x82X\xcd\x04\x00\x0e\xf55\xcb\xd1\x8e\x0e\x1f\x00\x00\x00\x00IEND\xaeB`\x82'
>>> import base64
>>> base64.b64encode(s)
'iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=='
i.e. take all data, as will be stored in file (not the png marker too), not just raw image data and encode it