{"id":274,"date":"2005-01-30T13:03:27","date_gmt":"2005-01-30T12:03:27","guid":{"rendered":"http:\/\/wp.devco.net\/?p=274"},"modified":"2014-10-08T09:51:32","modified_gmt":"2014-10-08T08:51:32","slug":"netmovabletype_and_imageexiftool","status":"publish","type":"post","link":"https:\/\/www.devco.net\/archives\/2005\/01\/30\/netmovabletype_and_imageexiftool.php","title":{"rendered":"Net::MovableType and Image::ExifTool"},"content":{"rendered":"

Posts for my photoblog<\/a> are structured in a specific way. I put the image name in the entry body and the text in the extended entry. As long as I stick to that format my templates will automatically put in the right thumbnails, full size images etc.<\/p>\n

While this is pretty simple to keep in mind and I have been doing it manually I wanted to automate things a bit. I also wanted to include some EXIF info for each image which Movable Type could not do on its own.<\/p>\n

The solution was to write a simple blogging client in perl, read on for some details.<\/p>\n

First off, lets cover the EXIF extraction, I found a excellent module in the FreeBSD ports system called Image::ExifTool<\/a>. From its description:<\/p>\n

\nExifTool provides an extensible set of perl modules to read and write
\nmeta information in image files. It reads EXIF, GPS, IPTC, XMP,
\nGeoTIFF, ICC Profile and Photoshop IRB meta information from JPEG,
\nTIFF, GIF, THM, CRW (Canon RAW), CR2 (Canon 1D Mk II RAW), MRW (Minolta
\nRAW), NEF (Nikon Electronic image Format), PEF (Pentax RAW), ORF
\n(Olympus RAW Format) and DNG (Digital Negative) images, as well as the
\nmaker notes of many digital cameras by various manufacturers including
\nCanon, Casio, FujiFilm, Minolta\/Konica-Minolta, Nikon, Olympus\/Epson,
\nPanasonic\/Leica, Pentax\/Asahi, Sanyo and Sigma\/Foveon. It writes EXIF,
\nGPS, IPTC, XMP and MakerNotes information to JPEG, TIFF, GIF, THM, CR2,
\nNEF, PEF and DNG files.\n<\/p><\/blockquote>\n

Using it is trivial, and you can read all the details at its CPAN Page<\/a>. For me it was as simple as this:<\/p>\n

\n
my $exifTool = new Image::ExifTool;
$exifInfo = $exifTool->ImageInfo(\"$photodir\/$image\");

$tagDescription = $exifTool->GetDescription($tag);

%tagValue = $exifTool->GetValue($tag);

<\/p><\/pre>\n<\/blockquote>\n

Really simple, to see for yourself what information this will find
\nin a image you can run the included ‘exiftool’ script, here is some
\nsample output:<\/p>\n

\n—- ExifTool —-
\nExifTool Version Number : 3.72
\n—- File —-
\nFile Name : 30012005.jpg
\nFile Size : 67KB
\nFile Type : JPG
\nImage Width : 366
\nImage Height : 550
\n—- EXIF —-
\nSoftware : Adobe Photoshop CS Windows
\nFlash : No Flash
\nExif Image Width : 366
\nExif Image Length : 550
\nCompression : JPEG (old-style)
\nThumbnail Offset : 586
\nThumbnail Length : 6137
\n—- IPTC —-
\nApplication Record Version : 2
\n—- Photoshop —-
\nPhotoshop Thumbnail : (Binary data 6137 bytes, use -b option to extract)
\n—- XMP —-
\nVersion : 2.2
\nRaw File Name : DSC_4995.NEF
\nWhite Balance : As Shot
\nExposure : +0.85
\nShadows : 5
\nBrightness : 50
\nContrast : +25
\nSaturation : 0
\nSharpness : 25
\nLuminance Smoothing : 0
\nColor Noise Reduction : 25
\nChromatic Aberration R : 0
\nChromatic Aberration B : 0
\nVignette Amount : 0
\nShadow Tint : 0
\nRed Hue : 0
\nRed Saturation : 0
\nGreen Hue : 0
\nGreen Saturation : 0
\nBlue Hue : 0
\nBlue Saturation : 0
\nTv(Shutter Speed) : 1\/500
\nShutter Speed Value : 1\/500
\nAv(Aperture Value) : 5.6
\nAperture Value : 5.6
\nExposure Program : Program AE
\nShooting Date\/Time : 2005:01:23 13:58:27
\nExposure Compensation : -0.33
\nMax Aperture Value : 5.7
\nMetering Mode : Multi-segment
\nFocal Length : 125.0mm
\nFocal Length In 35mm Format : 187
\nColor Space : Unknown (4294967295)
\nISO Speed : 200
\nFlash Fired : False
\nFlash Return : No return detection
\nFlash Mode : Unknown (0)
\nFlash Function : False
\nFlash Red Eye Mode : False
\nLens : 18.0-125.0 mm f\/3.3-5.6
\nMake : NIKON CORPORATION
\nCamera Model Name : NIKON D70
\nOrientation : Horizontal (normal)
\nX Resolution : 300
\nY Resolution : 300
\nResolution Unit : inches
\nCreator Tool : Adobe Photoshop CS Windows
\nDate\/Time Of Last Modification : 2005:01:23 17:21:22
\nDate\/Time Of Digitization : 2005:01:23 17:21:22
\nMetadata Date : 2005:01:23 17:21:22
\nDerived From Instance ID : uuid:121a03ec-6d63-11d9-bfa3-cf79758759c4
\nDerived From Document ID : adobe:docid:photoshop:121a03eb-6d63-11d9-bfa3-cf79758759c4
\nDocument ID : adobe:docid:photoshop:121a03ef-6d63-11d9-bfa3-cf79758759c4
\nFormat : image\/jpeg
\n—- Composite —-
\nAv(Aperture Value) : 5.6
\nImage Size : 366×550
\nScale Factor To 35mm Equivalent : 1.5
\nTv(Shutter Speed) : 1\/500
\nThumbnail Image : (Binary data 6137 bytes, use -b option to extract)
\nFocal Length : 125.0mm (35mm equivalent: 187.0mm)\n<\/p><\/blockquote>\n

This is very impressive, you can see multiple sets of data, example
\nis the Exposure, I shot it at -0.33 in the camera then bumped it to
\n+0.85 in Photoshop CS RAW Plugin.<\/p>\n

Now that I have a good way to extract meta data from my images the next step was to do the blog posting, this was trivial using Net::MovableType<\/a>, below is a quick code snippet, read all about it at CPAN<\/a><\/p>\n

\nuse Net::MovableType;
\n
my $mt = new Net::MovableType(‘http:\/\/your.com\/rsd.xml’);
\n$mt->username(‘user’);<\/p>\n

$mt->password(‘secret’);<\/p>\n

$entry = {
\n   title => “Hello World from Net::MovableType”,
\n   description => “Look ma, no hands!”
\n};<\/p>\n

$postID = $mt->newPost($entry);
\n$mt->publishPost($postID);\n<\/p>\n<\/blockquote>\n

Very simple, it has many other functions, you can read, edit,
\ncategorise etc, all the stuff you can do from the standard Movable Type
\nAPI.<\/p>\n


<\/p>\n","protected":false},"excerpt":{"rendered":"

Posts for my photoblog are structured in a specific way. I put the image name in the entry body and the text in the extended entry. As long as I stick to that format my templates will automatically put in the right thumbnails, full size images etc. While this is pretty simple to keep in […]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_et_pb_use_builder":"","_et_pb_old_content":"","footnotes":""},"categories":[7],"tags":[121,46],"_links":{"self":[{"href":"https:\/\/www.devco.net\/wp-json\/wp\/v2\/posts\/274"}],"collection":[{"href":"https:\/\/www.devco.net\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devco.net\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devco.net\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devco.net\/wp-json\/wp\/v2\/comments?post=274"}],"version-history":[{"count":3,"href":"https:\/\/www.devco.net\/wp-json\/wp\/v2\/posts\/274\/revisions"}],"predecessor-version":[{"id":3057,"href":"https:\/\/www.devco.net\/wp-json\/wp\/v2\/posts\/274\/revisions\/3057"}],"wp:attachment":[{"href":"https:\/\/www.devco.net\/wp-json\/wp\/v2\/media?parent=274"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devco.net\/wp-json\/wp\/v2\/categories?post=274"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devco.net\/wp-json\/wp\/v2\/tags?post=274"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}