📄 exif.php
字号:
<?php
/******************************************************************************
*
* Filename: EXIF.php
*
* Description: Provides functions for reading and writing EXIF Information
* to/from an APP1 segment of a JPEG file
* Unfortunately, because EXIF data may be distributed anywhere
* throughout an image file, rather than just being in one block,
* it is impossible to pass just a string containing only the EXIF
* information. Hence it is neccessary to be able to seek to
* any point in the file. This causes the HTTP and FTP wrappers
* not to work - i.e. the EXIF functions will only work with local
* files.
* To work on an internet file, copy it locally to start with:
*
* $newfilename = tempnam ( $dir, "tmpexif" );
* copy ( "http://whatever.com", $newfilename );
*
*
* Author: Evan Hunter
*
* Date: 30/7/2004
*
* Project: PHP JPEG Metadata Toolkit
*
* Revision: 1.11
*
* Changes: 1.00 -> 1.10 : added function get_EXIF_TIFF to allow extracting EXIF from a TIFF file
* 1.10 -> 1.11 : added functionality to allow decoding of XMP and Photoshop IRB information
* embedded within the EXIF data
* added checks for http and ftp wrappers, as these are not supported
* changed interpret_IFD to allow thumbnail links to work when
* toolkit is portable across directories
*
*
* 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
*
******************************************************************************/
// TODO : Thoroughly test the functions for writing EXIF segments
// TODO : Figure out a way to allow EXIF to function normally with HTTP and FTP wrappers
// TODO : Implement EXIF decoding of Device Setting Description field
// TODO : Implement EXIF decoding of SpatialFrequencyResponse field
// TODO : Implement EXIF decoding of OECF field
// TODO : Implement EXIF decoding of SubjectArea field
// TODO : Add a put_EXIF_TIFF function
/******************************************************************************
*
* Initialisation
*
******************************************************************************/
if ( !isset( $GLOBALS['HIDE_UNKNOWN_TAGS'] ) ) $GLOBALS['HIDE_UNKNOWN_TAGS']= FALSE;
if ( !isset( $GLOBALS['SHOW_BINARY_DATA_HEX'] ) ) $GLOBALS['SHOW_BINARY_DATA_HEX'] = FALSE;
if ( !isset( $GLOBALS['SHOW_BINARY_DATA_TEXT'] ) ) $GLOBALS['SHOW_BINARY_DATA_TEXT'] = FALSE;
include_once 'EXIF_Tags.php';
include_once 'EXIF_Makernote.php';
include_once 'PIM.php';
include_once 'Unicode.php';
include_once 'JPEG.php';
include_once 'IPTC.php';
include_once 'Photoshop_IRB.php'; // Change: as of version 1.11 - Required for TIFF with embedded IRB
include_once 'XMP.php'; // Change: as of version 1.11 - Required for TIFF with embedded XMP
include_once 'pjmt_utils.php'; // Change: as of version 1.11 - Required for directory portability
/******************************************************************************
*
* Function: get_EXIF_JPEG
*
* Description: Retrieves information from a Exchangeable Image File Format (EXIF)
* APP1 segment and returns it in an array.
*
* Parameters: filename - the filename of the JPEG image to process
*
* Returns: OutputArray - Array of EXIF records
* FALSE - If an error occured in decoding
*
******************************************************************************/
function get_EXIF_JPEG( $filename )
{
// Change: Added as of version 1.11
// Check if a wrapper is being used - these are not currently supported (see notes at top of file)
if ( ( stristr ( $filename, "http://" ) != FALSE ) || ( stristr ( $filename, "ftp://" ) != FALSE ) )
{
// A HTTP or FTP wrapper is being used - show a warning and abort
echo "HTTP and FTP wrappers are currently not supported with EXIF - See EXIF functionality documentation - a local file must be specified<br>";
echo "To work on an internet file, copy it locally to start with:<br><br>\n";
echo "\$newfilename = tempnam ( \$dir, \"tmpexif\" );<br>\n";
echo "copy ( \"http://whatever.com\", \$newfilename );<br><br>\n";
return FALSE;
}
// get the JPEG headers
$jpeg_header_data = get_jpeg_header_data( $filename );
// Flag that an EXIF segment has not been found yet
$EXIF_Location = -1;
//Cycle through the header segments
for( $i = 0; $i < count( $jpeg_header_data ); $i++ )
{
// If we find an APP1 header,
if ( strcmp ( $jpeg_header_data[$i]['SegName'], "APP1" ) == 0 )
{
// And if it has the EXIF label,
if ( ( strncmp ( $jpeg_header_data[$i]['SegData'], "Exif\x00\x00", 6) == 0 ) ||
( strncmp ( $jpeg_header_data[$i]['SegData'], "Exif\x00\xFF", 6) == 0 ) ) // For some reason, some files have a faulty EXIF name which has a 0xFF in it
{
// Save the location of the EXIF segment
$EXIF_Location = $i;
}
}
}
// Check if an EXIF segment was found
if ( $EXIF_Location == -1 )
{
// Couldn't find any EXIF block to decode
return FALSE;
}
$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;
}
fseek( $filehnd, $jpeg_header_data[$EXIF_Location]['SegDataStart'] + 6 );
// Decode the Exif segment into an array and return it
$exif_data = process_TIFF_Header( $filehnd, "TIFF" );
// Close File
fclose($filehnd);
return $exif_data;
}
/******************************************************************************
* End of Function: get_EXIF_JPEG
******************************************************************************/
/******************************************************************************
*
* Function: put_EXIF_JPEG
*
* Description: Stores information into a Exchangeable Image File Format (EXIF)
* APP1 segment from an EXIF array.
*
* WARNING: Because the EXIF standard allows pointers to data
* outside the APP1 segment, if there are any such pointers in
* a makernote, this function will DAMAGE them since it will not
* be aware that there is an external pointer. This will often
* happen with Makernotes that include an embedded thumbnail.
* This damage could be prevented where makernotes can be decoded,
* but currently this is not implemented.
*
*
* Parameters: exif_data - The array of EXIF data to insert into the JPEG header
* jpeg_header_data - The JPEG header into which the EXIF data
* should be stored, as from get_jpeg_header_data
*
* Returns: jpeg_header_data - JPEG header array with the EXIF segment inserted
* FALSE - If an error occured
*
******************************************************************************/
function put_EXIF_JPEG( $exif_data, $jpeg_header_data )
{
// pack the EXIF data into its proper format for a JPEG file
$packed_data = get_TIFF_Packed_Data( $exif_data );
if ( $packed_data === FALSE )
{
return $jpeg_header_data;
}
$packed_data = "Exif\x00\x00$packed_data";
//Cycle through the header segments
for( $i = 0; $i < count( $jpeg_header_data ); $i++ )
{
// If we find an APP1 header,
if ( strcmp ( $jpeg_header_data[$i]['SegName'], "APP1" ) == 0 )
{
// And if it has the EXIF label,
if ( ( strncmp ( $jpeg_header_data[$i]['SegData'], "Exif\x00\x00", 6) == 0 ) ||
( strncmp ( $jpeg_header_data[$i]['SegData'], "Exif\x00\xFF", 6) == 0 ) ) // For some reason, some files have a faulty EXIF name which has a 0xFF in it
{
// Found a preexisting EXIF block - Replace it with the new one and return.
$jpeg_header_data[$i]['SegData'] = $packed_data;
return $jpeg_header_data;
}
}
}
// No preexisting segment segment found, insert a new one at the start of the header data.
// Determine highest position of an APP segment at or below APP3, so we can put the
// new APP3 at this position
$highest_APP = -1;
//Cycle through the header segments
for( $i = 0; $i < count( $jpeg_header_data ); $i++ )
{
// Check if we have found an APP segment at or below APP3,
if ( ( $jpeg_header_data[$i]['SegType'] >= 0xE0 ) && ( $jpeg_header_data[$i]['SegType'] <= 0xE3 ) )
{
// Found an APP segment at or below APP12
$highest_APP = $i;
}
}
// No preexisting EXIF block found, insert a new one at the start of the header data.
array_splice($jpeg_header_data, $highest_APP + 1 , 0, array( array( "SegType" => 0xE1,
"SegName" => "APP1",
"SegDesc" => $GLOBALS[ "JPEG_Segment_Descriptions" ][ 0xE1 ],
"SegData" => $packed_data ) ) );
return $jpeg_header_data;
}
/******************************************************************************
* End of Function: put_EXIF_JPEG
******************************************************************************/
/******************************************************************************
*
* Function: get_Meta_JPEG
*
* Description: Retrieves information from a Meta APP3 segment and returns it
* in an array. Uses information supplied by the
* get_jpeg_header_data function.
* The Meta segment has the same format as an EXIF segment, but
* uses different tags
*
* Parameters: filename - the filename of the JPEG image to process
*
* Returns: OutputArray - Array of Meta records
* FALSE - If an error occured in decoding
*
******************************************************************************/
function get_Meta_JPEG( $filename )
{
// Change: Added as of version 1.11
// Check if a wrapper is being used - these are not currently supported (see notes at top of file)
if ( ( stristr ( $filename, "http://" ) != FALSE ) || ( stristr ( $filename, "ftp://" ) != FALSE ) )
{
// A HTTP or FTP wrapper is being used - show a warning and abort
echo "HTTP and FTP wrappers are currently not supported with Meta - See EXIF/Meta functionality documentation - a local file must be specified<br>";
echo "To work on an internet file, copy it locally to start with:<br><br>\n";
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -