This is a project I recently wrote for the company. The project requirements are roughly like this:
1.Uploadlocal mobile phonepicture, and then crop (requirements added later)
2. Able to rotate pictures for cropping (requirements added later)
3. Fill in various texts, select colors, then watermark the text and 2 related pictures to the cropped picture, and upload it to the server to generate A picture address, return, share.
The functions are roughly the above, and the others are various small functions. I won’t mention them. Let’s talk about technical selection. Overall, use Vue (including router, resource, webpack, etc. )
So how to meet these requirements:
1. Upload locally, use html5’s File Api to get the image The base64 encoding is assigned to the src of img (pit 1, 2), and then a layer pops up for cropping. The first cropping is to put a p on top of the img to calculate the coordinates. After the calculation, use canvasTo intercept the picture, and then get the value (pit 3).
2. This function is solved by using the rotated image of canvas. It should be noted that the aspect ratio must be maintained when rotating, and the width and height must be paid attention to (pit 4).
3. Just use canvas to overlay watermarks and pictures. The main thing is to pay attention to the coordinates.
Let’s talk about the pitfalls:
1. Getting the base64 encoding of src seems to be no problem, but in fact there is a huge problem. Many pictures are displayed in vertical screen on the mobile phone, but after getting Base64 encoding, after directly assigning it to the src of img, it was found that the screen was horizontal. When I first discovered this situation, I thought it was an isolated phenomenon. After repeated attempts, I found that it is a very common situation, especially on IPhone phones. It also divides the picture folders you choose into the same picture in the album and photo stream, and a horizontal screen. , a vertical screen. I just can't understand why? ? ? Basically an afternoon was spent on this issue.
Until I went back in the evening and asked a friend of mine who is a master of IOS development, @叶古城, he told me that because the camera of the IPhone is now horizontal, the reason why the mobile phone displays a vertical screen is that iOS has processed it by itself. They can judge the horizontal and vertical issues based on a shooting angle value of the picture, but this value is really not available on our web end, which is very embarrassing. So how to solve this problem? ? ------- The solution I use: rotating pictures allows users to actively rotate pictures and select angles. There is another solution, which is also used in Pit 2, which will be discussed later.
2. In addition to this horizontal screen, android some mobile phones uploaded. After selecting the picture, there was no response. I initially thought that the reason was that the File Api of html5 was not supported, so The uploaded image is not displayed, and various debuggers are used later. The reason is that the change event of the Input tag is not triggered, and there is no way to trigger it no matter what. In order to solve this problem, After consulting various official documents and stackoverflow, I found that two attributes can be added to the input of type="file" to indicate uploading images on the mobile phone.
<input type="file" name="image" class="file-choose" id="file" accept="image/*" v-on:change="chooseFileChange($event)" capture/>
After adding accept and capture in this way, the Android phone in question has several folders to choose from when selecting pictures. Some of them can be uploaded, and some cannot. Always check carefully. The test found that the pictures on the SD card cannot be obtained, and the change event will not be triggered because there is no root permission to obtain the file data. This is another unsolvable problem, because your web is in the browser and the permissions are low. (I have to complain about the web permissions problem, damn it.) How to solve the problem? ? ? Bypass, that is to say, if your page is nested in your company's own App, let the App help you. Then our project is spread by WeChat and must be in the WeChat browser, so you can call WeChat's JSSDK option PictureInterface, he can bypass these permissions, and another advantage is that it solves the problem of Pit 1. It can handle the horizontal screen problem, that is, when uploading the vertical screen, the actual horizontal screen is uploaded. It is processed as a vertical screen, but the cost is not small. You have to select the picture, get a key, and then continue to call the SDK to send it to the WeChat server, get a serverid, and pass this ID to your own server. , let them use this ID to download pictures from WeChat to their own server, and return a Url to you. The process is very tortuous, and the number of downloads is limited (you can apply for loading restrictions with WeChat);
Reference: WeChat js sdk select image interface
3. Let’s continue talking about the pitfalls. After solving the above problems, we will crop them. The solution I used at first was like this. After getting base64, Assign a value to an img, then move the frame on the img, calculate the coordinates and then crop. There are no problems at all on the PC side and the efficiency is very high. However, when tested on WeChat, 3 problems were found (damn, the mobile phone side is a trap) , one function, 3 different questions), the first question is that everyone knows that nowadays mobile phones have high pixels and the pictures are not small. After uploading them, the base64 is not small either. Putting it in the src of img is actually in the memory, resulting in The entire WeChat is particularly prone to crashing (it crashes, it crashes, and WeChat crashes --- three times). The second problem is that using Vue's on to bind touch events, the response is very slow, and the movement is not smooth at all. And it also crashes, yes, crashes again. The third problem is that you need to use canvas conversion for rotation. You need to go to the image data first. After the conversion is completed, you need to assign a value to the image src, which is very troublesome.
Solution: Use canvas uniformly, don’t use img anymore, until the cropping is completed, just get the base64 of img, and when exporting, use jpeg instead of png, which will reduce some image quality. I think it is completely There is no impact, that is, the cropping and rotation of the image are all canvas. It is recommended to bind the event directly natively.
4. The pitfall of rotation. The problem with this is that we must save the data of the original image, rotate the canvas first and then drawImage. Otherwise, the imageData of the canvas itself cannot be rotated. I try The matrix method doesn’t seem to work (maybe I’m not good at math!!! If anyone knows, please demo).
The above is the detailed content of Various problems with uploading local images in html5. For more information, please follow other related articles on the PHP Chinese website!