How to encode image to base64 in TinyMCE? - javascript

This is a part of my TinyMCE config:
{
...
plugins: 'code paste',
paste_data_images: true,
...
}
When I add pics via simple drag and drop in TinyMCE, the local images will appear as Blob encoded image.
I want to encode to base64. Can find nothing about it. Only this:
images_upload_handler: function (blobInfo, success, failure) {
success("data:" + blobInfo.blob().type + ";base64," + blobInfo.base64());
}
What can I do?

When those images are sent to the server they are indeed Base64 encoded images. The browser just shows you a blob URL when the content is pasted/dragged into the editor.
If you look at this documentation page it outlines what you can configure TinyMCE to do when images are pasted/dragged into the editor:
https://www.tiny.cloud/docs-4x/advanced/handle-async-image-uploads/
Effectively you need server side code to process the image when TinyMCE sends it to the server. Most people don't need to write their own image handling code for the client side - you can just configure the images_upload_url parameter to tell the editor where to send the file:
https://www.tiny.cloud/docs/configure/file-image-upload/#images_upload_url
The real work is what do you do with that file once its uploaded - that is server side code you need to write to process the Base64 image and store it on your server. You then return JSON that tells TinyMCE what to put in for the src attribute of the image.
The process for what to do once the image is uploaded is covered here:
https://www.tiny.cloud/docs/advanced/handle-async-image-uploads/#imageuploaderrequirements

Related

TinyMCE detect remote image dragged-in or uploaded

As documented, TinyMCE allows uploading images automatically: one defines an endpoint (images_upload_url), which is expected to upload the image and return the location for TinyMCE to use in markup.
However, when pasting, dragging or inserting an image from a URL — for example, https://somecdn.com/image.png — TinyMCE will simply embed the image tag with the somecdn.com source, instead of sending the URL to images_upload_url to be uploaded.
I've scoured through the docs here and haven't found any way to configure TinyMCE to do this. Is there a method I can override in order to upload images from URLs as well as local image uploads?
Summary
To clarify:
Current behavior with local image dragged in: TinyMCE sends the image to the URL specified in images_upload_url, then embeds the source returned.
Current behavior with remote image dragged in: TinyMCE embeds the remote image, sourced with its remote URL.
Desired behavior with remote image dragged in, similar to well established products like Microsoft's GroupMe: TinyMCE sends the image URL to the URL specified in images_upload_url, then embeds the source returned. I can figure out how to upload the URL & manually embed the image in TinyMCE, but I need to know what event to intercept to get the dragged-in image URL!
With some tinkering, I was able to figure out how to handle remote images in TinyMCE!
As I'm using TinyMCE with React, I added an onDrop event:
<Editor
onDrop={onDrop}
And here is my method implementation, with comments:
const onDrop = useCallback((e) => {
const image_url = e.dataTransfer.getData("URL");
/*
If this is a local file, use the default functionality
provided using images_upload_url
*/
if (!image_url) {
return;
}
/*
Otherwise, intercept the drop event, get the file URL,
send it to the API to be uploaded, then embed in content
*/
e.preventDefault();
filesAPI
.upload({
image_url,
})
.then((response) => {
const { location } = response.data;
editorRef.current.execCommand(
"mceInsertContent",
false,
`<img src='${location}' />`
);
});
return false;
}, []);
The implementation seems to work pretty well! When local images are dropped in, they're processed by the default handler; otherwise the onDrop method uploads the images & inserts a tag with their location. Note that filesAPI in this context is just my app's wrapper around an axios fetch call.
What you are wanting to do is not technically possible for a great many "remote" images as most sites won't have the appropriate CORS headers in place to allow for what you want to happen. You can fetch/proxy the image via some server side code and then do whatever you want with it once it is fetched server side.
All that being said you also enter a slippery slope of "taking" someone else's intellectual property and storing/serving it from your server which in many cases would be against copyright laws.
EDIT (based on your comments):
The images_upload_url feature is not designed to do what you want it to do. It is not that you cannot do what you are describing but images_upload_url won't do that for you. You can try to use some of TinyMCE's events to capture content insertion and trigger that sort of behavior or you could simply wait for the content to be saved to the server and perform that processing when the content is prepared for saving to your data store.
There are a whole host of events that TinyMCE provides along with some of the standard browser events:
https://www.tiny.cloud/docs/advanced/events/#handlingeditorevents

