This post is part of a series. This list contains all of the posts:
For this blog, I wanted to be able to copy and paste an image from my clipboard into the textarea, capture the image, save it on my server and convert it to a markdown url pointing to the link. I struggled for a long time trying to implement this in javascript before giving up and searching for a library. Within 5 minutes I had a proof of concept with Paste.js, and with 15 minutes the feature was fully implemented.
I raised a pull request on cdnjs requesting that they host paste.js, and they did so in three days.
<script src="https://cdnjs.cloudflare.com/ajax/libs/paste.js/0.0.21/paste.min.js></script>
<script>
// Get paste.js to watch our text area
$('#post-content').pastableTextarea();
$('#post-content').on('pastImage', function(ev, data) {
// paste.js detected an image being pasted
// dataURL is the base64/png of the pasted image
console.log("dataURL: " + data.dataURL);
// Prompt user for a file name to save the image as
var file_name = prompt("Enter a file name", ".jpg");
// Send image and filename to server
ajax_data_url(data.dataURL, file_name);
}).on('pasteImageError', function(ev, data) {
// I suppose this is for incompatible browsers
console.log("error: " + data.message);
}).on('pasteText', function(ev, data) {
// paste.js detected text being pasted and will
// automatically insert into the text area for us
console.log("text: " + data.text);
});
</script>
<body>
<textarea id="post-content"></textarea>
</body>
The data.dataURL
will look something like this:
The ajax to send that back to the server to be saved looks like:
<script>
ajax_data_url = function(data_url, file_name) {
var csrf = "{{ csrf_token() }}";
var payload = {
"data_url": data_url,
"file_name": file_name,
"csrf": csrf
};
$ajax({
url: "/api/image-upload',
data: JSON.stringify(payload),
contentType: 'application/json',
dataType: 'json',
success: function(data) {
var post_content = $('#post-content').val() + data['md'];
$('#post-content').val(post_content);
},
error: function(jqXHR, textStatus, errorThrown) {
var responseJSON = jqXHR.responseJSON;
console.log("error saving image: " + responseJSON);
},
});
}
</script>
In the backend, I want Python and Flask to convert the base64/png to jpg, save it on the server, and return a markdown link to the front end.
PIL
is a cool library that can convert from png to jpg. I couldn't install it via pip install PIL
without receiving the error "Could not find a version that satisfies the requirement PIL". Instead I had to use the following"
pip install pillow
Here is the backend logic in Flask:
from PIL import Image import io import base64 @app.route('/api/image-upload/') def image_upload(): data = request.json['data'] file_name = data['file_name'] file_path = os.path.join(app.config['UPLOAD_FOLDER'], file_name) if os.path.isfile(file_path): return jsonify({"error": "Not a unique filename"}), 400 // remove the prefix to the base64 image img = data.split('data:image/png;base64,')[1] // Convert base64 to jpeg bytes image = Image.open(io.BytesIO(base64.b64decode(img))) // Save file in jpeg image.save(file_path, 'JPEG') // Convert file path to markdown and return to front end markdown = '![{}](/static/image/{file_name}) \n'.format( file_name=file_name ) return jsonify({"md": markdown}), 200
This post is part of a series. This list contains all of the posts: