Posts Tagged ‘script’

Script to produce iPhone app icons at different sizes

Tuesday, May 29th, 2012

The tools for writing iPhone software are really easy to use, and allow you to concentrate on the coding rather than on obscure configuration problems. But one area of iOS development that I found a little tedious whilst writing my Solar Balls game was producing Apple’s mandatory and optional icons, which need to be in a variety of sizes.

The application icons need to be generated at different sizes for the old screen resolutions, retina display resolution and for iPhone/iPad screen types. There are also other sizes you can produce for Spotlight and Settings.

The different icon sizes are described on Apple’s developer website here and here.

If you work for a big company and have access to an art department they may well manually produce optimised version of each icon. I don’t have an art department and don’t have time (or the interest!) to optimise each icon so I just wrote a very simple script to do the resizing for me.

It takes a source image and then resizes it into 8 different icons. It gives them names that fit in with Apple’s old recommended icon naming conventions.

solar balls lite icons

Icon list

57x57 Icon.png
114x114 [email protected]
72x72 Icon-72.png
144x144 [email protected]
29x29 Icon-Small.png
58x58 [email protected]
50x50 Icon-Small-50.png
100x100 Icon-Small-100.png

Usage

generateIcons.bat sourceicon [tag]
e.g.
generateIcons.bat iTunesArtwork
generateIcons.bat iTunesArtwork Lite

Or you can just drag the source image over the batch file.

If the first example the icons will be generated from your iTunesArtwork image with the names previously listed.

In the second example a tag is inserted into the name. So if the tag is ‘Lite’ then instead of Icon.png, you get IconLite.png. This can be very useful if you are using one XCode project to produce both a full and a lite version of your app.

You’ll need to have ImageMagick installed and on your path for this to work – ‘convert’ is a binary from ImageMagick.

This is a Windows batch file but you could easily convert it to a Mac OS shell script. I just happened to be using Windows at the time I was doing the icons for Solar Balls.

iPhone icon resizing script

goto :skip_functions
:makeAppIcons
	:: iPhone icon generator
	:: Details at http://www.reviewmylife.co.uk/blog/2012/05/29/script-to-produce-iphone-app-icons-at-different-sizes/
	set filename=%1
	set tag=%2
	:: icon sizes from
	:: http://developer.apple.com/library/ios/#qa/qa1686/_index.html
	:: http://developer.apple.com/library/ios/#documentation/UserExperience/Conceptual/MobileHIG/IconsImages/IconsImages.html#//apple_ref/doc/uid/TP40006556-CH14-SW1
	:: App icons
	convert %filename% -thumbnail 57x57 Icon%tag%.png
	convert %filename% -thumbnail 114x114 Icon%tag%@2x.png
	convert %filename% -thumbnail 72x72 Icon%tag%-72.png
	convert %filename% -thumbnail 144x144 Icon%tag%[email protected]
	:: Spotlight search result icons
	convert %filename% -thumbnail 29x29 Icon%tag%-Small.png
	convert %filename% -thumbnail 58x58 Icon%tag%[email protected]
	convert %filename% -thumbnail 50x50 Icon%tag%-Small-50.png
	convert %filename% -thumbnail 100x100 Icon%tag%-Small-100.png
goto :EOF
:skip_functions
call :makeAppIcons %1 %2
:end

It should be very obvious how to generate any additional sizes that you might need. And you could of course use a very similar script for resizing other app images that you might need for the standard/retina/iPhone/iPad screen resolutions.

DOS: Get the directory name from a file path

Monday, June 28th, 2010

If you need to write a DOS batch file that takes a file path as an input parameter and needs to do something to other files in the same directory as the input file then you’ll find there is no easy way to get the file’s directory name into a variable.

dos path from file

You could pass in the directory name as a separate parameter but that seems like cheating. I sometimes find answers to problems like these on Rob van der Woude’s scripting site or Google, but no luck this time.

I had to figure this one out from scratch. Here’s what I do. Let me know if you have a better (shorter) way of doing this.

  • Output the result of running ‘dir’ on the file path into a temporary file.
  • Loop through the lines in the temporary file, skipping the first three, and then taking the third token.
  • Assign that token to a variable.

If all has worked the variable which I’ve called ‘thedirectory’ should now contain the file path.

