Good day! There is a task: the user copies the images via the Internet (right click to copy the image), when going to the page, the user presses CTRL + V , the image should be uploaded to the server, there it is compressed using optipng or jpegoptim , depending on the image format. Once inserted, the image is converted from the blob link to base64 , sent in this form to the server, the server converts it and temporarily stores it as a file on the server, after work the server converts it back to base64 and sends a response, and then the client displays the finished compressed image that it copies in the same way (right click to copy image).
There is a working prototype, but it has a big problem. The code uses a variant for Firefox and for Chrome . The option for Firefox cannot be replaced, since only it works on old OS ( Windows XP ), there is a Firefox with long-lasting support.
The problem in determining the file format, I tried in different ways, last time I stopped on the definition of the file format using base64 , but Firefox defines all the images as png , and Chrome generally displays images as image / plain and accordingly, it’s impossible to choose what the image will be compressed either through optipng , or via jpegoptim and how to save this file in the future.
<!doctype html> <html> <head> <meta charset="UTF-8"> </head> <body> <p>base64: <br> <textarea id="base64" placeholder="" style="width:100%"></textarea></p> <img id="contenteditable" src=""> <hr> <img id="done" src=""> <script type="text/javascript"> if (!window.Clipboard) { var pasteCatcher = document.createElement("div"); pasteCatcher.setAttribute("contenteditable", ""); pasteCatcher.style.display = "none"; document.body.appendChild(pasteCatcher); pasteCatcher.focus(); document.addEventListener("click", function() { pasteCatcher.focus(); }); } window.addEventListener("paste", pasteHandler); function pasteHandler(e) { if (e.clipboardData) { var items = e.clipboardData.items; if (items) { for (var i = 0; i < items.length; i++) { if (items[i].type.indexOf("image") !== -1) { var blob = items[i].getAsFile(); var URLObj = window.URL || window.webkitURL; var source = URLObj.createObjectURL(blob); createImage(source); } } } } else { setTimeout(checkInput, 1); } } function checkInput() { var child = pasteCatcher.childNodes[0]; pasteCatcher.innerHTML = ""; if (child) { if (child.tagName === "IMG") { createImage(child.src); } } } function createImage(source) { var pastedImage = new Image(); pastedImage.onload = function() { document.getElementById("contenteditable").src = source; } pastedImage.src = source; var xhr = new XMLHttpRequest(); xhr.open('GET', pastedImage.src, true); xhr.responseType = 'blob'; xhr.onload = function(e) { if (this.status == 200) { var reader = new window.FileReader(); reader.readAsDataURL(this.response); reader.onloadend = function() { loadImg(reader.result); } } }; xhr.send(); } function loadImg(dataURL) { var xmlhttp = getXmlHttp(); xmlhttp.open('POST', 'compress.php', true); xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xmlhttp.send("a=" + encodeURIComponent(dataURL)); xmlhttp.onreadystatechange = function() { if (xmlhttp.readyState == 4) { if(xmlhttp.status == 200) { document.getElementById("base64").placeholder = xmlhttp.responseText; document.getElementById("done").src = xmlhttp.responseText; } } }; } function getXmlHttp() { var xmlhttp; try { xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } catch (E) { xmlhttp = false; } } if (!xmlhttp && typeof XMLHttpRequest!='undefined') { xmlhttp = new XMLHttpRequest(); } return xmlhttp; } </script> </body> </html> Server side:
<?php //ini_set('display_errors','On'); //error_reporting('E_ALL'); header('Content-type: text/html; charset=windows-1251'); $base64 = $_POST["a"]; function base64_to_image($base64_string, $output_file) { $type0 = explode(';', $base64_string); $type1 = explode('/', $type0[0]); $GLOBALS['type'] = $type1[1]; $data = explode(',', $base64_string); $source = imagecreatefromstring(base64_decode($data[1])); if ($GLOBALS['type'] == "png") { imagepng($source, $output_file.".png"); exec("optipng -o7 img.png"); }else if ($GLOBALS['type'] == "jpg" || $GLOBALS['type'] == "pjpeg" || $GLOBALS['type'] == "jpeg" || $GLOBALS['type'] == "plain") { imagejpeg($source, $output_file); exec("jpegoptim img"); }else{ echo "This file type is not supported, or the input data is corrupted! (".$GLOBALS['type'].")"; } imagedestroy($source); return $output_file; } base64_to_image($base64, "img"); $ENpath = 'img'; //$ENtype = pathinfo($ENpath, PATHINFO_EXTENSION); $ENtype = mime_content_type($ENpath); $ENdata = file_get_contents($ENpath); //$ENbase64 = 'data:image/' . $ENtype . ';base64,' . base64_encode($ENdata); $ENbase64 = 'data:' . $ENtype . ';base64,' . base64_encode($ENdata); unlink('img'); echo $ENbase64; Please do not throw hard slippers, JS is not strong, but the problem must be solved somehow. If you need a working prototype to "see", I can provide a link.
UPD. The safety of this action does not bother, as it will be available to a limited circle of people at work.
phpnot strong. But about the definition of the file type in the browser - do not even think. - Stepan Kasyanenkogetimagesize()php function - ArchDemon