use strict; use warnings; use Image::MetaData::JPEG; use Image::MetaData::JPEG::Record; use Image::MetaData::JPEG::data::Tables qw(:JPEGgrammar :Endianness :RecordTypes); #read the image filname from the command line arguments my $image = new Image::MetaData::JPEG($ARGV[0]); # This would be the correct procedure for adding records at low level # if the APP2 update routine existed at all (but it isn't implemented) # 1) create an empty APP2 segment # my $segref = # new Image::MetaData::JPEG::Segment('APP2', undef, 'NOPARSE'); # 2) store a record with a given key and value # my $head = "MPF0"; # $segref->store_record('MP_HEADER', $ASCII, \$head); # 3) IMPORTANT: update the binary block from the in memory # representation (this was the step you were missing) # $segref->update(); # But APP2 can "currently" only be parsed if it contains Flashpix # conversion information ("FPXR") or ICC profiles data. And there is # no update routine at all. So, either you extend the package or # create the entire binary block by hand in a local variable: # you skip parsing and just create the segment. my $buffer = "MPF0\0"; my $segref = new Image::MetaData::JPEG::Segment('APP2', \$buffer, 'NOPARSE'); # then insert it into the image $image->insert_segments($segref); # the segment is there, albeit without description, since unparsed foreach my $s ($image->get_segments('APP')) { print $s->get_description(); } # you can save to file nonetheless, unparsable segments aren't dropped my $new_file_name = 'tmp1.jpg'; $image->save($new_file_name); print "---------------------------------\n"; # now open the new file and check that APP2 is there (I avoid trying # to parse it, since parsing would fail with "Invalid APP2 segment" # in this case) my $new_image = new Image::MetaData::JPEG($new_file_name, 'APP[^2]'); foreach my $s ($new_image->get_segments('APP')) { print $s->get_description(); } print "---------------------------------\n"; # have a look at what's really inside your file: the APP2 segment # should be in the very first lines, unless your APP1 is huge. use Data::HexDump; my $hexdumper = new Data::HexDump; $hexdumper->file($new_file_name); $hexdumper->block_size(1024); print while $_ = $hexdumper->dump;