How to invert a PDF using ImageMagick

The problem:

I wanted to print the extremely-twisted and NSFW Cards Against Humanity deck (available as a free PDF). The last 5 pages have white text on a black background, which kills my toner and looks awful (e.g. uneven toner placement, smudging, etc). I wanted to print these as black-on-white instead, but couldn’t find a black-on-white version of the PDF. Furthermore, I couldn’t figure out how to do it at print time (my laser printer doesn’t seem to have an “invert” option).

More »

How to remove permanent marker from NES game pak labels

Time to re-define permanent!

I bought a bunch of used games, and some of them are a mess. Stickers on every side, gum and dirt sticking out, etc. Filthy (but cheap!). I’ve been able to clean the sticky stuff really well using Goo Gone, and rubbing alcohol for the contacts (to prevent the “red blinky square of death”).

But I didn’t know what to do about the labels. Some labels had the previous owner’s name in permanent marker, like so:

SMB3 Before

After doing a bit of Googling, I read a suggestion to use a light amount of Goo Gone. So I sprayed a Bounty paper towel sheet about 1-2 pumps full of Goo Gone, then lightly tried to rub the permanent marker off. And it came off, without pulling away the rest of the label. Happy happy!

SMB3 After

If you look closely at the “After” photo, you’ll notice a darker spot where some Goo Gone seeped into the side of the label. Once it dried (about an hour later), the discoloration left, and the label looked perfect. I try to avoid the edge of the label where possible, but sometimes I miss.

So far, I’ve tried it with NES and SNES cartridge labels with great success. I tried it with an N64 game too (Diddy Kong Racing), and unfortunately the ‘Gone caused the label colors to bleed. So I’m a bit apprehensive about trying to clean up another N64 game.

If you try this yourself:

  • Avoid the edges of the label where possible, to avoid discoloration (even though it’ll probably go away when the Goo Gone dries
  • Don’t use too much ‘Gone. Try a spray or two into paper towel, and see how that works. If you think you’re getting the label too wet, dry off the excess liquid! Take your time :-) .
  • Don’t spray the label directly. Spray into your paper towel.
  • If this is your first time, you might want to practice with a label that you don’t care much about.
  • If you’re worried about the color bleeding, try wiping a small area that you don’t care about first. Also look at your paper towel as you clean. If you’re wiping up black marker, your towel will be black. If your towel turns the color(s) of your label, it might be time to stop before you smear it all to pieces!

Obligatory Flickr shots:

Funputer

Remember those advertisements where models look like they’re having far too much fun playing video games?

I spent a weekend or two working on a small site called Funputer, where video game systems are judged by how much fun people appear to be having.

In addition to the typical game systems, Rock Paper Scissors was added as a control mechanism. It was beating all the other systems until I posted about it on Digg.

Unfortunately, I can’t find the PS2 promo images that inspired me to make the site. If you know where these might be found, pleeease let me know.

Propagating Noise

This weekend, I took some steps to move the Dillfrog Noise site to a new home. A home that doesn’t fear more than 384kbps of traffic. A home with enough square footage (or square meter..age..?) to hold losslessly-compressed audio.

It’s a relatively-unusable work-in-progress, but at least it’s in progress!

Here’s what I’ve learned so far:

  • PHP appears to be the ugly child of Perl, Java, and let’s say EMACS. I say “EMACS” because it’s the first thing that comes to mind when I think of a hacked-together system with few intuitive design decisions. I’m new to PHP, and (flame-repellant) I don’t know much of EMACS either.
  • Dreamhost likes to kill my processes when I don’t run them “nice -n19″. And even then, I’ve still (apparently) been a CPU hog. To their great credit, they added a feature to give “nice -n19″ apps a fair chance, after I submitted a support ticket. Major points for listening to their customers! I was running a lot of server-side FLAC -> Mp3 conversions to build the site.
  • It’s easier than I expected to edit remote files without X11. See, I’m used to editing my code with “nedit” over X11, but Dreamhost doesn’t allow that. I searched around for programs that mapped SSH connections as network drives, automatically synchronized folders via FTP, etc. I found these, but none of them felt like a great idea. Eventually I realized that my already-favorite apps (WinSCP for Windows, and Cyberduck for OS X) already allow me to edit files locally and magically re-upload whenever I save them. WinSCP has been a little finicky, but Cyberduck treats me right.

