Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

jima (1016)

jima
  (email not shown publicly)
http://www.empty-handed.com/

Born 1968. Not dead yet.

Journal of jima (1016)

Wednesday September 06, 2006
10:58 AM

Removing EXIF data from JPEG images using PerlMagick

[ #30908 ]

One issue that came up when we were testing the original version of this software was that metadata was being kept in images that were created by the system. Small "slices" of the original images uploaded by players were passed along to subsequent players, for them to use in their own creations, and any existing EXIF thumbnail images in the original image file were accidentally also being passed along.

After some futzing around with ImageMagick http://www.imagemagick.org/ I eventually settled on using the jpegtran tools that come installed on just about every flavor of Linux. But I never gave up on a possible PerlMagick solution, and now I've finally stumbled upon the correct combination of incantations that allow you to create an image with no EXIF data. Since the documentation for ImageMagick is quite sparse, I thought I would record my discovery here.

I suspected that copying an image from one Image::Magick object to another would probably not copy the EXIF data, and it took me a while to stumble on the Composite() method which in fact works exactly as I suspected it would. Here's my code:

use Image::Magick;

my($i) = Image::Magick->new();
my($j) = Image::Magick->new();

$i->Read('image-with-exif.jpg');
$j->Set('size', $i->Get('width').'x'.$i->Get('height'));
$j->Read('NULL:white');

$resp = $j->Composite( image => $i, compose => Copy );  # you can check $resp for errors

$j->Write('image-without-exif.jpg');

A couple of things that might not be obvious to the ImageMagick novice:

  • The $j->Read() function call is needed to create an image in the $j variable. Apparently you need to have some image in your destination variable to copy stuff onto.
  • The NULL:white string is what's known in ImageMagick as a pseudo-image format. Other formats, useful for creating gradients, steganographic images, plasma backgrounds, etc. can be found in this page in the ImageMagick documentation: http://www.imagemagick.org/script/formats.php#pseudo

Some investigation with the resulting images using the Image::ExifTool module indicates that there is no resulting EXIF data in the new JPEG image. Mission accomplished!

Monday September 04, 2006
12:08 PM

Notes on posting via Perl to Blogger

[ #30881 ]

One of the features that the new code will have is the ability to automatically create a new posting for a specified blog, in order to publicly display the finished collaborative art. Some blogs, such as Movable Type, have pretty straightforward API documentation: http://www.movabletype.org/mt-static/docs/mtmanual_programmatic.html Others, like Blogger, take a bit of trial and error to get working. Here's the code that I just got working for my module that posts to an existing Blogger weblog (you'll have to put in the user name, password and numeric blog ID string into the code yourself, of course):

my($ua) = LWP::UserAgent->new;

my($entry) = <<FOO;
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<entry xmlns="http://purl.org/atom/ns#">
  <title mode="escaped" type="text/plain">atom test</title>
  <issued>2006-09-04T00:00:00Z</issued>
  <generator url="http://anexquisitecorpse.net">An Exquisite Corpse backend code</generator>
  <content type="application/xhtml+xml">
    <div xmlns="http://www.w3.org/1999/xhtml">Testing the Atom API</div>
  </content>
</entry>
    FOO

my($h) = HTTP::Headers->new;
$h->header('Content-type', 'application/xml');
$h->header('Host', 'www.blogger.com');
$h->authorization_basic('username','password');  # << replace with your own details, obv

my($req) = HTTP::Request->new(

        POST => 'https://www.blogger.com/atom/12345678',  # << replace with your own blogger ID, found in the header of your blogspot homepage
        $h,
        $entry
);

my($resp) = $ua->request($req);

print $resp->as_string;

You should get back a big meaty chunk of XML that will include, among other things, the formatted entry returned from the blog and a link tag that contains the URL for the new entry. Here's what that looks like:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<entry xmlns="http://purl.org/atom/ns#">
    <link href="https://www.blogger.com/atom/12345678/1234567890" rel="service.edit" title="atom test" type="application/atom+xml"/>
    <author>
        <name>your name here</name>
    </author>
    <issued>2006-09-03T17:00:00-07:00</issued>
    <modified>2006-09-04T16:12:56Z</modified>
    <created>2006-09-04T16:12:56Z</created>
    <link href="http://whatever.blogspot.com/whatever" rel="alternate" title="atom test" type="text/html"/>
    <id>tag:blogger.com,1999:blog-12345678.post-1234567890</id>
    <title mode="escaped" type="text/html">atom test</title>
    <content type="application/xhtml+xml" xml:base="http://whatever.blogspot.com" xml:space="preserve">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <div xmlns="http://www.w3.org/1999/xhtml">Testing the Atom API</div>
        </div>
    </content>
    <draft xmlns="http://purl.org/atom-blog/ns#">false</draft>
</entry>

Still to be figured out: what standard-issue XML and HTTP modules I can use to parse these requests and responses, and how much of the XML I might need to hard-code into the modules.

And while we're on the subject of Blogger, can I just say that it's a big pain having to code for a standard that's currently in production (the Atom API), while at the same time being told to plan for an upgraded publishing spec (the GData API: http://code.google.com/apis/gdata/blogger.html) that I can't even test yet because it's still in beta. Well, maybe someday I'll get to test it, but for now I'll just stick with the Atom API, because that's what I've got to work with right now.

Thursday August 31, 2006
09:47 AM

Notes on CAMS

[ #30825 ]

Hello. I've been working on a large open source Perl project for a few months now, and I've been wanting a place to post my thoughts and code ideas, just to get them out of my head and onto paper.

The project is growing out of my work on the site An Exquisite Corpse http://www.anexquisitecorpse.net/, which is a Website devoted to playing the Exquisite Corpse game online (if you don't know what an Exquisite Corpse is, look it up in Wikipedia: http://en.wikipedia.org/wiki/Exquisite_corpse). The current system was cobbled together as quickly as possible, which of course means it's not that great or easy to use. I'm working on the next version of the code and trying to make it a lot more general-purpose (i.e., to provide the capability of implementing other online collaborative art games, not just Exquisite Corpse) and more user-friendly, with the ultimate goal of making it open source and available for other people to use and extend.

The new system, which I am currently referring to as the Collaborative Art Management System, or CAMS, will be a user-management system with a series of Perl modules that implement a series of collaboartive art "games". The first one I'm implementing is Exquisite Corpse, but ultimately I hope to have a number of games written. Other possible games include Photoshop Tennis http://www.coudal.com/tennis.php, Corpse Tennis http://www.deadhorse.org/corpsetennis/, and a text version of Exquisite Corpse.

I'm still in the development stage right now, and hope to have some code up and running by sometime next year. (It's not a high priority project; I do have a real job, as well as a fairly active social life.) A tentative goal is to attend either the 2007 or 2008 SXSW Interactive festival http://www.sxsw.com/ and promote the site, or the new project, or both. From the reports I've been getting about the festival it sounds like a good place to spread the gospel of the Corpse. I've also thought of attending Perl conferences to discuss the project, but right now I think we want to focus more on getting artists interested in the project, to improve the content that we're getting on the site.

So this site will be infrequently updated, as I work on the project and want to share my findings. Catch you later....