Objective
The iphone and some digital cameras often include a lot of photo information (EXIF) in the picture, such as photo time, aperture size, exposure time, GSP geographic information, and camera tilt when photographed, and so on, which often provides systems to correctly display pictures. But we usually lose those picture information when dealing with the picture, which leads to the display of the problem, the typical error is to cut the photos of the iphone and find that the picture is rotated 90 degrees, at which point the image should be processed accordingly.
Background
Bloggers are encountering this problem in a small project, although this project is small, but the various pits involved can really write a relatively long technical article, here is not described, a separate article on the project, the relevant knowledge points and pit point one by one description.
One of the problems with this small project is that I need to use HTML5 's canvas to trim the read picture and then render it to the canvas. A simple requirement, but testing on the iphone often results in a 90-degree automatic rotation of the image after clipping, which is not a problem on the Android machine.
Analysis
I've had this problem before, iphone photos copied to the Win7 to open the picture is a reverse, and on the phone to see there is no problem, this is because EXIF information in mischief, simple point that EXIF is to retain the picture of the shooting parameters, show the time the program will read the image of EXIF information , if the EXIF information does not exist, then the picture is in the most original form, if there is EXIF information, the program will be according to EXIF.
Here bloggers encounter the situation is the picture in the clip when the information is lost, the original program to read EXIF picture requirements clockwise rotation 90 °, now Exif lost, the program can not read, the default picture does not rotate, then we see the picture is inverted, here should how to solve it?
In this project, because there is a cross-domain problem with the read picture, it is not possible to crop the local picture directly, so it is to upload to the remote server, generate a remote address, and then use canvas to read the remote address, this solves the cross-domain problem.
Now in front of the blogger there are two solutions.
Only use Exif.js to read the EXIF information of the picture locally, judge it directly on the client.
Upload to the server when the image processing, the return of the remote address is already processed pictures
To compare the two schemes, the first one looks really good, directly in front of the processing, here will be very save server resources, but the disadvantage is also very obvious, canvas to the image of the rendering of a certain limit, when the picture is too large when rendering will fail, In this project, the customer requirements of the final generation of images must be large high-definition image, uploaded photos are generally 3~5m size, such a large picture most of the time canvas can not handle.
The principle of exif.js is actually relatively simple, is to convert the picture into a Base64 string, the information in which to parse, so once you want to deal with the big picture will appear problems, the amount of data is too large, resulting in failure.
The first option is not possible and you can only select the second option. The project backend uses PHP to do the relay processing, said previously needs to generate a remote address, the PHP is responsible for receives the picture to store in the remote server, then returns an address to the front end, here only needs in the memory before the picture processing can solve this problem.
Solve
First give the complete code and then explain the code
Include_once (".. /weixin/jssdk.php ");
$JSSDK = new Jssdk ("wx**************", "******************************");
$access _token = $jssdk->getaccesstoken ();
$media _id = $_post[' i '];
$savePathFile = '/upload/temps/'. Date (' Ymdhis '). Rand (1000,9999). JPG ';
$targetName = __dir__. $savePathFile;
$str = "http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=". $access _token. " &media_id= ". $media _id;
$image = imagecreatefromstring (file_get_contents ($STR));
$exif = Exif_read_data ($STR);
If (!empty ($exif [' orientation ']) {
switch ($exif [' orientation ']) {
Case 8:
$image = Imagerotate ($image, 90,0);
break;
Case 3:
$image = imagerotate ($image, 180,0);
break;
Case 6:
$image = imagerotate ($image, -90,0);
break;
}
}
Imagejpeg ($image, $targetName);
echo Json_encode (Array ("Code" =>0, ' d ' => $exif [' Orientation '], "path" => $savePathFile));
It seems to be quite simple, the main or call some of the internal functions, to deal with more convenient.
This project uses the micro-letter upload interface, so PHP needs to be from the micro-letter of the temporary server to upload the user uploaded pictures, through the File_get_contents method can quickly get, of course, can also use curl to do. Then use imagecreatefromstring to create a picture of the cache, under normal circumstances, if you do not need to deal with the image, then the next can be stored directly, here we also need to do some action on the picture.
The Exif_read_data method can directly read the EXIF information of the picture.
Note: Exif_read_data This method is the method of EXIF extension, if it can not be performed, please check whether the extension is installed, open, and so on.
EXIF module Inside there are many interesting ways, can be used to do a lot of useful things, such as the batch collection and analysis of pictures, extract picture information and so on, here recommend a fun website https://exif.cn/
If (!empty ($exif [' orientation ']) {
switch ($exif [' orientation ']) {
Case 8:
$image = Imagerotate ($image, 90,0);
break;
Case 3:
$image = imagerotate ($image, 180,0);
break;
Case 6:
$image = imagerotate ($image, -90,0);
break;
}
}
This paragraph is easy to understand, is to judge the rotation of the picture, the image of the rotation processing Imagerotate method is very useful, of course, there are many similar functions, you can go to understand, if you are doing picture processing, these functions should be very helpful.
Finally, use the Imagejpeg method to write the processed picture to disk, and then return a JSON containing the remote address to the front end.
Note: I do not have an exception capture here, normally file IO operations must be an exception capture, the code here only to illustrate the use of methods, so omit this step.
Postscript
In this small project, the most common problem is that in the use of PHP functions, the same effect can be handled using more than one function, select a simple and efficient function is very important, in the use of Third-party extensions to ensure that the extension is installed, the extension depends on whether the plug-in installed, has been opened, Whether there are additional additional conditions and so on.
Front-End aspects need to know that the use of JS plug-ins have those additional functions, if the API article is not clear enough to directly open the plug-in source code, usually, an excellent plug-in will often be in the uncompressed code inside the use of all the interface, as well as considerations, the use of conditions.
In addition, it is also necessary to determine the unusual situation, when there are some strange bugs should be considered whether it is because the current given parameters do not conform to the specification, or beyond the scope of the specification allowed, said the picture to Base64 format size limit is a difficult to find the problem, Bloggers in the debugging of the generated data to observe the discovery, when the big picture will be converted to failure.