I’ve tested this on Windows 7 and I’m guessing it will work on other versions of Windows, but I’ll make no promises.

Here is the code:

goto :skip_functions

:setDir
if not %thedirectory% == "" goto :EOF
set thedirectory=%1
goto :EOF

:getDirectory
del %TEMP%\getdir.tmp
dir %1 > %TEMP%\getdir.tmp
for /f "skip=3 tokens=3" %%i in (%temp%\getdir.tmp) do call :setDir %%i
goto :EOF

:skip_functions

set thedirectory=""
call :getDirectory %1

@echo off
echo thefile =%1
echo thedirectory=%thedirectory%

And if you want to know what I needed it for have a look at my post about stitching together photos using ImageMagick.

Converting file extensions to lower case

Friday, January 15th, 2010

Recently I needed to convert a large number of photo file extensions to lower case. Doing this manually would take ages and wouldn’t be a fun job.

I wrote a quick batch file to look through all the sub-directories from the one it is executed from and change selected file extensions to lower case.

To use this script place the below code in a file called lowerCaseExtensions.bat. Put the batch file in the directory containing the files that you want changed and double click on it.

The script will loop through all the files in the directory, and will loop thought the files in all sub-directories and will change jpg, png and gif extension to lower case.

@echo off
setlocal
pushd .
goto :skip_functions
:toLower
	cd %1
	echo Processing %1
	ren *.JPG *.jpg 2>&1
	ren *.PNG *.png 2>&1
	ren *.GIF *.gif 2>&1
goto :EOF
:skip_functions
for /f %%i in ('dir /b/s/ad') do call :toLower %%i
popd
endlocal

You can easily customise this to change the file extensions of other file types to lower case.

This has been tested only on my Windows XP computer so I’d suggest you test it first on some copied files before you let it lose on your real ones.

Even if you aren’t specifically interested in the functionality that this batch file implements you might find it interesting to see how to implement a simple callable function in a batch file (:toLower), and how to implement ‘for’ loops.

Batch processing photos with DOS and ImageMagick

Thursday, August 7th, 2008

For my recent walking project I knew I was going to be taking lots of photos. I wanted a DOS script which would batch process the JPEG photos from my camera into the ‘full sized images’ (which are much smaller than the raw camera images), and the poloroid-like thumbnails.

The excellent ImageMagick tool provides a way to generate poloroid-like thumbnails automatically. I also wanted the thumbnails to be rotated at random angles which ImageMagick can do as well.

However the ImageMagick instructions were missing a few things 1) they seem to be aimed at people using Unix / Linux scripts whereas I’m using DOS scripts and 2) they show how to do this processing on single images rather than on a whole directory of them.

Poloroid rotation with ImageMagick Poloroid rotation with ImageMagick

It is quite easy to generate a random rotation angle with a simple bit of perl. The below line will generate a random floating point number between -7 and +7. I want both negative and positive numbers so that some of the poloroids will be tilted to the left, and others to the right.

perl -e "print rand() * 14 - 7"

I wanted to do all the processing through a DOS batch file so the next problem was how to get the random number into a DOS environmental variable. The answer is to use the ‘for /f‘ command to assign the output of a command into a variable:

for /f %%i in ('perl -e "print rand() * 14 - 7"') do set ANGLE=%%i

At the time when I wrote this script generating a poloroid involved a whole sequence of commands. Something like below!

-bordercolor white -border 6 -bordercolor grey60 -border 1 -background none -rotate %ANGLE% -background black ( +clone -shadow 60x4+4+4 ) +swap -background white -flatten

My script still uses this long poloroid command, but you might want to use the new one word ‘poloroid‘ command which is built straight into the latest versions of ImageMagick instead.

As well as generating the poloroid thumbnails it will also generate the full size website friendly images which are tagged with the website URL.

Prerequisites:
Your JPEG images are in an ‘images’ directory.

Usage:
ProcessPhotos.bat [path of directory that contains ‘images’ directory]

Output:
A new directory called ‘generated’ in the input directory containing a full size image (which has been tagged with the website URL), and a poloroid thumbnail.

Notes:
In order to use this script you will have to customise 1) the location of the ImageMagick executable 2) the reference to the drive – it is assuming a ‘f:’ drive here and 3) the website URL.

