PHP 圖片
需求描述:
使用PHP對圖片檔案進行最佳化處理,但此最佳化處理只能進行一次,二次進行會對圖片造成不可恢複的損壞。期望在圖片一次處理之後,在圖片檔案中寫入一個自訂的字串,什麼都行,僅用於判斷圖片是否經過處理。
期待可以使用PHP解決。目前想到JPEG格式的話有 EXIF資訊,可以嘗試從這個作為突破,在EXIF資訊中寫入一個自訂的字串。但GIF,PNG,BMP呢,怎麼能解決常用的網狀圖片格式?
google到這貨
Imagick::setImageProperty
根據文檔http://www.php.net/manual/zh/imagick.setimageproperty.php
貌似剛好符合要求,但是使用這個函數儲存圖片,再次讀取卻為空白,不曉得是不是我的用法有問題
$image = new Imagick($file);$image->setImageProperty('Exif:Make', 'Imagick');$image->writeImage($file2);$image2 = new Imagick($file2);echo $image->getImageProperty('Exif:Make');
這個是一個思路,但沒能實現,真希望是我用法有問題,而不是這個函數不可實現。
又嘗試使用 APP13
$size = getimagesize('1.jpg', $info);var_dump($size);if(isset($info['APP13'])){ $iptc = iptcparse($info['APP13']); var_dump($iptc);}
但也不行。
難道我一直在走彎路?有什麼好的辦法嗎?要的不多,就是想在不破快圖片的基礎上在圖片資料中寫入一個字串,供下次讀取這個字串。
大大們現身吧,給點指點,解決問題立刻散分。
回複討論(解決方案)
對於 GD 支援的圖片,均可以在圖片資料結束後附加自訂資料,而不影響圖片的內容
範例程式碼
$url = 'http://avatar.profile.csdn.net/0/E/F/1_jaylecn.jpg';$im = imagecreatefromjpeg($url);imagepng($im, 'test.png'); //產生一個 png 圖片檔案$s = 'abcefg'; //待附加的資訊file_put_contents('test.png', sprintf('%sInfo%s', $s, pack('n', strlen($s))), FILE_APPEND); //按自訂格式附加在圖片檔案之後//回讀$s = file_get_contents('test.png');$t = unpack('A4t/noffs', substr($s, -6)); //取回自訂資訊的長度$v = substr($s, -6 - $t['offs'], -6); //取回自訂資訊echo $v;//abcdef
請自行驗證圖片資料沒有被破壞
其實大致有這樣一個概念:可以邊讀取邊展示的基本是流式資料,這樣的資料,標頭檔將說明了mimetype和長度(或有結束標誌),那麼在長度(或結束標誌)之後的“額外”資料並不影響主體資料的展示,依此概念,甚至rar、zip等也能做手腳,呵呵
謝謝兩位回答,看樣子思路是一樣的,就是在檔案的資料格式之外插入一段字元。
開始也想到過這個辦法,手工編輯了一個幾個檔案,其中有一個GIF動態圖插入之後,圖片遭到損壞。當時認為這種方法不可行,就沒繼續深入。我又使用了那張手工修改被破壞的GIF圖,用xuzuning的代碼測試了一下,竟然是可以的,看來手工修改確實不行。
這個方案看來基本可行了,那麼問題就是 我恐怕 沒辦法去測試所有的圖片格式,這種方法是否具有確定性呢?(GD只要支援,就一定沒問題?)
PS:我先去測試幾種格式的圖片試試。
用Imagick類可以實現,需要PHP安裝imagemagick擴充模組
我在發帖的時候就已經說了,google到了一個 Imagick 的函數,但實際上是無法寫入的,不知道樓上說的用Imagick實現是怎麼實現的?
是的,GD 支援的圖片都是可以的(gif、jpg、png)
因為此類圖片都是壓縮儲存的,在檔案頭部都有一個資料區長度的表識。
圖片顯示時,軟體通過該標識讀取並解壓資料
但對於 GD 不支援的,比如 bmp 檔案,就沒有那麼幸運了。
bmp 的資料是從檔案尾向檔案頭方向排列的,如果你在檔案尾部新增內容,就將破壞圖片資料
其實最簡單的測試方法就是準備你的位元據和原始檔案,然後用DOS命令
copy /b 原始檔案 + 位元據 新檔案
然後檢查這個新檔案有沒問題
先用這種方案吧,有個PHP類或者什麼的,可以相容各種圖片格式就好了。這個需求我覺得倒還挺常見的,比如批量給圖片打浮水印,可以給圖片加個屬性來判斷是否已經浮水印過了。
結貼,感謝兩位