Archive for the ‘rmagick’ Category

iPhone screenshot processing – part 2

Today I was working on automating of preparation of iPhone screen shots for usage on the website. The new eideticsoftware.com website design requires for the images to have drop shadows so instead processing everything in Adobe® Photoshop® I have decided it would be much nicer to just automate the process with rmagick.

If you are impatient and just want the script jump to the bottom of the post and download image_processor.rb but if you want to know how it works then read on.

This script scales the images for the post.

example_scaled
First we take the original image and scale it by 50% –

source = original.scale(0.5)











example_scaled_stripped
Next we strip out the status bar with crop method:

source = source.crop(0, 10, 160, 240)











example_scaled_stripped_canvas_with_shadow
We create a transparent canvas that is 10px wider and 10px longer and another identical canvas that we are going to use for the shadow. On the image_shadow canvas we draw a rectangle with the same dimensions as the original image. In the source file the rectangle is created by the “drop_shadow_rectangle” function.

We use the image_shadow canvas to create two shadows, first is the actual shadow, the second we use as a mask to soften the shadow itself.

We apply the first shadow to the original canvas with “OverCompositeOp” option and then we apply the mask on top of that with “CopyOpacityCompositeOp” option.


example_scaled_stripped_canvas_with_image
We apply the scaled and cropped image on top of the shadow and draw a white border. The white border is only necessary when the screen shot is dark to distinguish the shadow from the image.

Finally we write the image to a file with “canvas.write” method.







Source Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
require 'rubygems'
require 'rmagick'
 
include Magick
 
img_filename = "example.png"
 
 
# Helper function to create new name
def new_name(img_filename, modifier = "_shadow")
  chunks = img_filename.split(".")
  chunks[0..-2].join(".") + modifier + ".#{chunks[-1]}"  
end
 
# Creates drop show rectangle
def drop_shadow_rectangle(x,y,width,height)
  gc = Draw.new
  gc.fill_color("black")
  gc.rectangle(x,y,width,height)
end
 
# creates frame draw object
def white_frame(x,y,width, height)
  frame = Draw.new
  frame.fill_opacity(0)
  frame.stroke_color("white")
  frame.rectangle(x,y,width,height)
end
 
 
def add_shadow(img_filename)  
  original = ImageList.new(img_filename)
 
  source = original.scale(0.5)
  source.write(new_name(source.filename, "_scaled"))
  source = source.crop(0, 10, 160, 240)
 
  canvas = Image.new(source.columns + 10, source.rows + 10) do
    self.background_color = "transparent"
  end
 
  # Generates intermediate images
  #source.write(new_name(source.filename, "_stripped"))
  #canvas.write(new_name(source.filename, "_raw_canvas"))
 
  image_shadow = Image.new(canvas.columns, canvas.rows) do
    self.background_color = "transparent"
  end
 
  drop_shadow_rectangle(0, 0, source.columns, source.rows).draw(image_shadow)
 
  blur = 1
  x, y = 1, 1
 
  image_shadow = image_shadow.shadow(x, y, blur, 1)
  shadow_mask = image_shadow.shadow(x, y, blur, 1)
 
  # Place the shadow
  canvas.composite!(image_shadow, 0, 0, OverCompositeOp)
 
  # Place the mask to soften the shadow
  canvas.composite!(shadow_mask, 0, 0, CopyOpacityCompositeOp)
 
  # Intermediate image  
  # canvas.write(new_name(source.filename, "_canvas_with_shadow"))
 
  # Now place the image on the canvas
  canvas.composite!(source, 1, 1, OverCompositeOp)
 
  # And draw the white border on top of the image
  white_frame(0, 0, source.columns, source.rows).draw canvas
 
  # save the final image
  canvas.write(new_name(source.filename, "_canvas_with_image"))
end
 
add_shadow(img_filename)

Processor: image_processor.rb

Automating iPhone screenshots processing with rmagick

In programming repetition is evil. No one should do the same task more than once so I was not to excited about doing screenshots for FitTimer.

Taking the screenshots is not a big deal.

  1. On your device Hold the sleep/wake button and click the “home” button.
  2. Connect the device to your mac and import your images to iPhoto
  3. Select the imported images in iPhoto and drag them to a desired folder.

Unfortunately you can’t use these raw images. Apple requires you convert them to JPEG format and recommends you crop out the iPhone status bar. This task for many people mean opening each screenshot in Photoshop, cropping the image to “320 x 460″ and saving it as a JPG.

One may say: “It’s only a few images” but if you often update to your applications UI updating screenshots becomes one more thing you have to do. Additionally, if your website requires screenshots of different size or thumbnails, your screenshot updating task will take more and more time.

There is a better way of dealing with screenshots. You can automate the whole process with a few simple lines of ruby code using rmagick gem.

To use rmagick you will need to install the gem. You can find a link to installation instructions at the end of the post in the references section.

After you have rmagick successfully installed you can start processing your images.

I keep all my marketing material in <project_root>/marketing folder to keep it together in a single source code repository (git), however you are welcome to keep it anywhere you like.

To use my script you will need to prepare a few things:

  1. Create your working folder (in my project – “marketing”)
  2. In the working folder create three folders “raw_images”, “itunesconnect” and “web_images”
  3. Copy the script to the working folder
  4. Copy your raw ‘png’ screenshots to raw_images
  5. If you are copying the files from iPhoto you may want to rename them to something human readable like “main_view.png”
  6. Open your favorite terminal app and run the script

The script does 4 things.

  1. Crops the status bar and saves screenshots for itunesconnect in the itunesconnect folder
  2. Saves the cropped screenshots in the web_images folder
  3. Reduces the image by 50% and saves it in web_images folder with new name <filename>_50.jpg
  4. Creates a thumbnail by reducing the original image to 25% of it’s original size and saves it in web_images folder with new name following schema <filename>_thumb.jpg
require 'rubygems'
require 'rmagick'
 
Dir.glob('raw_images/*').each do |original|
  path = original.split('/')
  name = path[1].split('.').first
 
  itunes_img_path = "itunesconnect/#{name}.jpg"
 
  web_img_path = "web_images/#{name}.jpg"
  web_img_scaled_path = "web_images/#{name}_50.jpg"
  web_img_thumb_path = "web_images/#{name}_thumb.jpg"
 
  original = Magick::ImageList.new(original)
  cropped = original.crop(0,20, 320, 460)
  cropped.write(itunes_img_path)
  cropped.write(web_img_path)
 
  scaled = cropped.scale(0.5)
  scaled.write(web_img_scaled_path)
 
  thumb = cropped.scale(0.25)
  scaled.write(web_img_thumb_path)
end

References

Rmagick installation instructions
iTunes Connect Developer Guide can be found on the itunesconnect website in Manage Your Applications Section.