setlocal
pushd .
goto :skip_functions
:makeThumb
	echo %1
	set jpg=%1
	set jpg=%jpg:~0,-4%
	echo %jpg%
	for /f %%i in ('perl -e "print rand() * 14 - 7"') do set ANGLE=%%i
	set ANNOTATE=-gravity south -stroke "#000C" -strokewidth 2 -annotate +0+20 "www.advancedhtml.co.uk" -stroke none -fill white -annotate +0+20 "www.advancedhtml.co.uk"
	set POLOROID=-bordercolor white -border 6 -bordercolor grey60 -border 1 -background none -rotate %ANGLE% -background black ( +clone -shadow 60x4+4+4 ) +swap -background white -flatten
	D:appsImageMagick-6.3.6-Q16convert %1 ( +clone -resize 600x -auto-orient %ANNOTATE% -compress JPEG -quality 70 -write %jpg%_full.jpg +delete ) -resize 180x -auto-orient %POLOROID% -compress JPEG -quality 80 -sampling-factor 2x1 -strip %jpg%_th.jpg
goto :EOF
:skip_functions
f:
cd %1images
for /f %%i in ('dir /b *.jpg') do call :makeThumb %%i
md %1generated
move *_full.jpg ..generated
move *_th.jpg ..generated
popd
endlocal


Using a common form mail script for multiple websites

Thursday, June 12th, 2008

I run a number of different websites. Most of them have a contact page which is powered by a form mail script. Until recently each of these websites used an almost identical copy of the same form mail script – I use PHPFormMail but you could adapt this solution for other form mail scripts. Each contact us page has very similar HTML in it. I wanted a way of sharing a common form script and wanted to avoid the duplicated HTML without losing the individual styling of each contact us page.

For this to work for you you’ll need:

  1. All your websites to be on a single host. The code on this page is what I used on my 1and1 hosting account, but the solution should be similar for other web hosts.
  2. To be allowed to use .htaccess files.
  3. Have enough technical knowledge to understand what I’m saying and to customise this for your own site. I’ll give you enough information to implement this, but only if you have enough understanding of knowledge of HTML, PHP and .htaccess files.

On my web server I use one directory for each domain. I map my domain names to directories like this:

http://www.advancedhtml.co.uk    ->   /advancedhtml-web/
http://www.reviewmylife.co.uk    ->   /reviewmylife-web/
http://www.interrail-italy.co.uk ->   /interrail-web/

You’ll note that it is not possible to access the root of my web hosting account ‘/’ from the web.

I’ve added a common directory to store the form mail script and the form HTML. This directory is not accessible from any web address. I’ll explain the contents of the formmail.inc later on.

/common/
/common/formmail.php
/common/formmail.inc

The formmail.php is my usual PHPFormMail script.

I then set up a global variable in a .htaccess file in the root of my web server. This .htaccess file is not accessible to any of my website visitors but it is processed.

The contents of the .htaccess look like the below snippet. You’ll need to replace the /kunden… part with the path of your own common directory.

SetEnv COMMON_PATH /kunden/homepages/25/dxxxxxxx/htdocs/common

If you don’t know what your web server path looks like create a file called ‘test.php’ with the following contents – <?PHP phpinfo(); ?> and then load file from your browser. You can use this test.php to verify that your new environmental variable is present. Below is my formmail.inc

formmail.inc
<center>
<form method="post" action="commonformmail.php">
<table width="80%" cellpadding="0" cellspacing="0">
<tr>
  <td><font face="arial">Name</font></td>
  <td><p><input type="text" name="name"></p></td>
</tr>
<tr>
  <td><font face="arial">Email</font></td>
  <td><p><input type="text" name="email"></p></td>
</tr>
<tr>
  <td><font face="arial">Subject</font></td>
  <td><p><input type="text" name="subject"></p></td>
</tr>
<tr>
  <td><font face="arial">Message</font></td>
  <td><p><textarea name="message" rows="15" cols="45"></textarea></p></td>
</tr>
<tr>
  <td></td>
  <td><p><input type="submit" name="Submit" value="Send"></p></td>