Use Messenger SDK to send file data

I have a webview that opens from a messenger bot.
From the webview I want to send image data to the conversation (no URL - data coming from the canvas).
I tried to use Messenger SDK beginShareFlow with file data attachment:
function uploadImage(data) {
let message = {
"attachment": {
"type": "image",
"payload": {
"is_reusable": true
},
"filedata": data
}
};
MessengerExtensions.beginShareFlow(function (share_response) {
// User dismissed without error
if (share_response.is_sent) {
// The user actually did share.
//close the webview
MessengerExtensions.requestCloseBrowser(function success() {
// webview closed
}, function error(err) {
console.log(err);
});
}
},
function (errorCode, errorMessage) {
// An error occurred in the process
console.log(errorMessage);
},
message, "current_thread");
}
But I get an error:
Messenger Extensions unexpected error.
Would appreciate help =]
EDIT:
I found out that filedata is used to transfer a file location (which I do not have).
So I tried other solutions:
I created from my cavas blob, and tried to pass it in filedata - did not work
I created a blob file (by adding name and date) and tried to move the location - did not work
I created a url from blob and tried to move it as a url (not as filedata) - and got an error:
Invalid image URL provided in message content
When I go to the blob url from the browser I see the image =[
Per the SDK's section on sending attachments:
There are three ways to attach an asset to a message:
URL
File
attachment_id
The attachment_id refers to previously uploaded URL/File attachments. Sending raw file data is not an option. You must either upload the image to a URL or save it to a file. Blob URLs do not work because they refer only to data stored in the local system's memory. You need to move that data to an image or file on a server.
Upload the image to a URL
Your first option is to upload the image to a URL. Depending on how private the contents of the image are, you could use a public image hosting service like imgur, or you could upload the image to a public location on your server. If you want to keep the image hidden, you could save the image at a URL containing a randomly generated hash and delete that file as soon as the attachment has been uploaded to Messenger. However, you could keep the image totally private with the second option:
Upload the image from a (temp) file
Your second option is to upload the image according to a file location. By uploading the image to a file on your server, you could avoid the image ever becoming visible to the public. To avoid filling up server space, you could manually delete the file once the attachment has uploaded, or you could use a temp file. In fact, the SDK's example for sending a file demonstrates sending a temporary file saved in the /tmp folder.

Upload/download/save image to a local server from a remote server using an Image URL and PHP?

I am building a Discussion Forum as part of a bigger application I am building, the forum is just 1 section of the Application.
For my TextArea fields when posting a new Topic or a Post Reply, I have decided that nothing is as good as the PageDown Markdown Library. It is the same one that StackOverflow uses on all their sites and it works better than many of it's competitors.
The way the library ships though, I am not happy with the default Insert Image functionality. You hit the button to insert an image and it allows you to enter a URL for an Image and then it inserts the proper MarkDown syntax to show the linked image.
This just won't cut it. I need the functionality that you see on StackOverflow! Very similar anyways.
I need it to show a Dialog when you click the Insert Image button, like it does now, but instead of just an input field for a Image URL, it will have 2 filed options...
Upload image from your computer
Insert an Image URL and it will then DOWNLOAD the image from that URL and insert it into the post just as if you had uploaded it from your computer. This is important to not confuse this step. IT should not simply insert the Image linking it to the original Image URL. Instead it will take that URL and download/upload the Image to the same server that the upload from computer option does and then it will insert the NEW Image URL pointing to the newly uploaded image!
Based on some simple HTML like below for a Dialog window with a filed for my Upload from Computer functionality, which I already have working. I need to come up with some JavaScript and PHP that will download/save a remote image to my upload folder on my server when a button is clicked using only the URL that will be inside the URL text input field.
So it will need to do a few things...
Fetch and save an image file to my uploads folder using PHP when the only thing that the PHP function will receive is a URL of the image which could be on the same server or most likely a remote server.
After successfully saving/uploading an image from the URL, the PHP function will return a JSON string with the status/error and if successful then it will also return the actual URL and filename of where the new image is saved on the local server. The JavaScript/AJAX script will receive this JSON response and insert the Markdown syntax for the image into the PageDown editor.
The PHP function will need to ensure that the URL that it is trying to save/download is a valid image file and not some malicious file! Also not simply just some file of the wrong filetype like a non-image file unless we are allowing the file type.
It will be part of a module installed on many dinosaur servers so it needs to work on as many servers as possible too!
From the web
From your computer
I would be greatful of any help, tips, code snippets or anything to help with this. At this stage I really just need to build a nie PHP function that will upload images from a remote URL and also ensure that the URL passed in is a real image file or even better that it is in the allowed file types array!
A couple years ago I had started this but have now lost it and I am starting over and don't remeber much about how I went about doing it then.
The easiest way to download a file from a remote server would be to use copy (http://php.net/manual/en/function.copy.php):
copy('http://someurl.com/image.png', '/var/www/uploads/image.png');
As this function returns a bool, it is easy to determine whether the operation was successful and create a JSON response.
To verify that the file is an actual image, there is unfortunately no way that is 100% sure. It is probably enough to check the mimetype though. You can use finfo for that (http://php.net/manual/en/function.finfo-file.php):
$finfo = finfo_open(FILEINFO_MIME_TYPE);
echo finfo_file($finfo, $filename);
finfo_close($finfo);
For a gif, this would return image/gif for example. You will have to hardcode a list of all mimetypes you want to allow.

Upload image from current HTML page

I have an image on my HMTL page. This is generated by DevExpress library at runtime and the src url points to a DevExpress script with a cache key:
<img id="Chart_89_IMG" src="/DXB.axd?DXCache=30f02093-de66-4ed6-8557-2382065c701a" />
I'm trying to get this file onto the server in a subsequent form post to use in an email. I've tried just passing the url in my form, but by the time it gets to the server, I get a 404 (assuming the cache key is expired).
I've also tried using canvas to get the bytes and pass that to the server, but was having trouble converting that byte stream back to an image, and canvas won't work for IE8, which I need to support.
My last idea was to include a file upload input on my form and pass the image to the server that way. But, how can I create a file from an image in javascript to use as an upload?
Any other ideas would be appreciated too!
Since this was DevExpress, I was able to change the BinaryStorageMode to the session:
settings.BinaryStorageMode = BinaryStorageMode.Session;
Then after I posted the form, the chart's bytes were accessible in the Session:
byte[] bytes = ((DevExpress.Web.ASPxClasses.BinaryStorageData)HttpContext.Current.Session[sessionKey]).Content;

How to display 'Base64' encoded image in Adobe AIR application using Javascript/HTML

I'm having some issues while displaying a 'Base64' encoded image in my AIR application.
I'm fetching an image, which is 'Base64' encoded string, in a XML through a web service. At application side I'm able to decode it, but its not been able to display the image on the fly. A little search on Google gave me various result, but not pertaining to my problem, because most of them are related to Flex.
My queries are:
1) After decoding the 'Base64' string, do I need to convert this to a PNG image using some PNG encoder? if so, then how can I use a PNGEncoder in my Adobe AIR HTML/Javascript application. is there any API or so?
2) Since the image I'm fetching from the web server is an icon, I'm setting it as a 'src' value for the element which I'm creating dynamically as follows:
var category_header_img = new Element('img',
{
'id': 'category_header_img' + this.SelectedCategoryID,
'class': 'category_header_img',
'src': 'data:image/png;base64,'+categoryIconBytes,
'cat_id': this.SelectedCategoryID
});
I'd found this solution,
'src': 'data:image/png;base64,'+categoryIconBytes
somewhere which tried to use but it didn't work.(where, categoryIconBytes is the 'Base64' encoded string)
Please, help to solve this issue. I'll be really grateful for any of your suggestions.
Thanks.
The data URL scheme isn't supported in AIR. What was the image before it was base64 encoded? If it is already a PNG, then all you need to do is reverse the base 64 encoding and save it locally to a temporary file. You should then be able to load it with an image tag.

Categories

Resources