Antworten auf deine Fragen:
Neues Thema erstellen

[php]iptc Daten in Grafik schreiben

sokie

Mod | Web

leider habe ich nur Informationen gefunden wie man iptc Daten per php aus Grafikdateien (insbesondere jpg) lesen kann. Kann man per php auch solche Daten in Bilder schreiben / editieren? wenn ja,wie?
 

saila

Moderatorle

AW:
PHP:
iptc Daten in Grafik schreiben[/b]

Hi,

ich vermute mal, dass du dich zu exif eingelesen hast. Das auslesen ist somit geklärt. Die Fragestellung, wie man nun bei der Generierung von thumbnails oder Images über php wiederum Bilddaten in das zu generierende Bild platzieren kann, hat sich mir noch nicht gestellt sofern das die Fragestellung betrifft.

Alternativ würde ich versuchen, einen image-header zu erzeugen, in welchem dann wiederum die Bilddaten gepseichert werden. Dabei würde ich auf die Vorlage der exif-Funktion "exif_read_data" und derer Parameter zurückgreifen.

Ob das allerdings mit dem header über php funktoniert wäre lediglich mit der image-Funktion "iptcembed" möglich und zu testen.
 

sokie

Mod | Web

AW:
PHP:
iptc Daten in Grafik schreiben[/b]

Hallo Saila, dankefür die Antwort und die darin enthaltenen Anstösse. aus den Beispielen und Kommentaren zu iptcembed hab ich einiges gefunden, was mich eine Weile beschäftigen wird, und sicher auch zu Ergebnissen führt :-)
EXIF ist für mein Projekt nicht interessant, weil php nur funktionen zum auswerten der Daten bereitstellt, nicht aber zum schreiben und bearbeiten.
Vielleicht hat ja jemand Erfahrungen mit dem Schreiben von iptc Einträgen.
 

saila

Moderatorle

AW:
PHP:
iptc Daten in Grafik schreiben[/b]

Hi,

exif ist auch lediglich zur Info gedacht, wie z.B. die Daten wiederum über php anzusprechen sind und wie diese in dem image-file eingebunden wurden.

Da ich derzeit wenig Zeit habe und auch ein Plugin für jQuery schreibe, bin ich - so gerne ich es tun würde - leider nicht in der Lage, zu dem Thema iptc zu testen. Allerdings würde mich das Ergebnis interessieren. Insbesondere das handling mit [B]iptcembed[/B]
 
D

derkk_koenig

Guest

AW:
PHP:
iptc Daten in Grafik schreiben[/b]

wir haben gerade eine ähnliche Problem gehabt. iptcembeded hat nur bedingt geholfen, besonders wenn's ums schreiben von Jpgs geht, die in Photoshop bearbeitet wurden... Stichwort XMB.
Bislang haben wir und damit jedes Bild zerschossen, weil es da auch keine 'echte' Schnittstelle wie für IPTC/ Exif gibt, sondern man den XML-Header auslesen muss.

Insofern würde mich das Ergebnis auch interessieren bzw. vielleicht könnte man mal zusammen daran arbeiten.

Hintergrund: Wir bauen mehr oder minder als (noch) internes Projekt an einer Bilderdatenbank, die Fotografen entgegen den gängigen Portalen ermöglicht ihre eigenen Preise zu bestimmen, evtl. als SaaS oder für den die eigene Website.

VG

der kk_koenig
 

sokie

Mod | Web

AW:
PHP:
iptc Daten in Grafik schreiben[/b]