I still need to clean up the UI, add graphics, build an authentication mechanism, an admin tool, AND ACTUALLY WRITE NEW SONGS, but it’s nice to see some progress.

The next challenge will be to either synchronize or move the Dillfrog account database to Dreamhost’s MySQL servers, so I can keep things personalized. Hopefully, like the Cyberduck/WinSCP example above, the solution is staring me in the face.

Help me test this out, won’tcha, and subscribe to the new Noise podcast feed.

Geotagging in the 21st Century

Geotagging Prototype: BridgeIn preparation for my WalkAmerica get-up-early and test-those-sneakers walk, I’ve been playing around with some of my GPS toys. This involves two projects which I hope will converge, but so I don’t confuse you, let me just talk about the geotagging piece.

My Motives

  • I hate asking for donations, in fact up ’til now I have avoided it entirely. But I thought maybe I could use my strengths (geeky and musical) to add a low-cost incentive, so it’s less of a “something for nothing” proposition.
  • It’s no fun having geeky toys and not using them to their fullest. Time to break out the Garmin eTrex Legend that’s been sitting around here.

From this, I decided to try documenting the event using geotagged photographs. Basically, I would provide a map of where I walked, and pictures along the path. Not as exciting as the Grand Canyon or something, but it had potential.

Low-Tech Geotagging: The Theory

Okay, here’s the plan: on my walk, I’m going to bring my GPS receiver (Garmin eTrex Legend), and my digital camera (Canon Powershot A40), then use the combined data to map the digital pictures to a GPS location.

The camera records the date/time each image was shot, inside the EXIF data of the JPEG file.

The GPS receiver records my GPS position, along with the time it was recorded, in its Track Log (eTrex Legend users can see data usage by going to Main Menu -> Tracks).

Caveat #1: GPS Positions seem to be recorded every 15 seconds or so, meaning I won’t know the *EXACT* location a photo was taken at, but this is close enough for me. The frequency might change as my movement vector changes, but I didn’t look into it.

Caveat #2: When you save a GPS track, the eTrex strips the timestamp data. That’s right — if I decide to “Save” my track, I won’t be able to use it to geotag images. Only the “Active Track Log” (the log automatically maintained, where you DON’T save images) maintains the timestamp.

Caveat #3: I’m dealing with two separate clocks: the GPS receiver’s and the camera’s. Since the camera clock is only maintained by an internal battery, and the GPS receiver’s is based on the satellite time, I’m trusting the receiver. This means that I need to either change my camera’s time to match my receiver’s prior to shooting, or I need to specify a time offset as photos are merged.

Coding the Prototype (in Java!)

Yeah, I could write a 10-step process using existing commercial apps, but I’d rather code a solution than bootstrap non-open solutions. Plus I’m curious how it all works. So this led me to use the following:

  • Netbeans 5 IDE – for MacOS X this time, just for fun. Java Runtime 1.4.2 for compatibility, as much as I enjoy 1.5.
  • GPSLib4J – an open library to retrieve Garmin GPS data using Java. It’s structured in the hopes of pulling data from other devices in the future, but such support has yet to be seen. Since I’ve got a Garmin, I’m set, plus if I ever want to support other devices, this is probably the best place to start. With this, I can retrieve my trackpoints (timestamps, latitude, longitude, etc).
  • Drew’s JpegMetadataReader – also known as “jpeg exif / iptc metadata extraction in java”, which doesn’t have a snazzy acronym yet. This lets me read the timestamp each of my images was captured (which is stored as EXIF data), and was very easy to get started with. Mad props to those who published the library and provided simple example code.
  • Some random thumbnailer code by Marco Schmidt. I don’t know if AWT is still “the way to go” for this (I’m no Java expert), but it was great enough for my prototyping session.

