public function testUnicodeUserComment() { $filename = $this->mediaPath . 'exif-user-comment.jpg'; $seg = JpegMetadataExtractor::segmentSplitter($filename); $exif = new Exif($filename, $seg['byteOrder']); $data = $exif->getFilteredData(); $expected = array('UserComment' => 'test⁔comment'); $this->assertEquals($expected, $data); }
public function testUnicodeUserComment() { if (!wfDl('exif')) { $this->markTestIncomplete("This test needs the exif extension."); } $filename = $this->mediaPath . 'exif-user-comment.jpg'; $seg = JpegMetadataExtractor::segmentSplitter($filename); $exif = new Exif($filename, $seg['byteOrder']); $data = $exif->getFilteredData(); $expected = array('UserComment' => 'test⁔comment'); $this->assertEquals($expected, $data); }
/** * @return ExifReader */ private static function instance() { if (self::$instance === null) { self::$instance = ExifReader::factory(ExifReader::TYPE_NATIVE); } return self::$instance; }
function isMetadataValid($image, $metadata) { global $wgShowEXIF; if (!$wgShowEXIF) { # Metadata disabled and so an empty field is expected return self::METADATA_GOOD; } if ($metadata === self::OLD_BROKEN_FILE) { # Old special value indicating that there is no EXIF data in the file. # or that there was an error well extracting the metadata. wfDebug(__METHOD__ . ": back-compat version\n"); return self::METADATA_COMPATIBLE; } if ($metadata === self::BROKEN_FILE) { return self::METADATA_GOOD; } wfSuppressWarnings(); $exif = unserialize($metadata); wfRestoreWarnings(); if (!isset($exif['MEDIAWIKI_EXIF_VERSION']) || $exif['MEDIAWIKI_EXIF_VERSION'] != Exif::version()) { if (isset($exif['MEDIAWIKI_EXIF_VERSION']) && $exif['MEDIAWIKI_EXIF_VERSION'] == 1) { //back-compatible but old wfDebug(__METHOD__ . ": back-compat version\n"); return self::METADATA_COMPATIBLE; } # Wrong (non-compatible) version wfDebug(__METHOD__ . ": wrong version\n"); return self::METADATA_BAD; } return self::METADATA_GOOD; }
public function getInstance() { if (is_null(self::$instance)) { self::$instance = new self(); } return self::$instance; }
function getMetadata($image, $filename) { try { $meta = BitmapMetadataHandler::Jpeg($filename); if (!is_array($meta)) { // This should never happen, but doesn't hurt to be paranoid. throw new MWException('Metadata array is not an array'); } $meta['MEDIAWIKI_EXIF_VERSION'] = Exif::version(); return serialize($meta); } catch (MWException $e) { // BitmapMetadataHandler throws an exception in certain exceptional // cases like if file does not exist. wfDebug(__METHOD__ . ': ' . $e->getMessage() . "\n"); /* This used to use 0 (ExifBitmapHandler::OLD_BROKEN_FILE) for the cases * * No metadata in the file * * Something is broken in the file. * However, if the metadata support gets expanded then you can't tell if the 0 is from * a broken file, or just no props found. A broken file is likely to stay broken, but * a file which had no props could have props once the metadata support is improved. * Thus switch to using -1 to denote only a broken file, and use an array with only * MEDIAWIKI_EXIF_VERSION to denote no props. */ return ExifBitmapHandler::BROKEN_FILE; } }
public static function get_exif_info($img) { $exif = Exif::get_exif_arr($img); $imgtype = array("", "GIF", "JPG", "PNG", "SWF", "PSD", "BMP", "TIFF(intel byte order)", "TIFF(motorola byte order)", "JPC", "JP2", "JPX", "JB2", "SWC", "IFF", "WBMP", "XBM"); $Orientation = array("", "top left side", "top right side", "bottom right side", "bottom left side", "left side top", "right side top", "right side bottom", "left side bottom"); $ResolutionUnit = array("", "", "英寸", "厘米"); $YCbCrPositioning = array("", "the center of pixel array", "the datum point"); $ExposureProgram = array("未定义", "手动", "标准程序", "光圈先决", "快门先决", "景深先决", "运动模式", "肖像模式", "风景模式"); $MeteringMode_arr = array("0" => "未知", "1" => "平均", "2" => "中央重点平均测光", "3" => "点测", "4" => "分区", "5" => "评估", "6" => "局部", "255" => "其他"); $Lightsource_arr = array("0" => "未知", "1" => "日光", "2" => "荧光灯", "3" => "钨丝灯", "10" => "闪光灯", "17" => "标准灯光A", "18" => "标准灯光B", "19" => "标准灯光C", "20" => "D55", "21" => "D65", "22" => "D75", "255" => "其他"); $Flash_arr = array("0" => "flash did not fire", "1" => "flash fired", "5" => "flash fired but strobe return light not detected", "7" => "flash fired and strobe return light detected"); $exif_info = array("文件名" => isset($exif['FILE']['FileName']) ? $exif['FILE']['FileName'] : "", "文件类型" => isset($exif['FILE']['FileType']) ? isset($imgtype[$exif['FILE']['FileType']]) ? $imgtype[$exif['FILE']['FileType']] : "" : "", "文件格式" => isset($exif['FILE']['MimeType']) ? $exif['FILE']['MimeType'] : "", "文件大小" => isset($exif['FILE']['FileSize']) ? number_format($exif['FILE']['FileSize'] / 1000, 0) . " KB" : "", "时间戳" => isset($exif['FILE']['FileDateTime']) ? $exif['FILE']['FileDateTime'] : "", "图片说明" => isset($exif['IFD0']['ImageDescription']) ? $exif['IFD0']['ImageDescription'] : "", "制造商" => isset($exif['IFD0']['Make']) ? $exif['IFD0']['Make'] : "", "型号" => isset($exif['IFD0']['Model']) ? $exif['IFD0']['Model'] : "", "方向" => isset($exif['IFD0']['Orientation']) ? isset($Orientation[$exif['IFD0']['Orientation']]) ? $Orientation[$exif['IFD0']['Orientation']] : "" : "", "水平分辨率" => isset($exif['IFD0']['XResolution']) ? $exif['IFD0']['XResolution'] : "" . isset($exif['IFD0']['ResolutionUnit']) ? isset($ResolutionUnit[$exif['IFD0']['ResolutionUnit']]) ? $ResolutionUnit[$exif['IFD0']['ResolutionUnit']] : "" : "", "垂直分辨率" => isset($exif['IFD0']['YResolution']) ? $exif['IFD0']['YResolution'] : "" . isset($exif['IFD0']['ResolutionUnit']) ? isset($ResolutionUnit[$exif['IFD0']['ResolutionUnit']]) ? $ResolutionUnit[$exif['IFD0']['ResolutionUnit']] : "" : "", "创建软件" => isset($exif['IFD0']['Software']) ? $exif['IFD0']['Software'] : "", "修改时间" => isset($exif['IFD0']['DateTime']) ? $exif['IFD0']['DateTime'] : "", "作者" => isset($exif['IFD0']['Artist']) ? $exif['IFD0']['Artist'] : "", "YCbCr位置控制" => isset($exif['IFD0']['YCbCrPositioning']) ? isset($YCbCrPositioning[$exif['IFD0']['YCbCrPositioning']]) ? $YCbCrPositioning[$exif['IFD0']['YCbCrPositioning']] : "" : "", "版权" => isset($exif['IFD0']['Copyright']) ? $exif['IFD0']['Copyright'] : "", "摄影版权" => isset($exif['COMPUTED']['Copyright.Photographer']) ? $exif['COMPUTED']['Copyright.Photographer'] : "", "编辑版权" => isset($exif['COMPUTED']['Copyright.Editor']) ? $exif['COMPUTED']['Copyright.Editor'] : "", "Exif版本" => isset($exif['EXIF']['ExifVersion']) ? $exif['EXIF']['ExifVersion'] : "", "FlashPix版本" => isset($exif['EXIF']['FlashPixVersion']) ? "Ver. " . number_format($exif['EXIF']['FlashPixVersion'] / 100, 2) : "", "拍摄时间" => isset($exif['EXIF']['DateTimeOriginal']) ? $exif['EXIF']['DateTimeOriginal'] : "", "数字化时间" => isset($exif['EXIF']['DateTimeDigitized']) ? $exif['EXIF']['DateTimeDigitized'] : "", "拍摄分辨率高" => isset($exif['COMPUTED']['Height']) ? $exif['COMPUTED']['Height'] : "", "拍摄分辨率宽" => isset($exif['COMPUTED']['Width']) ? $exif['COMPUTED']['Width'] : "", "光圈" => isset($exif['EXIF']['ApertureValue']) ? $exif['EXIF']['ApertureValue'] : "", "快门速度" => isset($exif['EXIF']['ShutterSpeedValue']) ? $exif['EXIF']['ShutterSpeedValue'] : "", "快门光圈" => isset($exif['COMPUTED']['ApertureFNumber']) ? $exif['COMPUTED']['ApertureFNumber'] : "", "最大光圈值" => isset($exif['EXIF']['MaxApertureValue']) ? "F" . $exif['EXIF']['MaxApertureValue'] : "", "曝光时间" => isset($exif['EXIF']['ExposureTime']) ? $exif['EXIF']['ExposureTime'] : "", "F-Number" => isset($exif['EXIF']['FNumber']) ? $exif['EXIF']['FNumber'] : "", "测光模式" => isset($exif['EXIF']['MeteringMode']) ? Exif::get_img_val($exif['EXIF']['MeteringMode'], $MeteringMode_arr) : "", "光源" => isset($exif['EXIF']['LightSource']) ? Exif::get_img_val($exif['EXIF']['LightSource'], $Lightsource_arr) : "", "闪光灯" => isset($exif['EXIF']['Flash']) ? Exif::get_img_val($exif['EXIF']['Flash'], $Flash_arr) : "", "曝光模式" => isset($exif['EXIF']['ExposureMode']) ? $exif['EXIF']['ExposureMode'] == 1 ? "手动" : "自动" : "", "白平衡" => isset($exif['EXIF']['WhiteBalance']) ? $exif['EXIF']['WhiteBalance'] == 1 ? "手动" : "自动" : "", "曝光程序" => isset($exif['EXIF']['ExposureProgram']) ? isset($ExposureProgram[$exif['EXIF']['ExposureProgram']]) ? $ExposureProgram[$exif['EXIF']['ExposureProgram']] : "" : "", "曝光补偿" => isset($exif['EXIF']['ExposureBiasValue']) ? $exif['EXIF']['ExposureBiasValue'] . "EV" : "", "ISO感光度" => isset($exif['EXIF']['ISOSpeedRatings']) ? $exif['EXIF']['ISOSpeedRatings'] : "", "图像压缩率" => isset($exif['EXIF']['CompressedBitsPerPixel']) ? $exif['EXIF']['CompressedBitsPerPixel'] . "Bits/Pixel" : "", "对焦距离" => isset($exif['COMPUTED']['FocusDistance']) ? $exif['COMPUTED']['FocusDistance'] . "m" : "", "焦距" => isset($exif['EXIF']['FocalLength']) ? $exif['EXIF']['FocalLength'] . "mm" : "", "等价35mm焦距" => isset($exif['EXIF']['FocalLengthIn35mmFilm']) ? $exif['EXIF']['FocalLengthIn35mmFilm'] . "mm" : "", "用户注释编码" => isset($exif['COMPUTED']['UserCommentEncoding']) ? $exif['COMPUTED']['UserCommentEncoding'] : "", "用户注释" => isset($exif['COMPUTED']['UserComment']) ? $exif['COMPUTED']['UserComment'] : "", "色彩空间" => isset($exif['EXIF']['ColorSpace']) ? $exif['EXIF']['ColorSpace'] == 1 ? "sRGB" : "Uncalibrated" : "", "Exif图像宽度" => isset($exif['EXIF']['ExifImageLength']) ? $exif['EXIF']['ExifImageLength'] : "", "Exif图像高度" => isset($exif['EXIF']['ExifImageWidth']) ? $exif['EXIF']['ExifImageWidth'] : "", "文件来源" => isset($exif['EXIF']['FileSource']) ? bin2hex($exif['EXIF']['FileSource']) == 0x3 ? "digital still camera" : "unknown" : "", "场景类型" => isset($exif['EXIF']['SceneType']) ? bin2hex($exif['EXIF']['SceneType']) == 0x1 ? "A directly photographed image" : "unknown" : "", "缩略图文件格式" => isset($exif['COMPUTED']['Thumbnail.FileType']) ? $exif['COMPUTED']['Thumbnail.FileType'] : "", "缩略图Mime格式" => isset($exif['COMPUTED']['Thumbnail.MimeType']) ? $exif['COMPUTED']['Thumbnail.MimeType'] : ""); $degree = 0; if (isset($exif['IFD0']['Orientation'])) { $ort = $exif['IFD0']['Orientation']; switch ($ort) { case 1: // nothing break; case 2: // nothing break; case 3: $degree = 2; break; case 4: // nothing $degree = 2; break; case 5: $degree = 1; break; case 6: $degree = 1; break; case 7: $degree = 3; break; case 8: $degree = 3; break; } } $height = isset($exif['COMPUTED']['Height']) ? $exif['COMPUTED']['Height'] : 0; $width = isset($exif['COMPUTED']['Width']) ? $exif['COMPUTED']['Width'] : 0; //拍摄时间 $datetime_original = isset($exif['EXIF']['DateTimeOriginal']) ? $exif['EXIF']['DateTimeOriginal'] : ""; //相机型号 $camera_model = isset($exif['IFD0']['Model']) ? $exif['IFD0']['Model'] : ""; //文件格式 $pic_type = isset($exif['FILE']['MimeType']) ? $exif['FILE']['MimeType'] : ""; $exif_info['degree'] = $degree; $return = array("exif_info" => $exif_info, "degree" => $degree, "height" => $height, "width" => $width, "datetime_original" => $datetime_original, "pic_type" => $pic_type, "camera_model" => $camera_model); return $return; }
/** * Going through all the fields that have been created for a given node type * and try to figure out which match the naming convention -> so that we know * which exif information we have to read * * Naming convention are: field_exif_xxx (xxx would be the name of the exif * tag to read * * @param $arCckFields array of CCK fields * @return array a list of exif tags to read for this image */ public function getMetadataFields($arCckFields = array()) { $arSections = Exif::getMetadataSections(); foreach ($arCckFields as $drupal_field => $metadata_settings) { $metadata_field = $metadata_settings['metadata_field']; $ar = explode("_", $metadata_field); if (isset($ar[0]) && in_array($ar[0], $arSections)) { $section = $ar[0]; unset($ar[0]); $arCckFields[$drupal_field]['metadata_field'] = array('section' => $section, 'tag' => implode("_", $ar)); } } return $arCckFields; }
/** * Create new exif model with exif data * * @param string $filename * @param int $image_id of parent image * @return Exif_Model */ public static function factory($filename = false, $image_id = false) { $exif_model = new Exif_Model(); if ($filename) { // read exif data from file $exif_data = Exif::factory($filename)->read(); if (!empty($exif_data)) { // set image_id if given if ($image_id) { $exif_data['image_id'] = (int) $image_id; } // validate if ($exif_model->validate($exif_data)) { // save our model only if image_id was given if ($exif_model->image_id) { $exif_model->save(); } } } } return $exif_model; }
/** * @param $image * @param $filename * @return string */ function getMetadata($image, $filename) { global $wgShowEXIF; if ($wgShowEXIF) { try { $meta = BitmapMetadataHandler::Tiff($filename); if (!is_array($meta)) { // This should never happen, but doesn't hurt to be paranoid. throw new MWException('Metadata array is not an array'); } $meta['MEDIAWIKI_EXIF_VERSION'] = Exif::version(); return serialize($meta); } catch (MWException $e) { // BitmapMetadataHandler throws an exception in certain exceptional // cases like if file does not exist. wfDebug(__METHOD__ . ': ' . $e->getMessage() . "\n"); return ExifBitmapHandler::BROKEN_FILE; } } else { return ''; } }
<?php $fullFilename = loadPicFile("helpers/checkfilepath.php"); list($normalisedExtension, $mimeType) = loadPicFile("helpers/checkimagetype.php", array("filename" => $fullFilename)); $imageSizes = loadPicFile("conf/app.json")["image_sizes"]; if (empty($_POST["size"]) || !in_array($_POST["size"], array_keys($imageSizes))) { $imageSize = $imageSizes["medium"]; } else { $imageSize = $imageSizes[$_POST["size"]]; } $path = Access::getCurrentPath(); $image = PicImage::open($fullFilename); $image->cropResize($imageSize["width"], $imageSize["height"]); $image->fixOrientation(); $imageData = $image->cacheData($normalisedExtension); header("Content-type: {$mimeType}"); loadPicFile("classes/exif.php"); $exif = Exif::read($fullFilename); if ($path->hasPermission("metadata") && $exif) { header("X-Pictorials-Pic-Metadata: " . json_encode(array_filter(array("date_taken" => $exif->getCreationDate() ? $exif->getCreationDate()->format("Y-m-d") : null, "exposure" => $exif->getExposure(), "iso" => $exif->getIso(), "focal_length" => $exif->getFocalLength())))); } if ($path->hasPermission("gps") && $exif) { if ($gpsCoords = $exif->getGPS()) { list($gpsLat, $gpsLon) = explode(",", $gpsCoords); header("X-Pictorials-Pic-GPS: " . json_encode(array("lat" => (double) $gpsLat, "lon" => (double) $gpsLon))); } } echo $imageData;
function getExifData() { global $wgRequest; if ($this->metadata === '0') { return array(); } $purge = $wgRequest->getVal('action') == 'purge'; $ret = unserialize($this->metadata); $oldver = isset($ret['MEDIAWIKI_EXIF_VERSION']) ? $ret['MEDIAWIKI_EXIF_VERSION'] : 0; $newver = Exif::version(); if (!count($ret) || $purge || $oldver != $newver) { $this->updateExifData($newver); } if (isset($ret['MEDIAWIKI_EXIF_VERSION'])) { unset($ret['MEDIAWIKI_EXIF_VERSION']); } $format = new FormatExif($ret); return $format->getFormattedData(); }
function isMetadataValid($image, $metadata) { global $wgShowEXIF; if (!$wgShowEXIF) { # Metadata disabled and so an empty field is expected return true; } if ($metadata === '0') { # Special value indicating that there is no EXIF data in the file return true; } $exif = @unserialize($metadata); if (!isset($exif['MEDIAWIKI_EXIF_VERSION']) || $exif['MEDIAWIKI_EXIF_VERSION'] != Exif::version()) { # Wrong version wfDebug(__METHOD__ . ": wrong version\n"); return false; } return true; }
/** * @param object $metaObj Object from the FileMetadata class which calls this function * * @return array $metadata Returns an array of metadata */ function getExtendedData($metaObj) { /* * these properties can be accessed similarly for all image files and were set in the ImageFile class that * this class extends */ $metadata['header'] = $this->header; $metadata['width'] = $this->width; $metadata['height'] = $this->height; $metadata['otherinfo'] = $this->otherinfo; /* * these following types of metadata are also common to other types of files but may need to be accessed * differently based on file type */ //EXIF //get raw exif $metadata['exifraw'] = function_exists('exif_read_data') ? exif_read_data($metaObj->currname, 0, true) : false; //interpret and add tags if ($metadata['exifraw']) { require_once 'lib/metadata/datatypes/exif.php'; $exif = new Exif(); $metadata['exif'] = $exif->processRawData($metadata['exifraw']); //add EXIF to combined metadata array that is not reconciled $metadata['combined']['exif'] = $metadata['exif']; } else { $metadata['exif'] = false; } //IPTC //get raw iptc and place in an iptc key so that iptc array has same number of levels as exif and xmp //and to distinguish from digest key added later $metadata['iptcraw']['iptc'] = !empty($this->otherinfo['APP13']) ? iptcparse($this->otherinfo['APP13']) : false; //process raw iptc if (is_array($metadata['iptcraw']['iptc'])) { //first prepare for processing foreach ($metadata['iptcraw']['iptc'] as $fieldname => $value) { if (count($value) > 1) { $metadata['iptcraw']['iptc'][$fieldname] = $value; } else { $metadata['iptcraw']['iptc'][$fieldname] = $value[0]; } } //process raw data require_once 'lib/metadata/datatypes/iptc.php'; $iptc = new Iptc(); $metadata['iptc'] = $iptc->processRawData($metadata['iptcraw']); //add IPTC to combined metadata array that is not reconciled $metadata['combined']['iptc'] = $metadata['iptc']; //check stored and create current hash /* * add stored iptc hash if it exists * The IPTC block is within the APP13 (Photoshop) segment, which is at $this->otherinfo['APP13'] * The stored checksum is at hex marker \x38\x42\x49\x4D\x04\x25\x00\x00\x00\x00 (resource ID 1061) */ $hashstored = $metaObj->getDataSegment($this->otherinfo['APP13'], "8BIM%", 10, 2); if (!empty($hashstored)) { $metadata['iptc']['digest']['iptchashstored'] = array('newval' => bin2hex($hashstored), 'label' => 'Stored IPTC Hash'); } /* * add calculated current hash of the IPTC block, * which starts at hex marker \x38\x42\x49\x4D\x04\x04\x00\x00\x00\x00 within the APP13 segment */ $iptcblock = $metaObj->getDataSegment($this->otherinfo['APP13'], "8BIM", 10, 2); if (!empty($iptcblock)) { $metadata['iptc']['digest']['iptchashcurrent'] = array('newval' => md5($iptcblock), 'label' => 'Computed IPTC Hash'); } if (!isset($metadata['iptc']['digest']['iptchashstored']['newval']) || strlen($metadata['iptc']['digest']['iptchashstored']['newval']) > 0 && $metadata['iptc']['digest']['iptchashstored']['newval'] == $metadata['iptc']['digest']['iptchashcurrent']['newval']) { if (isset($metadata['iptc']['digest']['iptchashstored']['newval'])) { $metadata['iptc']['digest']['match']['newval'] = ''; //place text in suffix so it can be translated $metadata['iptc']['digest']['match']['suffix'] = 'IPTC stored and actual hash match - indication that metadata editors were compliant'; $metadata['iptc']['digest']['match']['label'] = 'Note'; } } else { $metadata['iptc']['digest']['mismatch']['newval'] = ''; $metadata['iptc']['digest']['mismatch']['suffix'] = 'Metadata has been edited by a noncompliant editor - IPTC stored and actual hash do not match'; $metadata['iptc']['digest']['mismatch']['label'] = 'Warning'; } /* * In case we needed to get the individual APP13 records, below are a couple of examples * each record starts with the tag marker of hex 1c (13), followed by record number and dataset number * * Example: record number is 02 and dataset number is hex 74 (116), so this is IPTC field 2#116 (or 2:116) * $single = $metaObj->getDataSegment($this->otherinfo['APP13'], "\x1c\x02\x74", 3, 2); * * Example2: record number is 01 and dataset number is hex 5a (90), so this is IPTC field 1#090 (or 1:090) * $single2 = $metaObj->getDataSegment($this->otherinfo['APP13'], "\x1c\x01\x5a", 3, 2); * * next two bytes after the record and dataset number are the size of the dataset */ } else { $metadata['iptc'] = false; } //XMP //get raw xmp DOM, convert to an array add tags and interpret if (!empty($metaObj->content)) { require_once 'lib/metadata/datatypes/xmp.php'; $xmp = new Xmp(); $metadata['xmpraw'] = $xmp->getXmp($metaObj->content, $metaObj->basicraw['type']); $metadata['xmp'] = $xmp->processRawData($metadata['xmpraw']); } else { $metadata['xmpraw'] = false; $metadata['xmp'] = false; } //add XMP to combined unreconciled metadata array if ($metadata['xmp'] !== false) { $metadata['combined']['xmp'] = $metadata['xmp']; } //Reconcile extended metadata in accordance with the Metadata Working Group standards require_once 'lib/metadata/reconcile.php'; $rec = new ReconcileExifIptcXmp(); $metadata['reconciled'] = $rec->reconcileAllMeta($metadata); //Add basic info $metadata = $metaObj->mergeBasicInfo($metaObj, $metadata); return $metadata; }
/** * Reads metadata of the tiff file via shell command and returns an associative array. * layout: * meta['page_count'] = number of pages * meta['first_page'] = number of first page * meta['last_page'] = number of last page * meta['page_data'] = metadata per page * meta['exif'] = Exif, XMP and IPTC * meta['errors'] = identify-errors * meta['warnings'] = identify-warnings */ public function retrieveMetaData() { global $wgImageMagickIdentifyCommand, $wgExiv2Command, $wgTiffUseExiv; global $wgTiffUseTiffinfo, $wgTiffTiffinfoCommand; global $wgShowEXIF; if ( $this->_meta === null ) { wfProfileIn( 'PagedTiffImage::retrieveMetaData' ); //fetch base info: number of pages, size and alpha for each page. //run hooks first, then optionally tiffinfo or, per default, ImageMagic's identify command if ( !wfRunHooks( 'PagedTiffHandlerTiffData', array( $this->mFilename, &$this->_meta ) ) ) { wfDebug( __METHOD__ . ": hook PagedTiffHandlerTiffData overrides TIFF data extraction\n" ); } elseif ( $wgTiffUseTiffinfo ) { // read TIFF directories using libtiff's tiffinfo, see // http://www.libtiff.org/man/tiffinfo.1.html $cmd = wfEscapeShellArg( $wgTiffTiffinfoCommand ) . ' ' . wfEscapeShellArg( $this->mFilename ) . ' 2>&1'; wfProfileIn( 'tiffinfo' ); wfDebug( __METHOD__ . ": $cmd\n" ); $retval = ''; $dump = wfShellExec( $cmd, $retval ); wfProfileOut( 'tiffinfo' ); if ( $retval ) { $data['errors'][] = "tiffinfo command failed: $cmd"; wfDebug( __METHOD__ . ": tiffinfo command failed: $cmd\n" ); return $data; // fail. we *need* that info } $this->_meta = $this->parseTiffinfoOutput( $dump ); } else { $cmd = wfEscapeShellArg( $wgImageMagickIdentifyCommand ) . ' -format "[BEGIN]page=%p\nalpha=%A\nalpha2=%r\nheight=%h\nwidth=%w\ndepth=%z[END]" ' . wfEscapeShellArg( $this->mFilename ) . ' 2>&1'; wfProfileIn( 'identify' ); wfDebug( __METHOD__ . ": $cmd\n" ); $retval = ''; $dump = wfShellExec( $cmd, $retval ); wfProfileOut( 'identify' ); if ( $retval ) { $data['errors'][] = "identify command failed: $cmd"; wfDebug( __METHOD__ . ": identify command failed: $cmd\n" ); return $data; // fail. we *need* that info } $this->_meta = $this->parseIdentifyOutput( $dump ); } $this->_meta['exif'] = array(); //fetch extended info: EXIF/IPTC/XMP //run hooks first, then optionally Exiv2 or, per default, the internal EXIF class if ( !empty( $this->_meta['errors'] ) ) { wfDebug( __METHOD__ . ": found errors, skipping EXIF extraction\n" ); } elseif ( !wfRunHooks( 'PagedTiffHandlerExifData', array( $this->mFilename, &$this->_meta['exif'] ) ) ) { wfDebug( __METHOD__ . ": hook PagedTiffHandlerExifData overrides EXIF extraction\n" ); } elseif ( $wgTiffUseExiv ) { // read EXIF, XMP, IPTC as name-tag => interpreted data // -ignore unknown fields // see exiv2-doc @link http://www.exiv2.org/sample.html // NOTE: the linux version of exiv2 has a bug: it can only // read one type of meta-data at a time, not all at once. $cmd = wfEscapeShellArg( $wgExiv2Command ) . ' -u -psix -Pnt ' . wfEscapeShellArg( $this->mFilename ) . ' 2>&1'; wfProfileIn( 'exiv2' ); wfDebug( __METHOD__ . ": $cmd\n" ); $retval = ''; $dump = wfShellExec( $cmd, $retval ); wfProfileOut( 'exiv2' ); if ( $retval ) { $data['errors'][] = "exiv command failed: $cmd"; wfDebug( __METHOD__ . ": exiv command failed: $cmd\n" ); // don't fail - we are missing info, just report } $data = $this->parseExiv2Output( $dump ); $this->_meta['exif'] = $data; } elseif ( $wgShowEXIF ) { wfDebug( __METHOD__ . ": using internal Exif( {$this->mFilename} )\n" ); if ( method_exists( 'BitmapMetadataHandler', 'Tiff' ) ) { $data = BitmapMetadataHandler::Tiff( $this->mFilename ); } else { // old method for back compat. $exif = new Exif( $this->mFilename ); $data = $exif->getFilteredData(); } if ( $data ) { $data['MEDIAWIKI_EXIF_VERSION'] = Exif::version(); $this->_meta['exif'] = $data; } } unset( $this->_meta['exif']['Image'] ); unset( $this->_meta['exif']['filename'] ); unset( $this->_meta['exif']['Base filename'] ); unset( $this->_meta['exif']['XMLPacket'] ); unset( $this->_meta['exif']['ImageResources'] ); $this->_meta['TIFF_METADATA_VERSION'] = TIFF_METADATA_VERSION; wfProfileOut( 'PagedTiffImage::retrieveMetaData' ); } return $this->_meta; }
public function uploadFileEnd($temp_id, $flag) { $uid = $this->uid; $data = $this->db->getRow("album_upload_temp", "file_title, file_md5, file_size, file_offset, file_path, file_type", "temp_id={$temp_id} AND user_id={$uid}"); if (!$data) { return array("code" => 403, "msg" => "uploadID不存在或无权限"); } //if($data['file_size'] != $data['file_offset']) { // return array("code" => 403, "msg" => "文件大小不匹配."); //} //$tempfsize = 0; //if( file_exists(ALBUM_TEMP.$data['file_path']) ) { // $tempfsize = filesize(ALBUM_TEMP.$data['file_path']); //} //if(!$tempfsize || $tempfsize != $data['file_size']) { // return array("code" => 403, "msg" => "文件大小不匹配!"); //} //移动临时文件到文件目录 if (!is_dir(ALBUM_IMAGE . $uid)) { mkdir(ALBUM_IMAGE . $uid, 0777); } //临时文件移动到user文件夹下 $tempfname = substr($data['file_path'], 0, -4); rename(ALBUM_TEMP . $data['file_path'], ALBUM_IMAGE . $tempfname); //移动文件成功 if (file_exists(ALBUM_IMAGE . $tempfname)) { $file_url = ALBUM_IMAGE . $tempfname; //获取图片的EXIF信息 $exif = Exif::get_exif_info($file_url); $img_exif = $exif['exif_info']; $degree = $exif['degree']; //获取图片的高度、宽度 $img = getimagesize($file_url); $width = $img[0]; $height = $img[1]; $file_format = $img[2]; if (!$img || !$width || !$height || $file_format > 6) { return false; } if ($file_format == 2 && $degree) { //旋转图片 $rotateDeg = $degree * 90; Image::rotate_by_degree($file_url, $rotateDeg); if ($degree == 1 || $degree == 3) { $t = $width; $width = $height; $height = $t; } $img_exif['degree'] = 0; $degree = 0; } $flag = $flag ? $flag : 2; //广播标识 $album_id = $this->db->getOne("wp_album", "album_id", "user_id = {$uid} AND album_flag={$flag}"); if (!$album_id) { //创建广播相册 $album_data = array('album_name' => '广播相册', 'user_id' => $uid, 'create_dt' => time(), 'update_dt' => time(), 'album_flag' => $flag); $album_id = $this->db->insertData("wp_album", $album_data); } $pic_info = array('album_id' => $album_id, 'user_id' => $uid, 'create_time' => time(), 'update_time' => time(), 'upload_ip' => $_SERVER['REMOTE_ADDR'], 'file_md5' => $data['file_md5'], 'file_size' => $data['file_size'], 'file_type' => $data['file_type'], 'pic_width' => $width, 'pic_height' => $height, 'degree' => intval($degree), 'appid' => 1); //上传到FS include 'application/include/FastDFS.php'; $this->fs = FastDFS::factory('group1'); //FS存储地址 $img_fs_name = $this->fs->upByFileName($file_url); //写TTServer $value = array("pic_fs_path" => $img_fs_name, "exif" => serialize($img_exif), "width" => $width, "height" => $height); $this->TT = new TTServer(); $this->TT->set($data['file_md5'], $value); $pic_id = $this->db->insertData("wp_pic", $pic_info); $this->db->query("UPDATE wp_album SET pic_num = pic_num+1 WHERE album_id={$album_id}"); //删除临时表数据 $this->db->DeleteData("album_upload_temp", array("temp_id" => $temp_id)); //生成160 $images = Image::createThumb_by_type($file_url, 160); $thumb_fs_name = substr($img_fs_name, 0, -4); $meta = array('remote_filename' => $thumb_fs_name . '_160.jpg'); $this->fs->upByFileName($images, $meta); if (file_exists($images)) { unlink($images); } return array("pid" => $pic_id, "url" => Kohana::config('album.recordThumb') . 'imgs/' . $pic_id . '_160.jpg', "uploaded" => true); } else { //移动文件失败 return null; } }
/** * This doesn't do much yet, but eventually I plan to add * XMP support for Tiff. (PHP's exif support already extracts * but needs some further processing because PHP's exif support * is stupid...) * * @todo Add XMP support, so this function actually makes * sense to put here. * * The various exceptions this throws are caught later. * @param $filename String * @throws MWException * @return Array The metadata. */ public static function Tiff($filename) { if (file_exists($filename)) { $byteOrder = self::getTiffByteOrder($filename); if (!$byteOrder) { throw new MWException("Error determining byte order of {$filename}"); } $exif = new Exif($filename, $byteOrder); $data = $exif->getFilteredData(); if ($data) { $data['MEDIAWIKI_EXIF_VERSION'] = Exif::version(); return $data; } else { throw new MWException("Could not extract data from tiff file {$filename}"); } } else { throw new MWException("File doesn't exist - {$filename}"); } }
public function update_contact_avatar($small_data, $middle_data, $original_data, $pic_data) { $user_id = $this->uid; //获取通讯录相册 $album_id = $this->db->getOne("wp_album", "album_id", "user_id = {$user_id} AND album_flag = '3'"); if (!$album_id) { $data = array("album_name" => '通讯录相册', "user_id" => $user_id, "create_dt" => time(), "update_dt" => time(), "album_flag" => 3); $album_id = $this->db->insertData("wp_album", $data); } $file_md5 = md5($original_data); if (!$this->TT) { $this->TT = new TTServer(); } $data = $this->TT->get($file_md5); //上传到FS include 'application/include/FastDFS.php'; $this->fs = FastDFS::factory('group1'); if ($data) { //生成新的格式的FS $fsfile_name_array = explode('.', $data['pic_fs_path']); $thumb_small_path = $fsfile_name_array[0] . '_48.' . $fsfile_name_array[1]; $thumb_middle_path = $fsfile_name_array[0] . '_120.' . $fsfile_name_array[1]; //已存在 $dataExif = unserialize($data['exif']); $pic_data_array['pic_width'] = $dataExif['拍摄分辨率宽'] ? $dataExif['拍摄分辨率宽'] : $data['width']; $pic_data_array['pic_height'] = $dataExif['拍摄分辨率高'] ? $dataExif['拍摄分辨率高'] : $data['height']; $pic_data_array['degree'] = $dataExif['方向']; //上传size=small的图片 $meta = array('remote_filename' => $thumb_small_path); $fs_small = $this->fs->upByBuff($small_data, 'jpg', $meta); //上传size=middle的图片 $meta = array('remote_filename' => $thumb_middle_path); $fs_middle = $this->fs->upByBuff($middle_data, 'jpg', $meta); //插入 数据大wp图片表 $pic_data_array['album_id'] = $album_id; $pic_data_array['user_id'] = $user_id; $pic_data_array['create_time'] = time(); $pic_data_array['update_time'] = time(); $pic_data_array['upload_ip'] = $_SERVER['REMOTE_ADDR']; $pic_data_array['upload_file_name'] = $pic_data['upload_file_name']; $pic_data_array['file_md5'] = $file_md5; $pic_data_array['file_size'] = strlen($original_data); $pic_id = $this->db->insertData("wp_pic", $pic_data_array); if ($pic_id) { return array("data" => array("0" => Kohana::config('album.recordThumb') . 'imgs/' . $pic_id . '.jpg', "1" => Kohana::config('album.recordThumb') . 'imgs/' . $pic_id . '_120.jpg')); } else { return null; } } else { //写入用户临时图片文件 //写入文件 if (!is_dir(ALBUM_IMAGE . $user_id)) { mkdir(ALBUM_IMAGE . $user_id, 0777); } $tmpfname = ALBUM_IMAGE . $user_id . '/' . $user_id . '_' . $file_md5 . '.jpg'; $handle = fopen($tmpfname, "w"); fseek($handle, 0); //移动指针到文件开始位置 fwrite($handle, $original_data); fclose($handle); //上传到DFS、获得文件映射名 //fs图片文件映射 $img_fs_name = $this->fs->upByFileName($tmpfname); if ($img_fs_name) { $fsfile_type_array = explode('.', $img_fs_name); $fsfile_name = $fsfile_type_array[0]; $thumb_small_path = $fsfile_type_array[0] . '_48.' . $fsfile_type_array[1]; $thumb_middle_path = $fsfile_type_array[0] . '_120.' . $fsfile_type_array[1]; //上传size=small的图片 $meta = array('remote_filename' => $thumb_small_path); $fs_small = $this->fs->upByBuff($small_data, 'jpg', $meta); //上传size=middle的图片 $meta = array('remote_filename' => $thumb_middle_path); $fs_middle = $this->fs->upByBuff($middle_data, 'jpg', $meta); } //获取图片exif信息 $exif = Exif::get_exif_info($tmpfname); $img_exif = $exif['exif_info']; $degree = $exif['degree'] ? intval($exif['degree']) : 0; $imgsWH = Image::getImagesWidthHight($tmpfname); $images_width = $imgsWH['width']; $images_height = $imgsWH['height']; //缩略图队列写入内存表 $thumb_array = array(); $thumb_array['file_path'] = $tmpfname; $thumb_array['fs_path'] = $fsfile_name; /* $thumbs = $this->create_thumb_by_width_height($images_width, $images_height, true, true); foreach ( $thumbs as $key => $value ) { if($key == 0) { $thumb_type_array.= $value['type']; } else { $thumb_type_array.= ','.$value['type']; } } $thumb_array['thumb_type'] = $thumb_type_array ; $thumb_array['images_width'] = $images_width; $thumb_array['images_height'] = $images_height; $thumb_array['create_time'] = time(); $this->add_to_thumb_queue($thumb_array); */ //添加数据到TTServer $value = array("pic_fs_path" => $img_fs_name, "exif" => serialize($img_exif)); $this->TT->set($file_md5, $value); //写表 $pic_data_array = array(); $pic_data_array['pic_width'] = $images_width; $pic_data_array['pic_height'] = $images_height; $pic_data_array['degree'] = $degree; $pic_data_array['album_id'] = $album_id; $pic_data_array['user_id'] = $user_id; $pic_data_array['create_time'] = time(); $pic_data_array['update_time'] = time(); $pic_data_array['upload_ip'] = $_SERVER['REMOTE_ADDR']; $pic_data_array['upload_file_name'] = $pic_data['upload_file_name']; $pic_data_array['file_md5'] = $file_md5; $pic_data_array['file_size'] = strlen($original_data); $pic_id = $this->db->insertData("wp_pic", $pic_data_array); if ($pic_id) { return array("data" => array("0" => Kohana::config('album.recordThumb') . 'imgs/' . $pic_id . '.jpg', "1" => Kohana::config('album.recordThumb') . 'imgs/' . $pic_id . '_120.jpg')); } else { return null; } } }