PC Plus HelpDesk - issue 262
 |
This month, Paul Grosse gives you more
insight into some of the topics dealt with in HelpDesk.
From the pages of HelpDesk, we look at:
- End-Of-Line codes;
- Animated favicons;
- Never work with children and animals;
- Correcting photographs for density; and,
- Is my manager/partner a psychopath?
|
 |
HelpDesk
End-Of-Line codes
If you are transferring flat text files between
Windows and UNIX-based systems, you might well encounter
a problem with files that are interpreted.
If you want to run a file in the current directory
called, say, 'silk5.pl' and this has been written on
Windows, say by Notepad, when you enter into the shell
'./silk5.pl' the shell might well say:
bash: ./silk5.pl: /usr/bin/perl^M: bad interpreter: No such file or directory
So, what is the problem?
All of the UNIX-like OSes use a single character for a
new line (0x0a on UNIX and 0x0d on Mac OS X). However,
Windows uses 0x0d0a so when Notepad saves a file, it uses
two characters instead.
The first, 0x0d, is not looked upon as a new line
(except in Mac OS X) but as a character - the following
0x0a being the new line. So, when Bash looks at the first
line, it is looking for a program called
'/usr/bin/perl^M' ('^M' or [Ctrl][M] being 0x0d) which,
of course, doesn't (or, at least, shouldn't) exist.
There are
two easy ways to get around this:
- One is to insist that your friend uses the '-w'
warnings switch on the hash bang line - this will
have the effect of placing the ^M after a switch
so the program name will be correct; and,
- The other is that you open his file in a text
editor such as KWrite and and under 'Tools', 'End
of Line', select 'UNIX'.
It should all run nicely now.
|
Animated favicons
By now, most of us have come across the favicon.ico
that appears in the address bar of the browser when we
see a web page. However, these are not limited to static
images or even .ICO files.
You can include an animated .GIF file by using the
following line of HTML code in the <HEAD> section
of your page - substituting 'animated_favicon1.gif' with
the path and file name of your image...
<link
rel="icon"
href="animated_favicon1.gif"
type="image/gif">
So, that's how easy it is to include an animated gif
but how do we go about getting one?
There are a number of different image processors that
will produce animated .GIF images but out of Photoshop
CS3 Extended, PaintShop Pro XI and The GIMP, only The
GIMP (as far back as version 1.2.3 and probably before)
will read them in - the others let you know that they
will discard all but the first layer of the image.
So, in the interests of being able to read in and edit
the file you have created (and also with the bonus of
being cross-platform), we'll use The GIMP (The GIMP has
been able to do this for years so we'll do this on
version 1.2.3).
|
First of all, you need to create the text or
other image(s) that you are going to use. Here, we'll
display some text and have that scroll by us.This is
an image that is 16 pixels high. At the end of it, we
have the first part, up to and including the 15th pixel.
If this was not included, the image would jump from some
empty space at the end to the first frame - here, we feed
into the first frame so that it looks nice and
continuous.
|
Next, copy the image (usually by pressing
[Ctrl][D]) and then use the crop tool to make it a 16x16
square at the far left (you'll find it useful to zoom in
by a factor of 10 or so). This will now be the first
frame of the animated .GIF file.Next, click on the
long image again and then, in the Layers dialogue box,
drag its image and drop that on the square image. This
has now become the top layer.
Use the move tool to make it displaced one pixel to
the left of the image underneath it. You can check that
this is the case either by clicking on the Eye logo in
the Layers dialogue or by changing its opacity
(remembering to change them back afterwards, of course).
Once you have a full strip in your image, you can just
drag that from the Layers dialogue and drop it in the
image - each one adds a new top layer that you can then
move.
Once you have got to the last frame (or even before,
if you want to see how it is getting on), you can test
out the layered image by right-clicking on the image and
then selecting 'Filters', 'Animation', 'Animation
Playback...' and pressing 'Play' in the dialogue.
If it all looks the way you want it, you can trim it
down to size because at the moment, almost all of the
layers are too long.
|
The last image in the sequence looks like
this. You can see from the dotted line that the rest of
the image goes off to the left. Ideally, you want to get
rid of this. You can either: go through each image on the
Layers dialogue box, clicking on 'Layer to imagesize';
or,
|
you can select the crop tool from the
toolbox.Select the whole of the 16x16 image and click
on 'Crop'.
|
This will cut every layer down to size, all
in one go.Next, convert it to a palette-based image by
right-clicking on the image and selecting 'Image',
'Mode', 'Indexed' and...
|
Next, we can produce an optimised animated
gif by right-clicking on the image and selecting
'Filters', 'Animation', 'Animation Optimize' which
produces a new image.You can see from the layers
dialogue screenshot on the right that each layer only
includes the changes that it needs to make from the
previous layer - this keeping down the image size and
processing that is needed in order for the image to work.
|
Finally, we have our image. Right-click on
the image and select 'File', 'Save As...' then type in a
name that ends with '.gif' such as 'anifavi.gif' and then
click on 'OK'.
|
Now, you need to let the program know that
you do want to save it as an animation so click on 'Save
as Animation' and then on 'Export'.
|
The next dialogue box allows you to specify
how you want any non-specified layers to be dealt with.
If you have followed these instructions, you shouldn't
have any of these so just click on 'OK'.
|
And this is how it should look. If your
browser supports favicon.ico images then this should
work.You should, of course, remember that you can
specify a normal icon and an icon file for shortcuts as
well so your head section should look like this...
<link rel="shortcut icon" href="favicon.ico" >
<link rel="icon" href="animated_favicon1.gif" type="image/gif" >
|
Never work with children and animals
Photography using photographic film that was then
developed required a certain amount of skill - especially
when using medium format - because darkroom skill had to
be earned. If you wanted to adjust the density of a
certain part of the image, you would be better off
changing the lighting when you took the original image.
On the whole, you would take care to make sure that
you had the correct focussing, lighting and aperture
before you took the shot. This is fine if you have a
stationary subject - you are taking a picture of a USB
drive or something - or a co-operative one - an adult or
group - but if the subject matter is moving
unpredictably, you might just have to take a shot and
hope for the best.
This is where image processing software comes in.
Unfortunately, there is a tendency for people to take
dozens of poor shots and then hope that they can use
Photoshop, PaintShop Pro or The GIMP to get something
reasonable out of it. If they can't, they then add one of
the special effects (make it look as though it is printed
on canvas or an old photograph) so that the effect messes
it up more than the original photograph was messed up,
thus disguising the fact that it was not a very good
image to start with.
So, assuming that you had a small furry kitten that
was not going to sit still and you had to take a
photograph of them, what can you do?
...
|
Correcting photographs
for density
We're going to have a look at two pictures of a kitten
and make them look all right.
These are things that you can do in the darkroom if
you want but as the images are already digital, we're
going to do it with an image processor (or three).
They are quite simple things to do to images that
haven't got a lot wrong with them in the first place -
making the picture better to look at by correcting issues
that are a result of lack of opportunity (rather than
just adding meretricious effects to a picture that is not
particularly good to start with, in the hope that the
effects will distract the viewer from the poor
photography).
|
Here is the first image. It is of the kitten
lying down on a window ledge - she had just woken up and
there wasn't a chance to get a light reflector on the
left (you can't see one in the kittens right eye).If
the opportunity presented itself a reflector would have
been best - if handled with respect, these don't frighten
kittens in the same way that a fill-in flash would.
|
|
This is what needs doing to it.We could
just open up the curves dialogue and push the darker
areas up a bit but that would reduce local contrast and
produce an inferior image. We need to boost the
luminosity of the darker area overall without losing that
local contrast.
So, this is the first step. Take a copy of your image
(as you should always do - never work on the original)
and copy the layer.
- GIMP - drag the image from the Layers dialogue
and drop it on the image itself - this duplicates
it, making it a two layer image with the current
layer as the top layer.
- PaintShop Pro - drag the image from the Layers
dialogue and drop it on itself - this duplicates
it and makes it a two layer image with the
current layer as the top layer.
- Photoshop CS3 Extended - create a duplicate image
by selecting 'Image', 'Duplicate'. Then, select
the original image so that it becomes the current
image and in the Layers dialogue, drag the
original image and drop it into the new image -
this becoming the top and current layer of the
new image.
|
|
Next, we need to
produce a mask from it that we can then blur - we need to
keep local contrast whilst reducing the overall contrast
between the shadow area and the rest of the image.
- GIMP - select the threshold tool and click on the
image. Take the lower threshold down to zero and
then adjust the upper threshold until the shadow
area is highlighted - around 40.
- PaintShop Pro - Click on 'Adjust', 'Brightness
and Contrast', 'Threshold'. Take the threshold
down to around 40 (in this case, you can't do it
the other way around. To get around this, we need
to invert the densities on that layer. Select
'Image', 'Negative Image'.
- Photoshop CS3 Extended - Click on 'Image',
'Adjustments', 'Threshold...', move the cursor
along until it says around 40 and click on 'OK'.
This control has even less control over it than
PaintShop Pro and again, we need to invert it.
So, select 'Image', 'Adjustments', 'Invert'.
|
Next, we need to blur
it so that we preserve the local contrast in the image.
- GIMP - select 'Filters', 'Blur', 'Gaussian
Blur...' and then choose a blur radius of 40 (in
this case - both for horizontal and vertical) and
click 'OK'.
- PaintShop Pro - select 'Adjust', 'Blur',
'Gaussian Blur...' and choose a blur radius of 10
for the same effect then click on 'OK'.
- Photoshop CS3 Extended - select 'Filter', 'Blur',
'Gaussian Blur...' and choose a blur radius of
around 10 for the same effect then click on 'OK'.
|
Now, we need to use
this to process our image - the black and white image is
too strong so we will use the 'Opacity'/'Transparency'
control to reduce its effect. We could just take it away
from our image but that would have the effect of reducing
the saturation of the affected part of the image as well
as reducing the overall tonal range of the image.
- GIMP - instead, we need to select 'Dodge'. Now,
move the Opacity control until you have the
correct effect. Remember that we don't want to
see that it has been corrected so we only need a
small amount - around 5 - 10%.
- PaintShop Pro - Change the blend mode to 'Dodge'
and lower the percentage for that layer to around
20%.
- Photoshop CS3 Extended - Change the layer mode to
'Color [sic] Dodge' and the opacity to around 5%.
|
Next, we need to make it one
layer.
- GIMP - flatten the image and that is all there is
to it.
- PaintShop Pro - select 'Layers', 'Merge', 'Merge
All (Flatten)'.
- Photoshop CS3 Extended - select 'Layers',
'Flatten Image'.
 This is the image
(left) compared to the original (right).
You can see that the detail in the shadow is a lot
more visible and will print better.
|
| |
Here's the second
image.This was taken a few weeks before the one above
and you can see that her eye's aren't as mature - they
still have the wappy psycho-kitten look about them and
they are pointing in slightly different directions.
The kitten eventually settled down between a bookshelf
and a blue, plastic storage box.
This is the image after straightening and cropping.
|
The fur on the
kitten's front is white so we would like to increase the
luminosity of that.In addition, we want it to look
like a picture of a kitten and not a kitten sandwich so,
as the kitten is light and its immediate surroundings are
dark, we'll tone down the fronts of the bookshelf and the
storage box thus making the kitten the focal point of the
photograph.
Also we need to remove the red-eye so, first of all,
let's do just that...
|
We need to mask off
the pupil.
- GIMP - One way of doing this is to click on the
ruby mask button at the bottom-left of the image
window, zoom in on the image and then use the
paint brush with a fuzzy brush to paint white
where the bits you want to edit are. When you
click back from the ruby mask, you will see your
area selected as in the image on the right.
- PaintShop Pro - Select 'Adjust', 'Red Eye
Removal...'. Next, select the method
'Point-to-Point Outline' and then, click points
on the image on the left, double-clicking when
you have done.
- Photoshop CS3 Extended - find on the tool ribbon
the healing brush tool (a plaster icon) and click
on it but hold it down. A tools menu will open up
and the 'Red Eye Tool' - select that and the icon
will change.
|
Next, get rid of the
red. We don't want any red but we do want the white
highlight.
- GIMP - Right-click on the image and select
'Layer', 'Colours', 'Desaturate' and the selected
area will become monochrome. The pupil now looks
grey and white but we want it with almost black
instead of grey. Click on the Curves tool (or
right-click on the image, select 'Layer',
'Colour', 'Curves...') and change it so that the
highlights have the same density but the
lowlights are darkened.
- PaintShop Pro - Next, you can change the feather,
glint size and so on. Note that PaintShop Pro
produces a false glint. When you have finished,
repeat the process for the other eye.
- Photoshop CS3 Extended - click on the red eye and
it will darken, preserving the original
highlight.
|
Now, we want to tone
down the edge of the book case (left) and the blue
plastic container (right) so that our kitten is what we
focus on. The reflective surface of the floor is
horizontal so we need to treat reflections in the same
way as the objects themselves.
- GIMP - Select the rectangular selection tool,
feather the edges to around 40 pixels and shrink
down the image. Expand the window and then drag
the cursor so that the top and bottom are well
away from the image - this means that the
feathering only affects the vertical lines.
Invert the selection ('Select', 'Invert' or
[Ctrl][I]) and then click on the Adjust Colour
Curves tool. Drag the curve downwards to tone
down the book case and the plastic container and
click on 'OK'. Next, deselect the selection
('Select', 'None') and then use the Adjust Colour
Curves tool to make the kitten's fur the right
density.
- PaintShop Pro - Select the parts of the image
with the rectangular tool in the same way as the
GIMP above. Select 'Selections', '' to invert the
selection of the image and then select 'Adjust',
'Brightness and Contrast', 'Curves...' and adjust
the density of the bookcase and the plastic
container by dragging the right hand marker down
on the RGB display then clicking on 'OK'. Next,
right-click on the image to remove the mask and
repeat the curves tool, only adjusting a point in
the middle this time to bring the fur out to its
correct density
- Photoshop CS3 Extended - click on the
'Rectangular Marquee Tool', set the feather to
20px and then drag the cursor across the image
following the same top-left to bottom-right path
that you can see in the GIMP image on the right.
This, unfortunately, feathers the top of the
image whereas, in The GIMP and PaintShop Pro,
they select properly. Next, invert the mask by
clicking on 'Select', Inverse. Next, click on
'Image', 'Adjustments', 'Curves...' and pull the
right hand half of the graph down to make the
book case and the plastic container darker and
click on 'OK'. Click on 'Select', 'Deselect' to
remove the mask and then click on 'Image',
'Adjustments', 'Curves...' and pull the right
half and the middle of the graph upwards to
lighten the fur.
One alternative is that you can darken the book case
and the plastic box and then, instead of deleting the
selection, just invert it and make the fur lighter - the
choice is yours.
|
 And this is it (left)
compared with the original (right). |
Is my manager/partner a psychopath?
Note that this runs on Windows, UNIX, Linux, *BSDs,
Mac OS X and so on.
There is a 20 point questionnaire called the Hare List
that was developed over the years by a number of
psychiatrists/psychologists so that there could be (along
with a number of interviews carried out by a
psychiatrist) a reasonably objective way of assessing
people to see if they fell into a group of personality
types that are known as psychopaths - there are other
parts to this assessment that the trained professional
would know about but here, we are, in the true tradition
of those psychometric tests that you see in women's
magazines at the doctor's/dentist's, we're going to throw
to one side all attempts to be objective and instead,
have a 'fun-to-do' test that will show off some of the
aspects of the Perl Tk GUI. This is, of course,
light-hearted and you shouldn't take the results
seriously. And, just in case you were wondering if
psychopaths had any positive contribution to make to
society, they do make good managers (although, you might
question if that is a positive contribution and also, you
might ask why are psychopaths more suited to the
requirements of modern management than others?).
So, where do we start and what do we need?
The Hare psychopathy check-list is freely available on
the Internet (you can find it in the Wikipedia for instance) but we have a
copy here.
The scoring on it for each check-list statement is:
- 0 for doesn't fit;
- 1 for fits a bit; and,
- 2 for fits completely.
There are four categories for the statements:
| Interpersonal |
- Glibness/superficial charm
- Egocentricity/Grandiose
sense of self-worth
- Pathological lying
- Conning/Manipulative
|
| Affective |
- Lack of remorse or guilt
- Callous/Lack of empathy
- Shallow affect
- Failure to accept
responsibility for own actions
|
| Lifestyle |
- Need for
stimulation/Proneness to boredom
- Parasitic lifestyle
- Lack of realistic,
long-term goals
- Impulsivity
- Irresponsibility
|
| Antisocial |
- Early behaviour problems
- Poor behavioural controls
- Juvenile delinquency
- Violation of conditional
release
- Criminal versatility
|
Traits
not associated
with any factor |
- Promiscuous sexual
behaviour
- Many short-term marital
relationships
|
However, we will just look at the
overall score. So, all we need now is a program. Perl is
cross-platform and it has a GUI - unlike the GUIs on some
operating systems, Perl's GUI is about getting the job
done, not distracting the user with facile special
effects.
We've all used Perl - it is the industry standard web
server language - but whilst it runs on literally
millions of servers every day, we can also use it for
normal programming as well and, it is particularly easy
to learn.
The GUI is called Perl Tk and it has the advantage
that you can design it using UNIX or Windows and it will
run on all of the others.
To use Perl Tk, you need to do a bit of object
oriented programming but this is fairly easy.
You can
find the program here
and have a look at it. Below is a summary of how the
program is written, right from the basics.
The following line tells the shell in UNIX where the
program that needs to run this script actually exists. In
this case it is in a directory called /usr/bin but can be
in /usr/local/bin or somewhere else.
#!/usr/bin/perl -w
On a UNIX system, you need to get this correct (you
can use the 'whereis' command to find out the answer).
On a Windows system. this doesn't matter because the
file associations are system-wide through the file
extension (normally .PL in the case of Perl programs).
The '-w' switch tells perl to use warnings - this is
useful when you are developing programs as they give out
useful information such as which line the interpreter
thinks an error occurs on and so on.
To remark a line out (that is, to remove the
functionality of a line of code without deleting that
line) just start the line with a hash mark '#'. You can
deactivate commands or write notes with these.
The next two lines tell perl to use the Tk module and
the progress bar module
use Tk;
use Tk::ProgressBar;
Now, we will call the program as a whole. Subroutines
that I have written start with an ampersand when they are
called.
The first two lines set things up in terms of
variables and the third generates the GUI. The fourth
runs the GUI and at that point, the program becomes event
driven.
&readfile; #input Definitions and explanations (1..20)...
&initvars; #initialise the variables
&creategui; #make the GUI
MainLoop; #run it...
exit (0);
Here's the first subroutine. We start off by defining
the block of program using 'sub name {}'. Anything within
the braces is part of the subroutine.
sub initvars {
$progress = 0;
$qn = 1;
$c = $d[$progress];
$b = $e[$progress]
}
'$progress' is a type of variable called a 'scalar'.
It can have integers, floating points or strings in it.
You can also have arrays (such as @myarray) but if you
want to address a single scalar within that array, you
use the $ sign in front (such as $myarray[17]). Array
indices start at zero.
In 'readfile' we open the list of statements and
descriptions. We give the file a handle (in this case
called 'FH') and we can use that to refer to the file in
future.
open (FH, "list");
There are 20 but they will use the indices 0..19. To
get a list of numbers (say 5 to 9), you do the following
(5..9) which returns a list '5 6 7 8 9'. If we wanted to
go through these in reverse, we would say 'reverse
(5..9)' which would produce '9 8 7 6 5'. The foreach
statements produces a list of values and stores them in
$c
foreach $c (0..19) {
$a[$c] = -1; # set element of array @a to -1
$d[$c] = <FH>; # read statement line from file
chomp ($d[$c]); # take return off end of line
$e[$c] = <FH>; # read description line from file
chomp ($e[$c]); # take return off end of line
#chop down the lengths of the string into more handleable portions
my @f = split " ", $e[$c]; # split the description line up into words and
# store them in an array called @f
$e[$c] =""; # empty the description
my ($g, $lg) = ("", 0); # set two local variables at the same time
$w = 50; # set a global variable - the line length
foreach $h (@f) { # create a loop using each word in the description
$lh = length ($h); # find the word's length
if (($lh + $lg) > $w) { # if that plus the length of the existing line
# is greater than the width ($w) then:
$e[$c] .= $g . "\n"; # add a new line character to the end and save it in
# the description array;
$g = $h . " "; # start a new line for the description
$lg = length($g) # find its length
} else { # alternatively:
$g .= $h . " "; # add the word and a space to the end
$lg = length($g) # and find its length
}
} # finish the loop
if ($lg) { # if there is anything left over,
chomp ($g);
$e[$c] .= $g . "\n" # add that as well.
}
}
close FH; # close the file.
}
Now for some OOP.
sub creategui {
# create GUI
$mw = MainWindow -> new(-title => "Hare Test...", -bd => 10);
^ ^ ^ ^ ^ ^ ^
Variable | | | | | Value
Object type | | set value Variable
| Method
Pointer
Here, we are setting a new variable $mw to contain the
pointer to an object (called 'MainWindow'). It doesn't
exist until we execute this line so we have to use a
method called 'new' which creates it. Optionally we set
some of its attributes, in this case, we set the '-title'
to have a value 'Hare Test...'. That is almost all there
is to it.
$bf = $mw -> Frame () -> pack (-side => 'bottom', -fill => 'x');
Now, we create a new variable - pointing to the
pointer $mw - that has a frame in it. It needs packing
into our main window so we call the pack method which has
its own variables. The reason we give it a pointer is
that we need to refer to it later so that we can put
things in it or modify it in some way. Like this...
$bf -> Button (-text => 'Quit', -command => sub{exit(0)}) -> pack (-side => 'right');
The above line doesn't generate a variable with a
pointer in it because we don't need one. The button,
though, does need to do something when it is clicked so
we have something called a 'callback', the '-command'
line. In this case, it is an anonymous procedure
consisting of just the exit command.
$bf -> Button (-text => 'About', -command => sub{&about}) -> pack (-side => 'right');
Here, it refers to an external command (so, if you
have a complex subroutine that is called more than a
couple of times from a number of different places, you
can refer to that; or,
$sb -> Button (-text => 'Last', -command => sub{if ($progress >0) {
$progress--;
$qn = $progress +1;
$c = $d[$progress];
$b = $e[$progress];
$n = $a[$progress];
}}) -> pack (-side => 'left');
in the above example, it is a multi-line procedure
which goes
if ($progress >0) { $progress--;
$qn = $progress +1;
$c = $d[$progress];
$b = $e[$progress];
$n = $a[$progress];
}
and that is about it. Use a few different types of
object and you can produce whatever you want.
There is plenty of more about this on the Internet and
there are loads of books as well. Mastering Perl/Tk is a
good start from O'Reilly (ISBN 1-56592-716-8).
So, how does it look on various platforms?
|
SuSE 8.2 professional |
SUSE 10.2 with Compiz |
OpenBSD 4.1 with KDE |
Windows Vista Ultimate.Note that with
Windows, you need to install ActiveState Perl (free) in
order to run it.
|
Back to PC Plus Archive Index Page
|