</tr>
</table>
<p>
<input type="hidden" name="redirect" value="thanks.htm"></p>
<input type="hidden" name="recipient" value="commonmail">
<?php
print "<input type="hidden" name="referer" value="" . $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"] . "">n";
?>
<input type="hidden" name="env_report"
 value="REMOTE_HOST,HTTP_USER_AGENT,REMOTE_ADDR">
</form>
</center>

Look at the PHPFormMail documentation for information about the redirect, recipient and env_report fields. You’ll note that I have added a referer field so that I’ll know which of my websites this form was posted from. The value of the recipient field has to be present in the PHPFormMail $recipient_array. If your contact page is a .html rather than a .php you’ll have to make sure that you can use PHP in HTML files.

In your contact us/email HTML file you can include the form like this:

<?php
include_once($_SERVER['REDIRECT_COMMON_PATH'] . '/formmail.inc');
?>

The final part of the solution is to add a commonformmail.php to each of your individual website directories. It will look like this and just includes the shared form mail script.

<?php
include_once($_SERVER['REDIRECT_COMMON_PATH'] . '/formmail.php');
?>

From now on you can change the behaviour and look of all your website forms from one place.

FTP uploading a directory of files using perl

Monday, February 18th, 2008

Here is a simple script to upload the files which are in a particular directory. I use something similar to automate the file uploading for my tube walking blog.

Whenever I take photos for the blog I put them into a directory with the current date as the directory name. So I have a structure like this:

c:\website\080115\
c:\website\080203\
c:\website\080205\
c:\website\080218\

I want the images in these directories to be uploaded to a new directory on the FTP server where the FTP server directory is named with the date e.g. ‘080218’.

The script is run with a command such as:

perl imageupload.pl c:\website\080218\

The script will then:

  1. Extract the date part of the directory – ‘080218’.
  2. Connect to the FTP server.
  3. Create a directory called ‘080218’ on the FTP server.
  4. Get a list of all the local files in the directory that you passed in as the argument.
  5. Upload each of these files to the FTP server.

Here’s the script. You’ll need to modify the FTP server address, username and password if you want to use it.

use File::Basename;
use Net::FTP;
my $directory = $ARGV[0];
my @parts = split(/\\/, $directory);
# get leaf directory name from whole path
my $length = $parts;
my $dateDir = $parts[$length-1];
$ftp = Net::FTP->new("ftp.yourwebsite.com", Debug => 1)
    or die "Cannot connect to hostname: [email protected]";
$ftp->login("username", "password")
    or die "Cannot login ", $ftp->message;
$ftp->cwd("/website/data")
    or die "Cannot change working directory ", $ftp->message;
# create 'date named' directory on FTP server
$ftp->mkdir($dateDir);
$ftp->cwd($dateDir);
# set binary mode which is needed for image upload
$ftp->binary();
opendir(DIR, "$directory");
my @files = readdir(DIR);
foreach my $file (@files)
    {
    if (not -d $file)
        {
        # make sure the names are lower case on the server
        $file = lc($file);
        # upload the file
        $ftp->put("$directory\\$file");
        }
    }
$ftp->quit();

The script is simple, but it can easily be integrated into a more complex set of scripts to help you manage your web site.

Backup / restore of last modified and created file time attributes on Windows

Saturday, January 12th, 2008

Last month I found that I needed to be able to backup and restore the last modified and created file times of a load of files in Windows XP. This is probably a bit of an obscure thing to need to do so naturally I couldn’t find any existing tools to do it.

I’ve therefore made a Perl script to allow this to be done. Just so you are clear, this isn’t backing up the files, it is backing up the last modified and created file time attributes.

This allows changes to be made to the files whilst keeping these attributes intact. In theory Perl’s utime function should allow me to change these attributes. However on my Windows XP machine it just didn’t work. I’ve therefore used the rather excellent nircmd tool to handle the file attribute modifications. You’ll need to download it and modify backupLastModified.pl to point to it.

Usage is simple:

perl backupLastModified.pl c:\yourdir -backup
perl backupLastModified.pl c:\yourdir -restore

Make sure you do a test of this script before you use it for real. It has only ever been tested on one machine.

  1. Download backupLastModified.zip
  2. View backupLastModified.pl

This script will create a file ‘backuplist.txt’ in the directory that you pass in as the first argument. If you run -backup multiple times then any new files will be appended to the backuplist.txt. The stored last modified / created times of any existing files will be preserved.