Home >Web Front-end >H5 Tutorial >Complete example of zooming and uploading images through Canvas and File API_html5 tutorial skills
Complete example of zooming and uploading images through Canvas and File API_html5 tutorial skills
WBOYOriginal
2016-05-16 15:49:071595browse
Example address: Canvas Resize Demo Original author: Dr. Tom Trenka Original date: August 6, 2013 Translation date: August 8, 2013
Tom Trenka It is a huge honor for me to write an article for "my" blog. Tom was one of the original contributors to the Dojo framework and was my mentor at SitePen. I witnessed his genius at the highest level, and he was always the first to foresee many difficult problems with forward-looking solutions. He always thinks from the outside and solves fringe problems in an unconventional but solid way. This article is a perfect example. Lately I've been asked a lot about creating a user interface API that would allow users to upload images to a server (among other things) and be used on the client side of the large number of websites our company supports. Usually this is a very easy thing - create a form, add a file type input box, let the user select an image from the computer, and set the enctype="multipart/form-data" form on the form tag properties and then upload. Pretty simple, isn't it? In fact, here is a simple enough example; Click to enter But what if you want to pre-process the image in some way before uploading it? For example, you must compress the image size first, or you need the image to be in only certain types of formats, such as png or jpg, what should you do? Use canvas to solve it!
Introduction to Canvas Canvas is a new DOM element in HTML5 that allows users to draw graphics directly on the page, usually using JavaScript. Different format standards are also different. For example, SVG is a raster API (raster API) while VML is a vector API. You can consider using Adobe Illustrator (vector) for drawing and Adobe Photoshop (raster) for drawing. difference.
What you can do on canvas is to read and render images, and allow you to manipulate image data through JavaScript. There are many existing articles that demonstrate basic image processing for you - focusing mainly on various image filtering techniques - but all we need is to scale the image and convert it to a specific file format, and Canvas can do these things completely.
Our assumed requirements, such as the image height not exceeding 100 pixels, no matter how high the original image is. The basic code is as follows:
Copy the code
The code is as follows:
// Parameters, maximum height var MAX_HEIGHT = 100; // Rendering function render(src){ // Create an Image object var image = new Image(); // Bind the load event handler and execute after loading is completed image.onload = function(){ // Get the canvas DOM object var canvas = document.getElementById("myCanvas"); // If the height exceeds the standard if(image.height > MAX_HEIGHT) { // Width proportional scaling *= image.width *= MAX_HEIGHT / image.height; image.height = MAX_HEIGHT; } // Get the 2d environment object of canvas, // It can be understood that Context is the administrator and canvas is the house var ctx = canvas.getContext("2d"); //Clear canvas screen ctx.clearRect(0, 0, canvas.width, canvas.height); //Reset canvas width and height canvas.width = image.width; canvas.height = image.height; // Draw the image onto the canvas ctx.drawImage(image, 0, 0, image.width, image.height); // !!! Note that the image is not added to the dom }; // Set the src attribute and the browser will automatically load it. // Remember that the event must be bound first before the src attribute can be set, otherwise synchronization problems will occur. image.src = src; };
In the above example, you can use canvas's toDataURL() method to obtain the Base64-encoded value of the image (which can be similarly understood as a hexadecimal string, or binary data stream). Note: canvas's toDataURL () The obtained URL starts with a string and has 22 useless data "data:image/png;base64," which needs to be filtered on the client or server. In principle, as long as the browser supports it, the URL address There is no limit to the length, and the length limit of 1024 is unique to the older generation of IE.
Excuse me, how to get the images we need? Good boy, I’m glad you asked. You cannot process it directly through the File input box. All you can get from this file input box element is only the path to the file selected by the user. According to conventional imagination, you can load images through this path path information, but this is unrealistic in the browser. (Translator's note: Browser manufacturers must ensure that their browsers are absolutely secure in order to gain market share and at least avoid media attacks. If this is allowed, malicious URLs can try to obtain certain sensitive information by piecing together file paths). In order to achieve this requirement, we can use HTML5's File API to read files on the user's disk and use this file as the source of the image (src, source).
File API Introduction The new File API interface is a way to read and list user file directories without violating any security sandbox rules - through sandbox restrictions, malicious websites cannot write viruses. User disks, of course, cannot be executed. The file reading object we want to use is called FileReader. FileReader allows developers to read the contents of files (the implementation of specific browsers may be very different).
Assuming that we have obtained the path path of the image file, then relying on the previous code, it becomes easy to use FileReader to load and render the image:
Copy code
The code is as follows:
// Load image file (url path) function loadImage(src){ / / Filter out non-image type files if(!src.type.match(/image.*/)){ if(window.console){ console.log("Selected file type Not a picture: ", src.type); } else { window.confirm("Only picture files can be selected"); } return; } // Create a FileReader object and call the render function to complete rendering. var reader = new FileReader(); // Bind the load event automatic callback function reader.onload = function(e){ / / Call the previous render function render(e.target.result); }; // Read the file content reader.readAsDataURL(src); };
Excuse me, how to obtain the file? Little white rabbit, be patient! Our next step is to obtain the file, and of course there are many ways to do this. For example: you can use a text box to allow users to enter file paths, but obviously most users are not developers and have no idea what values to enter. For user convenience, we use the Drag and Drop API interface.
Using the Drag and Drop API The drag and drop interface (Drag and Drop) is very simple - on most DOM elements, you can bind event handlers to Implementation. As long as the user drags a file from the disk to the dom object and releases the mouse, we can read the file. The code is as follows:
Copy code
The code is as follows:
function init(){ // Get the DOM element object var target = document.getElementById("drop-target"); // Prevent dragover (drag above the DOM element) event delivery target.addEventListener("dragover ", function(e){e.preventDefault();}, true); // Drag and release the mouse event target.addEventListener("drop", function(e){ // Prevent default events and event propagation e.preventDefault(); // Call the previous load image function, the parameter is the first file of the dataTransfer object loadImage(e.dataTransfer.files[ 0]); }, true); var setheight = document.getElementById("setheight"); var maxheight = document.getElementById("maxheight"); setheight.addEventListener(" click", function(e){ // var value = maxheight.value; if(/^d $/.test(value)){ MAX_HEIGHT = parseInt(value); } e.preventDefault(); },true); var btnsend = document.getElementById("btnsend"); btnsend.addEventListener("click", function(e ){ // sendImage(); },true); };
We can also do some other processing, such as displaying preview images. But if you don't want to compress the image, it's probably useless. We will use Ajax to upload image data through HTTP post method. The following example uses the Dojo framework to complete the request. Of course, you can also use other Ajax technologies to implement it. Dojo code is as follows:
Copy Code
The code is as follows:
// The translator does not understand Dojo, so the jQuery implementation will be attached later // Remember that DTK 1.7 is AMD! require(["dojo/request"], function(request){ // Set the request URL, parameters, and callbacks. request.post("image-handler.php", { data: { imageName: "myImage.png", imageData: encodeURIComponent(document.getElementById("canvas").toDataURL("image/png")) } } ).then(function(text){ console.log("The server returned: ", text); }); });
jQuery is implemented as follows :
Copy code
The code is as follows:
// Upload image, jQuery version function sendImage(){ // Get the canvas DOM object var canvas = document.getElementById("myCanvas"); // Get the Base64 encoded image data, the format is a string // At the beginning of "data:image/png;base64,", it needs to be removed on the client or server side, and the following parts can be written directly to the file. var dataurl = canvas.toDataURL("image/png"); // Encode URI for security // data:image/png;base64, beginning var imagedata = encodeURIComponent( dataurl); //var url = $("#form").attr("action"); // 1. If the form is difficult to process, you can use a hidden hidden field to set the request Address // var url = $("input[name='action']").val (); // 2. You can also directly use the attributes of a DOM object to obtain // // var url = $("#imageaction").attr("action"); // Because it is a string, the server needs to transcode the data, write file operations, etc. // Personal agreement, all http parameter names are in lowercase console.log(dataurl); //console.log(imagedata); var data = { imagename: "myImage .png", imagedata: imagedata }; jQuery.ajax( { url : url, data : data, type : "POST", / / Expected return value type dataType: "json", complete : function(xhr,result) { //console.log(xhr.responseText); var $tip2 = $( "#tip2"); if(!xhr){ $tip2.text('Network connection failed!'); return false; } var text = xhr.responseText ; if(!text){ $tip2.text('Network error!'); return false; } var json = eval("(" text ")" ); if(!json){ $tip2.text('Parse error!'); return false; } else { $tip2.text(json.message) ; } //console.dir(json); //console.log(xhr.responseText); } }); };
OK, done! All you need to do is create a simple user interface that allows you to control the size of the image. The data uploaded to the server does not need to handle the enctype of multi-part/form-data. Just a simple POST form handler is enough. Okay, here is a complete code example:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn