📄 jpeg.php
字号:
<?php/******************************************************************************** Filename: JPEG.php** Description: Provides functions for reading and writing information to/from* JPEG format files** Author: Evan Hunter** Date: 23/7/2004** Project: PHP JPEG Metadata Toolkit** Revision: 1.10** Changes: 1.00 -> 1.10 : changed put_jpeg_header_data to check if the data* being written exists** URL: http://electronics.ozhiker.com** Copyright: Copyright Evan Hunter 2004** License: This file is part of the PHP JPEG Metadata Toolkit.** The PHP JPEG Metadata Toolkit is free software; you can* redistribute it and/or modify it under the terms of the* GNU General Public License as published by the Free Software* Foundation; either version 2 of the License, or (at your* option) any later version.** The PHP JPEG Metadata Toolkit is distributed in the hope* that it will be useful, but WITHOUT ANY WARRANTY; without* even the implied warranty of MERCHANTABILITY or FITNESS* FOR A PARTICULAR PURPOSE. See the GNU General Public License* for more details.** You should have received a copy of the GNU General Public* License along with the PHP JPEG Metadata Toolkit; if not,* write to the Free Software Foundation, Inc., 59 Temple* Place, Suite 330, Boston, MA 02111-1307 USA** If you require a different license for commercial or other* purposes, please contact the author: evan@ozhiker.com*******************************************************************************//******************************************************************************** Function: get_jpeg_header_data** Description: Reads all the JPEG header segments from an JPEG image file into an* array** Parameters: filename - the filename of the file to JPEG file to read** Returns: headerdata - Array of JPEG header segments* FALSE - if headers could not be read*******************************************************************************/function get_jpeg_header_data( $filename ){ // prevent refresh from aborting file operations and hosing file ignore_user_abort(true); // Attempt to open the jpeg file - the at symbol supresses the error message about // not being able to open files. The file_exists would have been used, but it // does not work with files fetched over http or ftp. $filehnd = @fopen($filename, 'rb'); // Check if the file opened successfully if ( ! $filehnd ) { // Could't open the file - exit echo "<p>Could not open file $filename</p>\n"; return FALSE; } // Read the first two characters $data = network_safe_fread( $filehnd, 2 ); // Check that the first two characters are 0xFF 0xDA (SOI - Start of image) if ( $data != "\xFF\xD8" ) { // No SOI (FF D8) at start of file - This probably isn't a JPEG file - close file and return; //echo "<p>This probably is not a JPEG file</p>\n"; fclose($filehnd); return FALSE; } // Read the third character $data = network_safe_fread( $filehnd, 2 ); // Check that the third character is 0xFF (Start of first segment header) if ( $data{0} != "\xFF" ) { // NO FF found - close file and return - JPEG is probably corrupted fclose($filehnd); return FALSE; } // Flag that we havent yet hit the compressed image data $hit_compressed_image_data = FALSE; // Cycle through the file until, one of: 1) an EOI (End of image) marker is hit, // 2) we have hit the compressed image data (no more headers are allowed after data) // 3) or end of file is hit while ( ( $data{1} != "\xD9" ) && (! $hit_compressed_image_data) && ( ! feof( $filehnd ) )) { // Found a segment to look at. // Check that the segment marker is not a Restart marker - restart markers don't have size or data after them if ( ( ord($data{1}) < 0xD0 ) || ( ord($data{1}) > 0xD7 ) ) { // Segment isn't a Restart marker // Read the next two bytes (size) $sizestr = network_safe_fread( $filehnd, 2 ); // convert the size bytes to an integer $decodedsize = unpack ("nsize", $sizestr); // Save the start position of the data $segdatastart = ftell( $filehnd ); // Read the segment data with length indicated by the previously read size $segdata = network_safe_fread( $filehnd, $decodedsize['size'] - 2 ); // Store the segment information in the output array $headerdata[] = array( "SegType" => ord($data{1}), "SegName" => $GLOBALS[ "JPEG_Segment_Names" ][ ord($data{1}) ], "SegDesc" => $GLOBALS[ "JPEG_Segment_Descriptions" ][ ord($data{1}) ], "SegDataStart" => $segdatastart, "SegData" => $segdata ); } // If this is a SOS (Start Of Scan) segment, then there is no more header data - the compressed image data follows if ( $data{1} == "\xDA" ) { // Flag that we have hit the compressed image data - exit loop as no more headers available. $hit_compressed_image_data = TRUE; } else { // Not an SOS - Read the next two bytes - should be the segment marker for the next segment $data = network_safe_fread( $filehnd, 2 ); // Check that the first byte of the two is 0xFF as it should be for a marker if ( $data{0} != "\xFF" ) { // NO FF found - close file and return - JPEG is probably corrupted fclose($filehnd); return FALSE; } } } // Close File fclose($filehnd); // Alow the user to abort from now on ignore_user_abort(false); // Return the header data retrieved return $headerdata;}/******************************************************************************* End of Function: get_jpeg_header_data******************************************************************************//******************************************************************************** Function: put_jpeg_header_data** Description: Writes JPEG header data into a JPEG file. Takes an array in the* same format as from get_jpeg_header_data, and combines it with* the image data of an existing JPEG file, to create a new JPEG file* WARNING: As this function will replace all JPEG headers,* including SOF etc, it is best to read the jpeg headers* from a file, alter them, then put them back on the same* file. If a SOF segment wer to be transfered from one* file to another, the image could become unreadable unless* the images were idenical size and configuration*** Parameters: old_filename - the JPEG file from which the image data will be retrieved* new_filename - the name of the new JPEG to create (can be same as old_filename)* jpeg_header_data - a JPEG header data array in the same format* as from get_jpeg_header_data** Returns: TRUE - on Success* FALSE - on Failure*******************************************************************************/function put_jpeg_header_data( $old_filename, $new_filename, $jpeg_header_data ){ // Change: added check to ensure data exists, as of revision 1.10 // Check if the data to be written exists if ( $jpeg_header_data == FALSE ) { // Data to be written not valid - abort return FALSE; } // extract the compressed image data from the old file $compressed_image_data = get_jpeg_image_data( $old_filename ); // Check if the extraction worked if ( ( $compressed_image_data === FALSE ) || ( $compressed_image_data === NULL ) ) { // Couldn't get image data from old file return FALSE; } // Cycle through new headers foreach ($jpeg_header_data as $segno => $segment) { // Check that this header is smaller than the maximum size if ( strlen($segment['SegData']) > 0xfffd ) { // Could't open the file - exit echo "<p>A Header is too large to fit in JPEG segment</p>\n"; return FALSE; } } ignore_user_abort(true); ## prevent refresh from aborting file operations and hosing file // Attempt to open the new jpeg file $newfilehnd = @fopen($new_filename, 'wb'); // Check if the file opened successfully if ( ! $newfilehnd ) { // Could't open the file - exit echo "<p>Could not open file $new_filename</p>\n"; return FALSE; } // Write SOI fwrite( $newfilehnd, "\xFF\xD8" ); // Cycle through new headers, writing them to the new file foreach ($jpeg_header_data as $segno => $segment) { // Write segment marker fwrite( $newfilehnd, sprintf( "\xFF%c", $segment['SegType'] ) ); // Write segment size fwrite( $newfilehnd, pack( "n", strlen($segment['SegData']) + 2 ) ); // Write segment data fwrite( $newfilehnd, $segment['SegData'] ); } // Write the compressed image data fwrite( $newfilehnd, $compressed_image_data ); // Write EOI fwrite( $newfilehnd, "\xFF\xD9" ); // Close File fclose($newfilehnd); // Alow the user to abort from now on ignore_user_abort(false); return TRUE;}/******************************************************************************* End of Function: put_jpeg_header_data******************************************************************************//******************************************************************************** Function: get_jpeg_Comment** Description: Retreives the contents of the JPEG Comment (COM = 0xFFFE) segment if one* exists** Parameters: jpeg_header_data - the JPEG header data, as retrieved* from the get_jpeg_header_data function** Returns: string - Contents of the Comment segement* FALSE - if the comment segment couldnt be found*******************************************************************************/function get_jpeg_Comment( $jpeg_header_data ){ //Cycle through the header segments until COM is found or we run out of segments $i = 0; while ( ( $i < count( $jpeg_header_data) ) && ( $jpeg_header_data[$i]['SegName'] != "COM" ) ) { $i++; } // Check if a COM segment has been found if ( $i < count( $jpeg_header_data) ) { // A COM segment was found, return it's contents return $jpeg_header_data[$i]['SegData'];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -