PHP ने EXIF और IPTC मेटाडेटा पढ़ने के लिए समर्थन में बनाया है, लेकिन मुझे एक्सएमपी पढ़ने का कोई तरीका नहीं मिल रहा है?मैं PHP के साथ जेपीजी से एक्सएमपी डेटा कैसे पढ़ सकता हूं?
उत्तर
एक्सएमपी डेटा सचमुच छवि फ़ाइल में एम्बेड किया गया है, इसलिए इसे छवि फ़ाइल से PHP के स्ट्रिंग-फ़ंक्शंस के साथ निकाला जा सकता है।
निम्नलिखित इस प्रक्रिया को दर्शाता है (मैं SimpleXML उपयोग कर रहा हूँ, लेकिन हर दूसरे XML API या यहाँ तक कि सरल और चालाक स्ट्रिंग पार्स आप समान परिणाम दे सकते हैं):
$content = file_get_contents($image);
$xmp_data_start = strpos($content, '<x:xmpmeta');
$xmp_data_end = strpos($content, '</x:xmpmeta>');
$xmp_length = $xmp_data_end - $xmp_data_start;
$xmp_data = substr($content, $xmp_data_start, $xmp_length + 12);
$xmp = simplexml_load_string($xmp_data);
सिर्फ दो टिप्पणी:
- एक्सएमपी एक्सएमएल नेमस्पेस का भारी उपयोग करता है, इसलिए आपको कुछ एक्सएमएल उपकरणों के साथ एक्सएमपी डेटा को पार्स करते समय उस पर नजर रखना होगा।
- छवि फ़ाइलों के संभावित आकार पर विचार करते हुए, आप शायद
file_get_contents()
का उपयोग करने में सक्षम नहीं होंगे क्योंकि यह फ़ंक्शन पूरी छवि को स्मृति में लोड करता है। फ़ाइल स्ट्रीम संसाधन खोलने और कुंजी-अनुक्रम<x:xmpmeta
और</x:xmpmeta>
के लिए डेटा के हिस्सों की जांच करने के लिएfopen()
का उपयोग करना स्मृति पदचिह्न को काफी कम करेगा।
मैं केवल इतना समय के बाद इसका जवाब दे रहा हूं क्योंकि एक्सएमपी डेटा को पार्स करने के लिए Google को खोजते समय यह सबसे अच्छा परिणाम प्रतीत होता है। मैंने इस लगभग समान स्निपेट को कोड में कुछ बार देखा है और यह स्मृति का एक भयानक अपशिष्ट है। यहां उनके उदाहरण के बाद फॉपेन() विधि स्टीफन का उल्लेख है।
<?php
function getXmpData($filename, $chunkSize)
{
if (!is_int($chunkSize)) {
throw new RuntimeException('Expected integer value for argument #2 (chunkSize)');
}
if ($chunkSize < 12) {
throw new RuntimeException('Chunk size cannot be less than 12 argument #2 (chunkSize)');
}
if (($file_pointer = fopen($filename, 'r')) === FALSE) {
throw new RuntimeException('Could not open file for reading');
}
$startTag = '<x:xmpmeta';
$endTag = '</x:xmpmeta>';
$buffer = NULL;
$hasXmp = FALSE;
while (($chunk = fread($file_pointer, $chunkSize)) !== FALSE) {
if ($chunk === "") {
break;
}
$buffer .= $chunk;
$startPosition = strpos($buffer, $startTag);
$endPosition = strpos($buffer, $endTag);
if ($startPosition !== FALSE && $endPosition !== FALSE) {
$buffer = substr($buffer, $startPosition, $endPosition - $startPosition + 12);
$hasXmp = TRUE;
break;
} elseif ($startPosition !== FALSE) {
$buffer = substr($buffer, $startPosition);
$hasXmp = TRUE;
} elseif (strlen($buffer) > (strlen($startTag) * 2)) {
$buffer = substr($buffer, strlen($startTag));
}
}
fclose($file_pointer);
return ($hasXmp) ? $buffer : NULL;
}
यह ध्यान देने योग्य है कि जब छवि में कोई एक्सएमपी डेटा नहीं होता है, तो यह लटकता है, हालांकि मुझे यकीन है कि इसे आसानी से हल किया जा सकता है जो जानता है कि कैसे। –
मैंने लूप को मारने के लिए एक और \ ब्रेक स्थिति जोड़ा जो फ़ाइल –
में कोई एक्सएमपी तत्व मौजूद नहीं है, मैंने पहले इस खंड को प्रतिलिपि बनाने के लिए इस फ़ंक्शन को दोबारा प्रतिक्रिया दी और उसके बाद ऐसा करने की कोशिश करने के बजाय बफर के खिलाफ पहचान/संशोधन निष्पादित किया भाग –
मैं XMP Php Tookit विस्तार विकसित किया है: यह एक PHP5 एडोब XMP टूलकिट के आधार पर विस्तार है, जो jpeg, PSD, पीडीएफ से/लिखने/पार्स XMP metadatas पढ़ने के लिए मुख्य वर्गों और विधि प्रदान है, वीडियो, ऑडियो ... यह एक्सटेंशन जीपीएल लाइसेंस के तहत है। एक नई रिलीज जल्द ही उपलब्ध होगी, php 5.3 (अब केवल php 5.2.x के साथ संगत), और विंडोज और मैकॉक्स पर उपलब्ध होना चाहिए (अब केवल फ्रीब्स और लिनक्स सिस्टम के लिए)। http://xmpphptoolkit.sourceforge.net/
मैंने आपके टूलकिट की कोशिश की, लेकिन मैं इसे संकलित नहीं कर सका :(गायब प्रिंटफ के बारे में शिकायत करना। "Xmp_toolkit/common/XMP_LibUtils.hpp: 179: 62: त्रुटि: इस स्कोप में 'printf' घोषित नहीं किया गया था" – haggi
लिनक्स पर एक आसान तरीका exiv2 प्रोग्राम को कॉल करना है, जो डेबियन पर एक नामांकित पैकेज में उपलब्ध है।
$ exiv2 -e X extract image.jpg
एम्बेडेड एक्सएमपी युक्त image.xmp का उत्पादन करेगा जो अब आपके लिए पार्स है।
ब्रायन का समाधान अब तक का सबसे अच्छा था, लेकिन इसमें कुछ समस्याएं थीं इसलिए मैंने इसे सरल बनाने के लिए इसे संशोधित किया, और कुछ कार्यक्षमता को हटा दिया।
तीन मुद्दों मैं उसके समाधान के साथ पाया थे:
ए) हिस्सा निकाला सही तार हम खोज रहे होते हैं में से एक के बीच में पड़ता है, तो इसे प्राप्त नहीं कर सकेंगे। इस मुद्दे का कारण बनने के लिए छोटे हिस्से के आकार अधिक होने की संभावना है।
बी) यदि खंड में शुरुआत और अंत दोनों शामिल हैं, तो यह नहीं मिलेगा। अगर यह अंत में पाया जाता है कि यह देखने के लिए शुरूआत में पाया गया है कि उस खंड को फिर से जांचने के लिए अतिरिक्त विवरण के साथ यह ठीक करना एक आसान तरीका है।
सी) अन्य लूप को तोड़ने के अंत में जोड़ा गया कथन अगर यह नहीं मिलता है कि xmp डेटा का दुष्प्रभाव है कि अगर प्रारंभ तत्व पहले पास पर नहीं मिलता है, तो यह अब और जांच नहीं करेगा मात्रा। यह भी ठीक करने के लिए आसान है, लेकिन पहली समस्या के साथ यह इसके लायक नहीं है।
नीचे मेरा समाधान उतना शक्तिशाली नहीं है, लेकिन यह अधिक मजबूत है। यह केवल एक खंड की जांच करेगा, और उस से डेटा निकाल देगा। यह केवल तभी काम करेगा जब शुरुआत और अंत उस खंड में हों, इसलिए यह सुनिश्चित करने के लिए कि यह हमेशा उस डेटा को कैप्चर करता है, तो खंड आकार को इतना बड़ा होना चाहिए। एडोब फोटोशॉप/लाइटरूम निर्यात की गई फ़ाइलों के साथ अपने अनुभव से, एक्सएमपी डेटा आमतौर पर लगभग 20 केबी से शुरू होता है, और लगभग 45 केबी पर समाप्त होता है। 50k का मेरा हिस्सा आकार मेरी छवियों के लिए अच्छी तरह से काम करता प्रतीत होता है, यदि आप निर्यात पर उस डेटा को कुछ पट्टी करते हैं, तो सीआरएस ब्लॉक जैसे बहुत सी विकास सेटिंग्स हैं, तो यह बहुत कम होगा।
function getXmpData($filename)
{
$chunk_size = 50000;
$buffer = NULL;
if (($file_pointer = fopen($filename, 'r')) === FALSE) {
throw new RuntimeException('Could not open file for reading');
}
$chunk = fread($file_pointer, $chunk_size);
if (($posStart = strpos($chunk, '<x:xmpmeta')) !== FALSE) {
$buffer = substr($chunk, $posStart);
$posEnd = strpos($buffer, '</x:xmpmeta>');
$buffer = substr($buffer, 0, $posEnd + 12);
}
fclose($file_pointer);
return $buffer;
}
मैंने अपडेट किया तर्क के मुद्दों के साथ फिक्स के साथ मेरा कार्य :) :) –
आह, धन्यवाद ब्रायन! मैंने कभी नहीं देखा कि आपने अभी तक जवाब दिया है। मैं आपके संशोधित कोड की समीक्षा करूंगा और देख सकता हूं कि यह मेरे लिए काम करता है (मैं अभी तक इसे पूरी तरह से समझ नहीं पा रहा हूं, मैं प्रोग्रामर नहीं हूं ...) –
ओह, मुझे अब मिल गया .. आप बफर बना रहे हैं एक समय में हिस्सा और हमेशा बफर की जांच। यह सूचीबद्ध सभी समस्याओं को रोकता है। होशियार! धन्यवाद। –
उस संक्षिप्त संस्करण के लिए सेबस्टियन बी धन्यवाद :)। यदि आप समस्या से बचना चाहते हैं, तो जब कुछ फ़ाइलों के लिए chunk_size बहुत छोटा है, तो बस रिकर्सन जोड़ें।
function getXmpData($filename, $chunk_size = 50000){
$buffer = NULL;
if (($file_pointer = fopen($filename, 'r')) === FALSE) {
throw new RuntimeException('Could not open file for reading');
}
$chunk = fread($file_pointer, $chunk_size);
if (($posStart = strpos($chunk, '<x:xmpmeta')) !== FALSE) {
$buffer = substr($chunk, $posStart);
$posEnd = strpos($buffer, '</x:xmpmeta>');
$buffer = substr($buffer, 0, $posEnd + 12);
}
fclose($file_pointer);
// recursion here
if(!strpos($buffer, '</x:xmpmeta>')){
$buffer = getXmpData($filename, $chunk_size*2);
}
return $buffer;
}
मुझे पता है ... यह एक पुराने धागे की तरह है, लेकिन यह मेरे लिए मददगार था जब मैं यह करने के लिए एक तरह से तलाश कर रहे थे, तो मैं समझ यह किसी और के लिए उपयोगी हो सकता है।
मैंने यह मूल समाधान लिया और इसे संशोधित किया ताकि यह उस मामले को संभाल सके जहां टैग को भाग के बीच विभाजित किया गया हो। यह आपके इच्छित हिस्से के रूप में बड़े आकार के छोटे या छोटे होने की अनुमति देता है।
<?php
function getXmpData($filename, $chunk_size = 1024)
{
\t if (!is_int($chunkSize)) {
\t \t throw new RuntimeException('Expected integer value for argument #2 (chunkSize)');
\t }
\t if ($chunkSize < 12) {
\t \t throw new RuntimeException('Chunk size cannot be less than 12 argument #2 (chunkSize)');
\t }
\t if (($file_pointer = fopen($filename, 'rb')) === FALSE) {
\t \t throw new RuntimeException('Could not open file for reading');
\t }
\t $tag = '<x:xmpmeta';
\t $buffer = false;
\t // find open tag
\t while ($buffer === false && ($chunk = fread($file_pointer, $chunk_size)) !== false) {
\t \t if(strlen($chunk) <= 10) {
\t \t \t break;
\t \t }
\t \t if(($position = strpos($chunk, $tag)) === false) {
\t \t \t // if open tag not found, back up just in case the open tag is on the split.
\t \t \t fseek($file_pointer, -10, SEEK_CUR);
\t \t } else {
\t \t \t $buffer = substr($chunk, $position);
\t \t }
\t }
\t if($buffer === false) {
\t \t fclose($file_pointer);
\t \t return false;
\t }
\t $tag = '</x:xmpmeta>';
\t $offset = 0;
\t while (($position = strpos($buffer, $tag, $offset)) === false && ($chunk = fread($file_pointer, $chunk_size)) !== FALSE && !empty($chunk)) {
\t \t $offset = strlen($buffer) - 12; // subtract the tag size just in case it's split between chunks.
\t \t $buffer .= $chunk;
\t }
\t fclose($file_pointer);
\t if($position === false) {
\t \t // this would mean the open tag was found, but the close tag was not. Maybe file corruption?
\t \t throw new RuntimeException('No close tag found. Possibly corrupted file.');
\t } else {
\t \t $buffer = substr($buffer, 0, $position + 12);
\t }
\t return $buffer;
}
?>
आप ExifTool उपलब्ध (एक बहुत उपयोगी उपकरण) है और बाहरी कमांड चलाने कर सकते हैं, तो आप इसे JSON प्रारूप में यह उत्पादन XMP डेटा निकालने के लिए विकल्प (-xmp:all
) और (-json
है उपयोग कर सकते हैं), जिसे आप आसानी से एक PHP ऑब्जेक्ट में परिवर्तित कर सकते हैं:
$command = 'exiftool -g -json -struct -xmp:all "'.$image_path.'"';
exec($command, $output, $return_var);
$metadata = implode('', $output);
$metadata = json_decode($metadata);
- 1. मैं PHP के साथ .tar.gz फ़ाइल कैसे पढ़ सकता हूं?
- 2. मैं PHP से पीएनजी मेटाडाटा कैसे पढ़ सकता हूं?
- 3. मैं QTableWidget पर डेटा कैसे दिखा सकता हूं और हेडर के साथ डेटा पढ़ सकता हूं?
- 4. मैं wfstream से बाइनरी डेटा कैसे पढ़ सकता हूं?
- 5. मैं यूएसबी फ्लैश ड्राइव से डेटा कैसे पढ़ सकता हूं?
- 6. मैं यूपीपी के माध्यम से PHP के साथ आईपी पते पर डेटा कैसे भेज सकता हूं?
- 7. मैं केकेपीएचपी में सत्र डेटा कैसे बना सकता हूं, लिख सकता हूं और पढ़ सकता हूं?
- 8. क्या मैं XDomainRequest के माध्यम से ठीक से बाइनरी डेटा पढ़ सकता हूं?
- 9. मैं .docx फ़ाइल कैसे पढ़ सकता हूं?
- 10. मैं जीपीयू लोड कैसे पढ़ सकता हूं?
- 11. मैं जावा में यूआरएल से छवि कैसे पढ़ सकता हूं?
- 12. मैं एक COM पोर्ट का अनुकरण कैसे कर सकता हूं, डेटा लिख सकता हूं और उससे डेटा पढ़ सकता हूं?
- 13. मैं फ़ाइल से पहली पंक्ति कैसे पढ़ सकता हूं?
- 14. ओपनसीवी में एक्सएमएल-स्ट्रिंग से मैं कैसे पढ़ सकता हूं?
- 15. मैं बाइटएरे (फ्लैश से) और कुछ फॉर्म डेटा को php पर कैसे भेज सकता हूं?
- 16. मैं पर्ल में एक्सेल फ़ाइलों को कैसे पढ़ सकता हूं?
- 17. डेटा फ्रेम के लिए मैं सारांश() के लिए कोड कैसे पढ़ सकता हूं?
- 18. मैं ज़िप फ़ाइल से फ़ाइलों को जावा के साथ मेमोरी में कैसे पढ़ सकता हूं?
- 19. मैं proc फ़ाइल से बड़े डेटा को कैसे पढ़ सकता हूं?
- 20. मैं आरआरडीटोल के साथ डेटा कैसे अपडेट कर सकता हूं?
- 21. मैं PHP के साथ एचटीएमएल कैसे आयात कर सकता हूं?
- 22. क्या मैं जावास्क्रिप्ट से कैप्चा डेटा को सुरक्षित तरीके से पढ़ सकता हूं?
- 23. nHibernate का उपयोग करके, मैं असामान्य कैसे पढ़ सकता हूं?
- 24. मैं सामग्री-स्वभाव हेडर की सामग्री कैसे पढ़ सकता हूं?
- 25. मैं मौजूदा डेटा से डेटा के साथ एक सोलर कोर कैसे बना सकता हूं?
- 26. PHP/apache के साथ कच्चे HTTP अनुरोध डेटा को मैं कैसे एक्सेस कर सकता हूं?
- 27. मैं वीईएसए/वीडियोबीओएस "मोड रिमूवल टेबल" कैसे पढ़ सकता हूं?
- 28. मैं एक HttpServletReponses आउटपुट स्ट्रीम कैसे पढ़ सकता हूं?
- 29. मैं लागू सीएसएस-काउंटर वैल्यू कैसे पढ़ सकता हूं?
- 30. मैं प्रति-पिक्सेल आधार पर जेपीईजी डेटा कैसे पढ़ और लिख सकता हूं?
यह समझाएगा कि PHP में कोई XMP विशिष्ट फ़ंक्शन क्यों नहीं है। – Liam