Tuesday, 11 February 2014

Fun with a digital photo frame.


Today, it's trying to get SWMBO's family pictures onto one of those “digital” picture frames.

It's an old one from Jessops (a 5156874) that was given to us for “not working properly”.
It was the cheapest on the market at the time.

It's quite difficult to operate using the touch controls, so the usual thing is just to power it on and let it do it's own thing. Plugging the USB into a Linux box throws a wobbly and doesn't work, so it's back to Windows to get files onto it.

The pictures are a mixture of jpegs, gifs and bmps from all over the place.
Sure enough, some pictures display ok, but some won't display. Unfortunately, this includes anything downloaded from Facebook, and also anything from a newish camera.
That's not good.

Further investigation seems to show that the unsupported jpegs are not “too big”, as I first thought, but they're “progressive jpegs”. Huh! Whatever that is, it's evidently too new for this frame.
It appears that jpeg files are not all the same, and there are a number of different types.

There's no possibility of any software updates for this, as Jessops went bust a while back. The new owners have re-invented the shops as a bit more up-market, and they don't do this sort of cheap stuff. Anyway, there doesn't appear to be any way to update it, even if such a thing was available.

The way I went about it, was to convert the errant pictures from progressive to baseline jpegs.
You can do this one file at a time with Windows Paint, and trying it out works ok, so that proves that we have found the problem.

This is all very well, but is going to take a lifetime, so searching around, and going back to Linux, I found that ImageMagick will also do this, and we should be able to cobble up a script to do a whole batch all at once.

Conveniently, as usual, someone has already been there, and there's a nice script on this page:-


However, there's one or two small gotchas.

First, I tried to cut-and-paste the script from the web page, but that doesn't work, as the web page uses some other codeset that won't work in a script. So I had to re-type it by hand.

Any file that's been near a FAT file system (i.e. most cameras) have an extension .JPG and not .jpg so we need an additional -i for the egrep on line 1.
He's used -i for the greps on line 3, so it's probably a typo.

Out of habit, I usually add a #!/bin/sh at the beginning of a script, because that's how we did it in the old days. (Am I beginning to sound like an old bearded Unix guy?)
This had me fooled for a while, as it fails with a “not found” on the if clause in line 5.
To cut a long story short, it seems that Ubuntu, in it's wisdom, has defaulted the sh command to dash instead of the expected bash. How am I supposed to know that?
Changing the line to #!/bin/bash makes it all work. (Nearly!)

Another slight problem is these pesky Windows file names with embedded spaces. Most OSs don't like this, expecially any *nix. And lo-and-behold, the script fails on such files.

This is a common Unix/Linux problem, so I try a quick fix to change the spaces to underscores.
As this is Ubuntu, it has the Perl version of rename, so we can:-
rename “s/ /_/g” *.jpg (and repeat the process for *.JPG).
(Note that this fails using just * instead of *,jpg. No-one else seems to have encountered this failure mode, so I'll leave it for another day.)

As I did a bit of mucking about, I ended up deleting all the left-over files with names like picture99.jpg.prog

Now the script runs ok, and I copy all the files to a shared partition, reboot into Windows and copy the files to the frame.
So far it's working ok, but it's taken me all day. Oh, well.

And here's the final script:-

#!/bin/sh
# script to convert progressive jpegs to baseline.
for img in `find . -name "*" | egrep -i *\.jpe?g$`
do
  idout=`identify -verbose $img | grep -i interlace | grep -i none$`

  if [[ -z $idout ]]
  then
    echo "-------------------------"
    echo "$img is progressive"
    echo "....making copy of original with .prog extension"
    /bin/cp -f $img $img.prog
    echo "....converting to baseline"
    convert $img -interlace none $img 
    echo "....done!"
  #else
    #echo "$img is non-progressive"
  fi
done











No comments:

Post a Comment