溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

php中如何實現照片旋轉

發(fā)布時間:2021-07-22 14:57:03 來源:億速云 閱讀:124 作者:小新 欄目:開發(fā)技術

這篇文章給大家分享的是有關php中如何實現照片旋轉 的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

前言

iPhone和一些數碼相機在拍照的時候往往會在圖片里面加入很多的照片信息(exif),比如拍照時間、光圈大小、曝光時間、GSP地理信息以及拍攝時相機傾斜狀態(tài)等等,這些信息往往會提供給某些系統來對圖片進行正確的顯示,但是我們在對處理圖片的時候通常會丟失掉那些圖片信息,這就會導致顯示出現問題,很典型的一個顯示錯誤就是對Iphone拍攝的照片進行剪裁之后發(fā)現圖片旋轉了90度,這個時候就需要對圖片進行相應的處理。

背景

博主是在一個小項目中遇到的這個問題,這個項目雖然小,但是涉及到的各種坑真的可以寫一篇比較長的技術文章了,這里先不描述,后面單獨發(fā)一篇關于這個項目的文章,把所涉及到的知識點以及坑點一一描述。

這個小項目中遇到的問題之一就是,我需要使用html5的canvas把讀取到的圖片進行剪裁,然后渲染到畫布上。很簡單的一個需求,但是在Iphone上測試經常會看到剪裁完之后圖片自動旋轉了90度,安卓機上不存在這個問題。

分析

之前就遇到過這個問題,iPhone拍攝的照片復制到win7上打開圖片就是一個倒過來的,而在手機上看卻沒有問題,這就是因為exif信息在搞鬼,簡單點說exif就是保留了圖片的拍攝參數,顯示的時候程序會讀取圖片的exif信息,如果exif信息不存在,那么圖片就是按照最原始的形式顯示,如果有exif信息,程序就會按照exif來。

這里博主遇到的情況是圖片在進行剪裁的時候導致exif信息丟失,本來程序讀取exif中圖片要求順時針旋轉90°,現在exif丟失,程序讀不到,默認圖片不用旋轉,那么我們看到的圖片就是倒著的,這里應該怎么解決呢?

在這個項目中,由于讀取的圖片存在跨域問題,不能直接對本地的圖片進行裁剪,所以是先上傳到遠程服務器,生成一個遠程的地址,然后再用canvas讀取遠程地址,這樣就解決了跨域問題。

現在擺在博主面前就有兩種解決方案了

  1. 只用exif.js本地讀取圖片的exif信息,直接在客戶端進行判斷

  2. 上傳到服務器的時候對圖片進行處理,返回的遠程地址已經是處理過的圖片

對這兩種方案進行對比,第一種方案看起來確實挺適合,直接在前端進行處理,這里會非常節(jié)省服務器資源,但是缺點也很明顯,canvas對圖片的渲染有一定的限制,當圖片過大的時候渲染就會失敗,而在這個項目中客戶要求最后生成的圖片一定要高清大圖,上傳的照片一般都有3~5M大小,這么大的圖片大多數時候canvas都無法處理。

exif.js的原理其實比較簡單,就是把圖片轉換成base64字符串,對其中的信息進行解析,所以一旦要對大圖進行處理的時候就會出現問題,數據量太大,導致失敗。

第一種方案不可行就只能選擇第二種方案了,項目后端使用php做中轉處理,前面說了需要生成一個遠程地址,php負責把接收到的圖片存儲在遠程服務器,然后返回一個地址給前端,這里只需要在存儲之前對圖片做處理就可以解決這個問題。

解決

首先給出完整代碼,然后對代碼進行解釋

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));

看起來確實比較簡單,主要還是調用了一些內部函數,處理起來就方便多了。

這個項目使用了微信的上傳接口,所以php需要從微信的臨時服務器上把用戶上傳的圖片取回來,通過file_get_contents方法就能快速拿到,當然也可以用curl來做。接著使用imagecreatefromstring創(chuàng)建一個圖片的緩存,正常情況下如果不需要對圖片進行處理,那么接下來就可以直接存儲了,這里我們還需要對圖片進行一些操作。

通過 exif_read_data 方法可以直接讀取到圖片的exif信息。

注意:exif_read_data 這個方法是exif擴展里面的方法,如果不能執(zhí)行,請檢查擴展是否安裝,是否開啟等。

exif模塊里面還有很多有意思的方法,可以拿來做很多有用的東西,比如拿來批量采集并分析圖片,提取圖片信息等。

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;
 }
}

這一段就很容易看懂了,就是判斷圖片的旋轉狀態(tài),對圖片進行旋轉處理imagerotate方法很好用,當然同類的還有好多函數,可以去了解下,如果你正在做圖片處理,這些函數應該會有很大的幫助。

最后使用 imagejpeg 方法把處理過的圖片寫入到磁盤,然后返回一個包含遠程地址的json到前端。

注意:我這里沒有做異常捕獲,正常情況下文件io操作都必須要做異常捕獲,這里的代碼只為了說明使用方法,所以省略了這一步。

總結

在這個小項目中,最為常見的問題就是在php函數的使用上,同一種效果可以使用多個函數進行處理,選擇一個簡潔高效的函數非常重要,在使用第三方擴展的時候務必確認擴展是否安裝,擴展依賴的插件是否安裝,是否已經開啟,是否有其他額外的附加條件等。

前端方面需要知道所使用的js插件有那些附加功能,如果api文章不夠清晰可以直接打開插件源碼,通常情況下,一個出色的插件往往會在未壓縮的代碼里面寫明所有接口的使用方法,以及注意事項,使用條件等。

此外,還需要對不常見的情況進行判定,當出現一些詭異bug的時候就應該考慮是否是因為當前所給的參數不符合規(guī)范,或者超出了規(guī)范允許的范圍,上面說道的圖片轉base64格式的大小限制就是一個很難被發(fā)現的問題,博主在調試的時候對生成的數據進行觀察才發(fā)現,當出現大圖的時候就會轉換失敗。

感謝各位的閱讀!關于“php中如何實現照片旋轉 ”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

php
AI