hallo derkk_koenig,
über die Probleme mit der Vorbelegung durch Photoshop habe ich inzwischen auch das eine oder andere gelesen:-(
ich bin an der Sache der iptc interessiert um eine galeriesoftware für Webseiten zu schreiben, die auf diesem Weg ohne Datenbank auskämen. (aslo müssten die Textinhalte zum Bild im Bild gespeichert werden.
 

saila

Moderatorle

AW:
PHP:
iptc Daten in Grafik schreiben[/b]

Hi,

am Donnerstag der kommenden Woche werde ich mal das ganze testen, da ich heute (besser gesagt gerade eben) mein Plugin für jQuery fertiggestellt habe :).

Nach dem bislang hier mitgeteiltem stellt sich mir die Frage: ist beabsichtigt, ein vorhandendes Bild im Header zu verändern oder soll auch gleichzeitig ein neues Bild erzeugt werden?

Zur Thematik - [B]iptcembed [/B]- ist hier die Frage offen, wodurch das Bild zerschossen wird bzw. was das Ergebnis des neuen Bildes ist. Z.B. schwarze Fläche oder wie sieht das zerschossene Ergebnis aus?
 
D

derkk_koenig

Guest

AW:
PHP:
iptc Daten in Grafik schreiben[/b]

[quote="saila, post: 1449784"]Hi,
Zur Thematik - [B]iptcembed [/B]- ist hier die Frage offen, wodurch das Bild zerschossen wird bzw. was das Ergebnis des neuen Bildes ist. Z.B. schwarze Fläche oder wie sieht das zerschossene Ergebnis aus?[/quote]

Da fragste mich was.. hat mein Mitarbeiter gemacht.

hier mal unser versuch, in die bilder zu schreiben, was geht, ohne was kaputt zu machen:

das ist zumindest ein Teil davon. die ganze Klasse hat 900 zeilen, was imho zu viel wäre hier zu posten...

Vll bekommen wir das ja gemeinsam hin

VG

der kk_koenig

[PHP]
public function checkForMissingData($filename)
    {
        ob_start();
        readfile($filename);
        $source = ob_get_contents();
        ob_end_clean();
          
        $xmpdata_start = strpos($source,"<x:xmpmeta");
        $xmpdata_end = strpos($source,"</x:xmpmeta>");
        $xmplenght = $xmpdata_end-$xmpdata_start;
        $xmpdata = substr($source,$xmpdata_start,$xmplenght+12);
        
        $domClass = new DOMDocument();
        if(false === @$domClass->loadXML($xmpdata))return;
        $ContactInfosNodeList = $domClass->getElementsByTagNameNS('http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/','*');
        
        $missingData = array();
        
        foreach($ContactInfosNodeList as $elem)
        {
            if($elem->nodeName == 'Iptc4xmpCore:CreatorContactInfo')
            {
                $i = 0;
                while($elem->attributes->item($i))
                {
                    $missingData[$elem->attributes->item($i)->name] = $elem->attributes->item($i)->value;
                    $i++;
                }
            }
            if($elem->nodeName == 'Iptc4xmpCore:SubjectCode')
            {
                $missingData['subjectCode'] = $elem->textContent;
            }
        }
            
        $ContactInfosNodeList = $domClass->getElementsByTagNameNS('http://ns.adobe.com/xap/1.0/rights/','*');
        foreach($ContactInfosNodeList as $elem)
        {
            if($elem->nodeName == 'xapRights:UsageTerms')
            {
                $missingData['usageterms'] = $elem->textContent;
            }
        }
        
        $ContactInfosNodeList = $domClass->getElementsByTagNameNS('http://www.w3.org/1999/02/22-rdf-syntax-ns#','*');
        foreach($ContactInfosNodeList as $elem)
        {
            if($elem->nodeName == 'rdf:Description')
            {
                $i = 0;
                while($elem->attributes->item($i))
                {
                    if( $elem->attributes->item($i)->name == 'IntellectualGenre' || 
                        $elem->attributes->item($i)->name == 'Location' || 
                        $elem->attributes->item($i)->name == 'SceneType' || 
                        $elem->attributes->item($i)->name == 'FileSource' ||
                        $elem->attributes->item($i)->name == 'LightSource' ||
                        $elem->attributes->item($i)->name == 'Contrast')
                    {
                        $missingData[$elem->attributes->item($i)->name] = $elem->attributes->item($i)->value;
                    }
                    $i++;
                }
            }
        }
        
        return $missingData;
        
    }
    
    public function updateExifData($newExifData)
    {
        $imagePath = $this->image_path;
        /**
         * First we make a workingcopy of the image
         */
        $workingCopyPath = $imagePath.'.wc.bak';
        if(false === copy($imagePath,$workingCopyPath))throw new Exception('Cannot copy image');
        
        if(false === getimagesize($workingCopyPath))throw new Exception('The workingcopy is damaged.');
        
        /**
         * Try to update all IPTC data by hand
         */
        //$this->updateMissingData($workingCopyPath,$newExifData);
        
        /**
         * Versucht und gescheitert
         * 
         * IPTCParse benutzen, hinterher jedoch prüfen, ob zusätzlich ein AMP Metablock existiert.
         * Wenn ja dort mit REGEX arbeiten um werte zu ermitteln ggf. zu erstezen
         * Wenn nicht evtl. ein default XMP Block einsetzten
         * --> Obwohl es textuell gut ausschaut ist das bild nicht mehr darstellbar ( Kodierungsproblem ?? )
         * 
         * PHP4 functionen benutzen 
         * --> Zu altes Script ? ; Andere/Neue XMP/IPTC Version ?
         * 
         * Über iptcparse() weitere Parameter ( bsw. 118 für Contact infos ) setzten
         * --> ignoriert unbekannte Tags ...
         */
        
        
        
        
        
        /**
         * now "clean" the wc
         */
        $wcString = iptcembed("",$workingCopyPath);
        
        /**
         * Insert the cleaned string
         */
        $fh = fopen($workingCopyPath,'wb');
        fwrite($fh,$wcString);
        fclose($fh);
        
        if(false === getimagesize($workingCopyPath))throw new Exception('Deleting the IPTC/EXIF Data just destroyed the workingcopy.');
        
        /**
         * Build up the new Exif/IPTC String
         */
        $ExifStr = "";
        $ExifStr .= $this->iptc_make_tag(2,'080', $newExifData->getContact_creator());
        $ExifStr .= $this->iptc_make_tag(2,'085', $newExifData->getContact_creator_job());
        $ExifStr .= $this->iptc_make_tag(2,'090', $newExifData->getPicture_create_town());
        $ExifStr .= $this->iptc_make_tag(2,'095', $newExifData->getPicture_create_state());
        $ExifStr .= $this->iptc_make_tag(2,'101', $newExifData->getPicture_create_country());
        $ExifStr .= $this->iptc_make_tag(2,'105', $newExifData->getContent_headline());
        $ExifStr .= $this->iptc_make_tag(2,'120', $newExifData->getContent_desc());
        $ExifStr .= $this->iptc_make_tag(2,'025', $newExifData->getContent_tags());
        
        $ExifStr .= $this->iptc_make_tag(2,'122', $newExifData->getContent_text_creator());
        $ExifStr .= $this->iptc_make_tag(2,'005', $newExifData->getStatus_title());
        $ExifStr .= $this->iptc_make_tag(2,'103', $newExifData->getStatus_job());
        $ExifStr .= $this->iptc_make_tag(2,'040', $newExifData->getStatus_statement());
        $ExifStr .= $this->iptc_make_tag(2,'110', $newExifData->getStatus_provider());
        $ExifStr .= $this->iptc_make_tag(2,'115', $newExifData->getStatus_source());
        $ExifStr .= $this->iptc_make_tag(2,'116', $newExifData->getStatus_copyright());
        
        /**
         * Insert the new Version into our wc
         */
        $finalStr = iptcembed($ExifStr,$workingCopyPath);
        $fh = fopen($workingCopyPath,'wb');
        fwrite($fh,$finalStr);
        fclose($fh);
        
        if(false === getimagesize($workingCopyPath))throw new Exception('Insert new ExifData destroyed our workingcopy.');
        
        /**
         * Overwrite old image with wc
         * Then delete wc
         */
        if(false === copy($workingCopyPath,$imagePath))throw new Exception('Cannot overwrite old image with the workingcopy.');
        unlink($workingCopyPath);
        
        return true;
    }
    
    public function iptc_make_tag($rec, $data, $value)
    {
        $length = strlen($value);
        $retval = chr(0x1C) . chr($rec) . chr($data);
    
        if($length < 0x8000)
        {
            $retval .= chr($length >> 8) .  chr($length & 0xFF);
        }
        else
        {
            $retval .= chr(0x80) . 
                       chr(0x04) . 
                       chr(($length >> 24) & 0xFF) . 
                       chr(($length >> 16) & 0xFF) . 
                       chr(($length >> 8) & 0xFF) . 
                       chr($length & 0xFF);
        }
    
        return $retval . $value;
    }

/**
     * Take the working copy and __simply__ change all its header data
     *
     * @param filename                   $filename     Filepath to wc
     * @param Application_Model_ExifData $newExifdata
     */
    public function updateMissingData($filename,$newExifdata)
    {
        // get the real image without any header
        if(false === ($realImg = $this->get_jpeg_image_data($filename)))throw new Exception('Unable to get compressed image data');
        
        // get existing header
        if(false === ($existsingHeader = $this->get_jpeg_header_data($filename)))$existsingHeader = array();
        
        //build up xmparray
        $xmparray = array(
            array(
                'tag' => 'exif:Flash',
                'attributes' => array(
                    'exif:Fired' => 'True',
                    'exif:Return' => '0'
                )
            ),
            array()
        );
        
        // Add the XMP packet header
        // The sequence 0xEFBBBF is the UTF-8 encoded version of the Unicode ìzero
        // width non-breaking space characterî (U+FEFF), which is used for detecting
        // whether UTF-16 or UTF-8 is being used.
        $XMP_text = "<?xpacket begin='\xef\xbb\xbf' id='W5M0MpCehiHzreSzNTczkc9d'?>\n";

        // Photoshop Seems to add this, but there doesn't appear to be
        // any information on what it means
        // TODO : XMP, Find out what the adobe-xap-filters tag means
        $XMP_text .= "<?adobe-xap-filters esc=\"CR\"?>\n";

        // Add the XML text
        $XMP_text .= $this->write_xml_array_to_text( $xmparray, 0 );


        // The XMP standard recommends adding 2-4k of white space at the
        // end for in place editing, so we will add it to the XML now
        $XMP_text .= str_repeat("                                                                                                   \n", 30);

        // Add the XMP packet trailer
        $XMP_text .= "<?xpacket end='w'?>";
        
        $this->put_XMP_text($existsingHeader,$XMP_text);
        
        die(print_r($existsingHeader,true));
        
        $this->put_jpeg_header_data($realImg,$filename,$existsingHeader);
    }
    
    /**
     * 
     *
     */
    public function write_xml_array_to_text( $xmlarray, $indentlevel )
    {
        // Create a string to receive the XML
        $output_xml_text = "";


        // Cycle through each xml element at this level
        foreach ($xmlarray as $xml_elem)
        {

                // Add the indent, then the cleaned tag name to the output
                $output_xml_text .= str_repeat ( " ", $indentlevel ) . "<" . xml_UTF8_clean( $xml_elem['tag'] );

                // Check if there are any attributes for this tag
                if (array_key_exists('attributes',$xml_elem))
                {
                        // There are attributes
                        // Cycle through each attribute for this tag
                        foreach ($xml_elem['attributes'] as  $xml_attr_name => $xml_attr_val)
                        {
                                // Add the cleaned attribute name, and cleaned attribute value to the output
                                $output_xml_text .= " ". xml_UTF8_clean( $xml_attr_name ) ." ='" .  xml_UTF8_clean( $xml_attr_val ) ."'";
                        }
                }

                // Add the 'greater-than' to close this tag to the output
                $output_xml_text .= ">";

                // Check if this element has any text inside it.
                if (array_key_exists('value',$xml_elem) )
                {
                        // There is text for this element - clean it and add it to the output
                        $output_xml_text .=  xml_UTF8_clean( $xml_elem['value'] );
                }

                // Check if there are any lower levels contained by this element
                if (array_key_exists('children',$xml_elem) )
                {
                        // There are sub-elements for this element

                        // Add a newline to the output, so the sub-elements start on a fresh line
                        $output_xml_text .= "\n";

                        // Recursively call this function to output the sub-elements, and add the result to the output
                        $output_xml_text .= $this->write_xml_array_to_text( $xml_elem['children'], $indentlevel + 1 );

                        // Add an indent to the output for the closing tag, since we are on a new line due to the sub-elements
                        $output_xml_text .= str_repeat ( " ", $indentlevel );
                }

                // Add the cleaned closing tag to the output
                $output_xml_text .= "</" .xml_UTF8_clean($xml_elem['tag']) . ">\n";
        }

        // Return the XML text
        return $output_xml_text;
    }
 

netbandit

Aktives Mitglied

AW:
PHP:
iptc Daten in Grafik schreiben[/b]

Schon mal versucht mit einer komplett neuen Grafik zu arbeiten (anstelle einer Kopie) und dann die Daten neu zu schreiben? Auf PHP.net ist ein Bespiel dafür: 
 
Oder bin ich da eher am Thema vorbei?
 
D

derkk_koenig

Guest

AW:
PHP:
iptc Daten in Grafik schreiben[/b]

IPTC ist weniger das Problem... sondern eher die XMP-Daten...

VG

der kk_koenig

EDIT: vll. sind die Kommentare etwas verwirrend.. intern behandeln wir das als ' eine Grütze' mit guten und schlechten Teilen
 

saila

Moderatorle

AW:
PHP:
iptc Daten in Grafik schreiben[/b]

Hi,

sorry, aber ich find keine Zeit um zu testen. Allerdings würde ich auf den von netbandit verweisenden Link mich in erster Linize zu diesem Beitrag einschiessen und diese als erstes testen. Zumal in diesem Beitrag einige weitergehende Infos enthalten sind: 

Zitat:
Example to read IPTC text from an image,  changing the text an write to a new file using the functions iptcparse  and iptcembed.
 
Also a list of the most common IPTC fields.
[php]
<?php
// original file name
$image_name_old = "test.jpg";

// New file name
$image_name_new = "test2.jpg";

// Reads the IPTC text in to the array  '$iptc'
// The number after the '#' is the IPTC field
// Ex: $iptc["2#120"][0] is Caption
// $iptc["2#055"][0]; is Creation date
$size = GetImageSize ("$image_name_old",&$info);
$iptc_old = iptcparse ($info["APP13"]);

// Adding or replacing IPTC text
   // This ex. replace the original category or create it if it dos not  exist
   $iptc_old["2#015"][0] = "Sport";
   // .. and adding more text to the  original caption
   $iptc_old["2#120"][0] .= " More caption text";

   // Making the new IPTC string
   foreach (array_keys($iptc_old) as $s){
      // Finds the IPTC numbers
      $tag = str_replace("2#", "", $s);
      // Creating the string
      $iptc_new .= iptc_maketag(2, $tag, $iptc_old[$s][0]);
   }

// The original file and the new IPTC Text  into $content
// Mode 0 - puts the image file into $content
// Mode 1 - puts the image file into $content and directly to the web  client
// Mode 2 - puts the image file to web client
$mode = 0;
$content = iptcembed($iptc_new, $image_name_old, $mode);

// writes the new file
$fp = fopen($image_name_new, "w");
fwrite($fp, $content);
fclose($fp);

// Function to format the new IPTC text,  (thanks to Thies C. Arntzen)
function iptc_maketag($rec,$dat,$val){
         $len =  strlen($val);
         if ($len < 0x8000)
                  return chr(0x1c).chr($rec).chr($dat).
                  chr($len >> 8).
                  chr($len & 0xff).
                  $val;
         else
                  return chr(0x1c).chr($rec).chr($dat).
                  chr(0x80).chr(0x04).
                  chr(($len >> 24) & 0xff).
                  chr(($len >> 16) & 0xff).
                  chr(($len >> 8 ) & 0xff).
                  chr(($len ) & 0xff).
                  $val;
}
?>
--- The most common IPTC Fileds
005 - Object Name
007 - Edit Status
010 - Priority
015 - Category
020 - Supplemental Category
022 - Fixture Identifier
025 - Keywords
030 - Release Date
035 - Release Time
040 - Special Instructions
045 - Reference Service
047 - Reference Date
050 - Reference Number
055 - Created Date
060 - Created Time
065 - Originating Program
070 - Program Version
075 - Object Cycle
080 - Byline
085 - Byline Title
090 - City
095 - Province State
100 - Country Code
101 - Country
103 - Original ************ Reference
105 - Headline
110 - Credit
115 - Source
116 - Copyright String
120 - Caption
121 - Local Caption</span>

----------------
Selbst wenn diese Vorgehensweise nicht vollständig zum Ergebnis führen würde, so ist sie dennoch aus- oder erweiterbar.
 
Bilder bitte hier hochladen und danach über das Bild-Icon (Direktlink vorher kopieren) platzieren.
Antworten auf deine Fragen:
Neues Thema erstellen

Willkommen auf PSD-Tutorials.de

In unseren Foren vernetzt du dich mit anderen Personen, um dich rund um die Themen Fotografie, Grafik, Gestaltung, Bildbearbeitung und 3D auszutauschen. Außerdem schalten wir für dich regelmäßig kostenlose Inhalte frei. Liebe Grüße senden dir die PSD-Gründer Stefan und Matthias Petri aus Waren an der Müritz. Hier erfährst du mehr über uns.

Stefan und Matthias Petri von PSD-Tutorials.de

Nächster neuer Gratisinhalt

03
Stunden
:
:
25
Minuten
:
:
19
Sekunden

Flatrate für Tutorials, Assets, Vorlagen

Zurzeit aktive Besucher

Statistik des Forums

Themen
118.565
Beiträge
1.538.067
Mitglieder
67.488
Neuestes Mitglied
Andrew56524
Oben