With those tools, my code takes a directory of images, and an attached GPS receiver as input. Then it:

  1. Imports trackpoints from the GPS receiver, and sorts them by time.
  2. Iterates through all the images in my directory, reading the normalized capture timestamp (the timestamp, which is synched to the GPS receiver’s time by some offset), and matching this to the nearest two GPS trackpoints.
    • If it matches one trackpoint exactly, we use that trackpoint’s coordinates.
    • If the image time is prior to the first trackpoint, we deem it unmatchable (harsh, I suppose — I could still allow it within N seconds of the first trackpoint)
    • If the image time is after to the last trackpoint, we deem it unmatchable (harsh again; I need to set up a threshold)
    • Otherwise it’s between two points! I interpolate a new point between these two points, and return that new point’s coordinates. In my tests, this was FAR more accurate than simply choosing the nearest (timewise) of the two points.The interpolation is simple, too. Ignoring minute issues about “double” precision:
      • // Determine where on this segment this image was taken (between 0.0 (point A) and 1.0 (point B))
      • double trackpointTimeDiff = trackpointB.time – trackpointA.time;
      • double imageTimeOffset = image.time – trackpointA.time;
      • double normalizedImagePos = imageTimeOffset / trackpointTimeDiff;
      • // Determine actual position
      • double newLat = trackpointA.latitude + (normalizedImagePos * (trackpointB.latitude – trackpointA.latitude));
      • double newLon = trackpointA.longitude + (normalizedImagePos * (trackpointB.longitude – trackpointA.longitude));
    • If the nearest trackpoints were more than N seconds apart (N=20 for me) I warn that the image’s coordinates could have some more error than usual.
  3. Outputs some HTML code that I can use to build my “Google Maps”-indexed page

Since GPS latitude and longitude can be stored in the EXIF data, I would have rather done that, but I couldn’t quickly find a free Java library to save EXIF data. If you know one, please buzz me.

Then I just uploaded the HTML page and images to my Web site, and had a crude map of images! Yay!

I could take this a step further and try uploading the images to Flickr, or upload straight to my site, etc, but this was enough to prove I wasn’t too crazy.

Don’t applications do this already?

I didn’t think so at the time, but as I was troubleshooting I ran into two big give-away URLs:

  • Julian blogged about a similiar project in early 2005. I can’t find the original article anymore — only in the Google cache. He ran into most of the same issues I did: Garmin’s track log not saving the timestamp, RXTX (serial Java interface stuff) not working properly without me belonging to group uucp, etc. Apparently I’ve been living in his shadow.
  • JetPhoto Studio does nearly everything I wanted — it imports the GPS points, correlates them to the images based on times, etc, but version 2.1.3 has two flaws as far as I can tell:
    • I haven’t found a way to specify a camera clock offset, so if I forget to sync my camera clock to the GPS receiver’s, I might suffer worse accuracy issues.
    • When JetPhoto matches a photo to a GPS position, it only picks the nearest point, as far as I can tell. I would much prefer that it interpolates a point as described earlier in my post.
    • I see no mention of open licensing, though it’s a free download. I’m afraid of it becoming pay-to-play, or that I want to add a feature that they don’t support. Open frameworks are neat.

Screenshots

Because reading about it can be pretty boring if you’re not me! My wife and I took a car trip downtown, snapping along the way.

Geotagging Prototype: Points OverviewHere’s how the points got mapped; these points are pretty darn accurate considering the potential margin of error.

Geotagging Prototype: BridgeWhen you click a point on the map, a thumbnail of the image pops up, which you can then click to view a full-size image. The info bubble is a bit, uh, malformed at the moment, but it’s good enough. Look at how this thumbnail matches up really well with the bridge. The picture is facing north, so you can see the highway below us. This interpolated point matched up tons better, I think, than the point JetPhoto Studio chose.

Conclusion

The prototype’s interface is pretty awful, but it’ll be swell enough for my walk, for sure. If I can find a way to save the EXIF data, that’d streamline most of my plans too. Or at least, maybe I can convince JetPhoto folks to add interpolation to their tool. Then I can move onto my second project! (More GPS adventures coming soon)

Time for Prepaid Cell Renewal

Mologogo Sample MapMy year of Tracfone service ended on February 28, and I couldn’t be happier. I use a cell phone for non-911 emergencies, grocery shopping, and calling when I’m lost. That’s about it, not much recreation about it. I’m about to change into a GPS-hugging, J2ME-codin’ anteater, but let’s look at how I got there.

More »

Copyright, Acknowledgement, and other Legal Sedatives